# HW3 ## Sacred Arts 先對助教指出的地方做修改: 1.![](https://i.imgur.com/2GCPItQ.png) 2.![](https://i.imgur.com/mHJ5gDA.png) 而這份LAB最重要的就是看懂組語在做甚麼,簡單說這份組語的行為如下: 1. Call open system call去打開/tmp/flag 2. 若開檔失敗,則印出wrong之後exit 3. 若開檔成功,則對檔案進行讀取,將讀取的值取二埔數後將最後兩個Byte對調 最後再跟下圖的值一一做比較 ![](https://i.imgur.com/RcZBfi1.png) 4. 若第3步途中有不同,表示錯誤,印出wrong後exit離開 若途中完全相同,表示正確,印出correct後結束程式 所以這題的關鍵在於第3步的行為,他會將讀出的flag值取二補數後對調最後兩個Bytes,我們只需要將第3步圖片中的陣列元素先對調最後兩個Bytes,然後除了每個元素最後一個Byte要取1補數後+1以外,元素的其他Byte都只需要取1補數就可以,如此就達到了組語將一個8 Byte Word取二埔數的行為。 #### Code 我將arr中每個元素最後兩個Byte對調後放到下圖的arr陣列中,然後再進行後續操作,就顯得容易許多 ![](https://i.imgur.com/E7F5WqU.png) 程式的行為即將每個元素除了最後一個Byte要取1補數後+1以外,元素的其他Byte都只需要取1補數,再將其轉成char後串進t字串中,由於他是反過來的,所以需要將t做reverse後再串進s中,s字串即為我們需要的FLAG!! ## trace ### 程式行為 trace會在/tmp下寫入一個叫cs_2022_fall_ouo的程式,然後fork child process,child先透過ptrace讓parent來追蹤,之後執行cs_2022_fall_ouo,parent在追蹤child的過程中,若暫存器值為0xE8CBCCDEADBEEFE8,會把它改成0x9090909090909090,而0xE8CBCCDEADBEEFE8指令會使程式異常結束。 ### 找出指令的位址 經過計算,下圖第7行的physical address為0x5555555554CE ![](https://i.imgur.com/Ak9Uwat.png) 在這個位址設斷點後去查看qword_79E0暫存器的值,一共得到五個斷點:0x4012c6、0x4011d2、0x401213、0x40123c、0x401262 1. 從此圖中可知道此暫存器位址為0x55555555b9e0 ![](https://i.imgur.com/JPKSysk.png) 2. 讀取暫存器的值 ![](https://i.imgur.com/FPYLm8Z.png) 如此反覆即可得到5個斷點的位址 ### GDB追蹤cs_2022_fall_ouo 在獲得5個斷點後只需要在追蹤前設定斷點位址即可 ![](https://i.imgur.com/OoxX2sA.png) 之後每執行到斷點程式就會停下來,而我們需要將rip的值+8,跳過錯誤的指令使其可以繼續執行下去 ![](https://i.imgur.com/Zt1gJ6K.png) 如此反覆4個斷點後,會出現輸入FLAG的地方 ![](https://i.imgur.com/mX6xiVy.png) 輸入完FLAG,之後會一路直行到第5個斷點,一樣先將rip+8,之後用si一步一步慢慢執行 ![](https://i.imgur.com/qmao9tg.png) 不久後就會看到FLAG被寫入rdx暫存器了 ![](https://i.imgur.com/wNecrq7.png) ## pwn_myself ### 觀察 此題有許多用來混淆修課學生的程式碼,但如果使用GDB配合IDA追蹤到最後,會發現FLAG蠻容易解出來。 ### 解題 1. 首先由於GDB追蹤pwn_myself時無法通過main函數中判斷euid那行,故需算出那行的physical address為0x5555555bab3a,然後修改其$rax始通過euid判斷 ![](https://i.imgur.com/BuHEyXf.png) 2. 緊接著,main函數在執行完 sub_66A37 函式理應結束,但透過GDB追蹤下,發現還會繼續下去執行,接著就依照GDB所追蹤的地址,對應到IDA繼續分析。 3. 做完一連串混淆修課學生的程式碼後,最後會來到重要的部分,下面這份code會去檢查FLAG長度是不是44(我猜他是檢查FLAG) ![](https://i.imgur.com/4DBcLAR.png) 4. 之後會進入到OpenSSL_3343F函數中,這邊會用OpenSSL相關函式進行加解密 ![](https://i.imgur.com/hC5gj9V.png) 5. 進入到encrypt函式裡面,並將裡面稍微整理過後,會發現key、iv都在程式碼中,而ciphertext在剛剛的OpenSSL_3343F中可以找的到 ![](https://i.imgur.com/Pd83BiW.png) ![](https://i.imgur.com/REqeDFG.png) 6. 透過上面取得的ciphertext、key、iv,現在只需要寫程式將其解密即可得到FLAG!! ![](https://i.imgur.com/CrCG5qC.png)