Linux下進程地址空間的佈局html
典型的堆棧結構linux
上圖中能夠看到棧中有return address還有局部變量,也就是函數的參數,bof攻擊是利用上參數的溢出將返回地址return address用本身構造的數據覆蓋掉,從而控制程序的進程。接下來就試着經過bof攻擊來實現調用getshell函數。shell
經過前面能夠看出只要把返回地址改爲getshell函數的起始地址就能夠,可是須要先肯定局部變量的大小,而後才能將getshell的起始地址剛好放到return address的位置。直接的想法就是拿一個足夠長的參數去試,這時要藉助debug工具才能看出那部分數據是溢出的,那部分數據在局部變量範圍內,linux終端下gdb就能夠進入debug。在debug下運行程序並輸入測試用例1111111122222222333333334444444455555556666666,查看結果以下圖。編程
裏面用到info命令查看eip寄存器(返回地址)的值,注意到0x35就是‘5’的ascll碼,所以能夠肯定地址應該在8個5的位置,因而再輸入一組測試,1111111122222222333333334444444412345678來肯定4字節地址的具體位置。bash
此時就能夠肯定輸入32字節以後的4個字節就是咱們要覆蓋的返回地址所在的位置了,接下來就是把原來的地址改成getshell函數的起始地址。從以前逆向的反彙編中咱們知道getshell的起始地址是0x0804847d,可是直接按這個順序輸入會錯,由於從上圖中看出當輸入是1234時eip寄存器中的值卻對應的是4321,這是由於棧頂是低地址的緣故,因此0x0804847d也須要反着輸入,即0x7d840408。這時又出現一個問題,如何將0x0408輸入,直接輸入顯然不能實現,但咱們知道在編程語言中的print函數是能夠作到的,再加上管道|就能把數據輸入了。dom
下面選擇使用perl語言構造輸入數據:編程語言
能夠看到成功的調用了getshell函數。函數
既然能夠跳轉到任意咱們輸入的地址,那麼只要注入本身編寫的shelcode而後再跳到對應的位置,咱們的shellcode就能夠順利的運行。下面嘗試利用相似的方法插入並讓程序運行本身編寫的代碼。工具
root@KaliYL:~# execstack -s pwn1 //設置堆棧可執行 root@KaliYL:~# execstack -q pwn1 //查詢文件的堆棧是否可執行 X pwn1 root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 2 root@KaliYL:~# echo "0" > /proc/sys/kernel/randomize_va_space //關閉地址隨機化 root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 0
首先須要肯定咱們插入shellcode後的地址在哪,下圖是已經跳轉失敗後查看的寄存器數據,因此此時棧頂esp就是eip的下一字,由於eip剛剛彈出棧,從棧頂的數據也能夠看出。我直接選擇了eip後做爲shellcode的起始地址,所以我應該把eip的值改成0xbffff1f0,一樣在注入時地址須要反着輸入,可是shellcode不須要逆序輸入,由於程序是按照從低地址到高地址執行的。佈局
接下來就構造輸入數據,先按前一步把eip和前32字節內容寫到input2文件中。而後編寫shellcode,編寫一個c文件編譯,而後反彙編找到須要的部分加到input2後面,。
代碼以下圖,只有輸出hello world的功能,爲了方便直接將整段程序接到input2後面,利用hello >> input2很方便就能實現。
將input2做爲輸入程序成功輸出hello world以下
shellcode的編寫其實有不少坑,瞭解更多http://www.cnblogs.com/xxy745214935/p/6477120.html。