歡迎來到 黑吧安全網 聚焦網絡安全前沿資訊,精華內容,交流技術心得!

如何編寫shellcode查找EIP & RIP

來源:本站整理 作者:佚名 時間:2020-01-23 TAG: 我要投稿

Shellcoding:查找EIP / RIP
我在學習OSCE認證時,花費了大量時間研究如何編寫自定義shellcode。這是我打算發布的一系列博客文章中的第一篇,其中將詳細介紹我在此過程中學到的一些技術。這篇博客文章的重點將是描述如何找到EIP / RIP,以及找到它可以做什么。OSCE將精力集中在32位系統上,作為我繼續學習的一部分,我將研究和記錄適用于64位系統的方法。
在這篇博文中,我不會介紹找到EIP和RIP的所有可能方法。我將介紹一些我熟悉并研究過的內容。如果你有興趣尋找更多的方法,我鼓勵你進行研究并踏上自己的學習之旅。你在這里看到的是我自己的學習總結,我希望它能以某種方式對你有所幫助。這些主題多年來已經涵蓋了許多主題,而且并不是什么新鮮事物,重點不是提出新的東西而是在我自己的學習過程中提供幫助,也許還可以幫助其他人開始自己的旅程。
查找EIP:32位匯編方法
我將從使用x86匯編(32位)指令找到EIP的方法開始。有兩種方法,這兩種方法都可能有用,具體取決于你可能遇到的情況和限制。兩種方法將實現尋找EIP的相同目標。我將詳細介紹的第一種方法比第二種方法小一個字節。兩種方法都可以達到完全相同的目的,即將EIP的值存儲在EAX寄存器中。兩種方法都沒有NULL(0x00)字節。之所以使用前一種而不是另一種,是因為你可能會遇到大小或字符限制。
方法1:使用FPU指令
此方法由Aaron Adams首次在漏洞開發郵件中進行了說明。他使用的方法利用x87浮點單元(FPU)寄存器來獲取EIP的值。以下基本匯編代碼會將EIP的值存儲在EAX寄存器中。
 [SECTION .text]
 
 BITS 32
 
 global _start
 
 _start:
     fldz
     fnstenv [esp-0x0C]
     pop eax
     add al, 0x07
為了激活FPU寄存器,執行fldz指令。該指令將常數值+0.0壓入FPU寄存器堆棧(ST(0))。在此過程中,將初始化FPU寄存器,并將EIP的當前值存儲在FPU指令指針偏移量(FIP)寄存器中。圖1詳細說明了FPU寄存器的結構。該表摘自《英特爾64和IA-32架構軟件開發人員手冊,第1卷:基本架構 PDF》。

圖1:內存中的保護模式x87 FPU狀態圖像(32位格式)
下一條指令將FPU寄存器存儲在指定地址。由于使用fnstenv指令將EIP值以0x0C(12)的偏移量存儲在FIP寄存器中。指定了ESP-0x0C的目標,以便將FIP值存儲在當前ESP地址中。接下來,該值從堆棧中彈出并存儲在EAX寄存器中。由于在將EIP存儲到FPU的FIP寄存器與將其彈出到EAX的時間之間已經執行了幾個字節的指令,因此有必要調整EIP值以表示FPU的當前值。為此,將0x07(7)添加到AL寄存器,AL寄存器用于避免使用NULL字節。
測試
要對此進行測試,可以使用nasm匯編代碼:
 nasm method1.asm -o method1.asm
然后將字節插入c代碼中:
 char code[] = "\xD9\xEE\xD9\x74\x24\xF4\x58\x04\x07";
 
 int main(int argc, char **argv)
 {
    int (*func)();
    func = (int (*)()) code;
    (int)(*func)();
 }
用MingW編譯代碼:
 i686-w64-mingw32-gcc-win32 method1.c -o method1.exe -fno-stack-protector -no-pie -m32
在你喜歡的調試器中運行生成的PE文件,并查看其工作方式。你將需要將.data節標記為可執行文件。你可以使用degger或諸如LordPE之類的工具來執行此操作。如果未將.data節標記為可執行文件,則當執行到達你的Shellcode時,將出現訪問沖突。我建議在PE文件中搜索調用eax指令并設置斷點,對EAX的第一個調用將是對shellcode的調用。如果一切順利,EAX將在執行add al,7指令時指向EIP ,請參見圖2。

圖2:EAX指向EIP
方法1替代-使用減法
由于使用減法從EAX寄存器在某些情況下會失敗,我加入此替代方法。問題在于,通過添加到AL寄存器中,如果加的字節將導致進位,則EAX可能指向錯誤的位置。例如,如果AL寄存器包含大于或等于0xF9的任何內容,則向其添加0x07會導致有1位被丟棄。例如,如果EAX包含0x001234F9,而我們添加0x07到AL寄存器(0xF9),結果將是0x00123400,而不是需要的0x00123500。
為了克服此問題并避免使用空字節,可以從EAX減去負值;舅阈g,加上負值會得出加法。更正后的代碼在下面,并且避免NULL字節,并且僅大一個字節:
 [SECTION .text]
 
 BITS 32
 
 global _start
 
 _start:
     fldz
     fnstenv [esp-0x0C]
     pop eax
     sub eax, -0x07
在圖9中,我們可以看到代碼確實有效,并且比原始代碼更可靠。

圖9:EAX指向EIP
方法2:使用跳轉和調用
第二個方法僅比第一個方法長一個字節,并達到了將EIP值存儲在EAX寄存器中的目的。為了獲得EIP,此方法使用了一系列跳轉和調用,這些跳轉和調用導致EIP的值存儲在EAX中。SK Chong文章的示例中,他使用db條目對這些跳轉和調用進行硬編碼。我要介紹的版本可以通過nasm輕松閱讀和修改。
 [SECTION .text]

[1] [2] [3]  下一頁

【聲明】:黑吧安全網(http://www.650547.live)登載此文出于傳遞更多信息之目的,并不代表本站贊同其觀點和對其真實性負責,僅適于網絡安全技術愛好者學習研究使用,學習中請遵循國家相關法律法規。如有問題請聯系我們,聯系郵箱[email protected],我們會在最短的時間內進行處理。
  • 最新更新
    • 相關閱讀
      • 本類熱門
        • 最近下載
        安徽快3自由的百科 免费下载四川金7乐 辽宁快乐12近1000期走势 pk10走势图官网 甘肃快三今天开奖结果 福建31选7胆拖对照表 中国体育彩票玩法规则 75秒时时彩规律破解 河北20选五开奖最新结果 江西多乐彩任三技巧 天津11选5只能在天津买吗