---
# System prepended metadata

title: HW3

---

# 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)




