Pwn學習隨筆( 七 )

  • got //查看got表
  • hexdump //像IDA那樣顯示數據 , 帶字符串
  • Return Oriented Programming緩沖區溢出攻擊的普遍發生給計算機系統造成了許多麻煩 ?,F代的編譯器和操作系統實現了許多機制,以避免遭受這樣的攻擊,限制入侵者通過緩沖區溢出攻擊獲得系統控制的方式 。
    【Pwn學習隨筆】Performing code-injection attacks on program RTARGET is much more difficult than it is for CTARGET, because it uses two techniques to thwart such attacks:
    • It uses randomization so that the stack positions differ from one run to another. This makes it impossible to determine where your injected code will be located. 開啟了PIE 保護(棧隨機化)
    • It marks the section of memory holding the stack as nonexecutable, so even if you could set the program counter to the start of your injected code, the program would fail with a segmentation fault. 開啟了NX保護(棧中數據不可執行)
    • 此外,還有一種棧保護 , 如果棧中開啟Canary found,金絲雀值,在棧返回的地址前面加入一段固定數據,棧返回時會檢查該數據是否改變 。那么就不能用直接用溢出的方法覆蓋棧中返回地址,而且要通過改寫指針與局部變量、leak canary、overwrite canary的方法來繞過
    The strategy with ROP is to identify byte sequences within an existing program that consist of one or more instructions followed by the instruction ret. Such a segment is referred to as a gadget
    ROPgadget
    ROP是用來繞過NX保護的,開啟 NX 保護的話,棧、堆的內存空間就沒有執行權限了,直接向?;蛘叨焉现苯幼⑷氪a的攻擊方式就無效了 。
    ROP的主要思想是在棧緩沖區溢出的基礎上,利用程序中已有的小片段 (gadgets) 來改變某些寄存器或者變量的值,從而控制程序的執行流程 。所謂 gadgets 就是以 ret 結尾的指令序列,通過這些指令序列 , 我們可以修改某些地址的內容,方便控制程序的執行流程 。
    ROP 攻擊一般得滿足如下條件
    • 程序存在溢出,并且可以控制返回地址 。
    • 可以找到滿足條件的 gadgets 以及相應 gadgets 的地址 。
    • 如果 gadgets 每次的地址是不固定的 , 那我們就需要想辦法動態獲取對應的地址了 ?!?/li>
    ROP其實就是利用已存在的代碼執行出我們想要的效果,如下圖所示,分為多個gadget,每一個gadget都是一段指令序列,最后以ret指令(0xc3)結尾 , 多個gadget中的指令形成一條利用鏈,一個gadget可以利用編譯器生成的對應于匯編語言的代碼,事實上,可能會有很多有用的gadgets,但是還不足以實現一些重要的操作,比如正常的指令序列是不會在ret 指令前出現pop %edi指令的 。幸運的是,在一個面向字節的指令集,比如x86-64,通??梢酝ㄟ^從指令字節序指令的其他部分提取出我們想要的指令 。
    Pwn學習隨筆

    文章插圖
    下面舉個例子來詳細說明ROP與之前的Buffer overflow有什么區別,我們不關心棧地址在哪,只需要看有沒有可以利用的指令
    我們可以在程序的匯編代碼中找到這樣的代碼:
    0000000000400f15 <setval_210>:400f15: c7 07 d4 48 89 c7 movl $0xc78948d4,(%rdi)400f1b: c3 retq這段代碼的本意是
    void setval_210(unsigned *p){*p = 3347663060U;}這樣一個函數,但是通過觀察我們可以發現,匯編代碼的最后部分:48 89 c7 c3又可以代表
    movq %rax, %rdiret這兩條指令(指令的編碼可以見講義中的附錄) 。
    第1行的movq指令可以作為攻擊代碼的一部分來使用,那么我們怎么去執行這個代碼呢?我們知道這個函數的入口地址是0x400f15 , 這個地址也是這條指令的地址 。我們可以通過計算得出48 89 c7 c3這條指令的首地址是0x400f18,我們只要把這個地址存放在棧中 , 在執行ret指令的時候就會跳轉到這個地址,執行48 89 c7 c3編碼的指令 。同時 , 我們可以注意到這個指令的最后是c3編碼的是ret指令,利用這一點 , 我們就可以把多個這樣的指令地址依次放在棧中,每次ret之后就會去執行棧中存放的下一個地址指向的指令 , 只要合理地放置這些地址,我們就可以執行我們想要執行的命令從而達到攻擊的目的 。

    推薦閱讀