上次打 bamboofox 覺得挺有趣的,又因為去年參加過的曹宸睿說會覺得頗有收穫所以想報名看看,就順勢拉了蛋餅、蕭梓宏、劉至軒等人一起報名參加了。
同時報名了 MyFirstCTF 和 AIS3 pre-exam,但因為週六白天是 APIO 所以不幸的完美錯過比賽時間,只剩下 pre-exam 可以打。
以下是這場比賽的簡單 Write up,順便紀錄一下自己這次學到了些什麼。
Microchip
除了簽到題以外最多人做出來的一題,其實就是給你一個 function,看懂之後發現它是對輸入的 flag 每四個 char 為一組加密,加密方法是把 ASCII 加減特定的值,於是就先用 flag 開頭的 AIS3 去 reverse 找出加密的 key,然後後面就可以照著 key reverse出原本的flag了。
因為是看懂程式碼就會做的題目,好像也沒學到什麼技巧(?)
ReSident evil villAge
目標是要嘗試得到 “Ethan Winters” 經過 RSA 加密後的簽名,可以對 server 做的事情是輸入字串並得到簽名,只不過該字串不能是 “Ethan Winters”。
終於看懂程式在幹嘛後發現,因為加密方法是 pow(bytes_to_long(msg), d, n)
,所以可以先將 bytes_to_long(Ethan Winters)
分成兩個數字 $p, q$ 的乘積後用 long_to_bytes(p) * long_to_bytes(q) % n
去得到原本的簽名,丟去 server 那邊驗證就順利拿到 flag。
因為一開始就出現 RSA.generate() 所以就大概知道是要往這邊研究,原本一直覺得是要解出 $d$,還在想大數找原根之類的事情,查了一些資料複習了好久沒碰的 RSA 後確定那不可做,也才突然想到其實題目應該只是想要我們利用那個函式而已xd
Republic of South Africa
目標一樣是要解 RSA 加密,題目給了一個會產生兩個質數 $p, q$ 的 function,然後會給你 e
、n = p * q
,還有 c = pow(bytes_to_long(flag), e, n)
。
其實就是要求出 $p, q$ 的值,然後 flag 就會是 long_to_bytes(pow(c,e * inv(lcm(p-1, q-1)), n))
。研究了一下 function 後發現是一個彈性碰撞模擬,兩個質量相差 $10^{153}$ 倍的物品在力學能守恆下由大質量的那方撞向另一方,另一方會反彈再撞回去直到大質量的那方最終改變方向,得到總碰撞次數 cnt 後再隨機選出 $p + q = $ cnt。
直接執行 function 後就發現是跑不完的,一開始想到的方法是把彈性碰撞寫成線性遞迴式子,然後嘗試用快速冪去二分搜,但寫完發現數字都會變成 inf
根本不可能得到答案。又盯著它看了不少時間,才想說先試試 $10^{5}$ 的 case 好了,發現碰撞次數是 $31415$(??),於是又試試看 $10^{6}$ 發現是 $314159$,就大膽猜測是 $\pi$ 的前$k$位了,拿回去加上 $n$ 的條件就成功解出 $p, q$ 拿到 flag。
可惜我 $\pi$ 只背到前 $30$ 位,不然直接打出來應該很爽xd 然後其實得到 cnt 後到解出 $p, q$ 我又花了超長時間,原因是 python 的 sqrt()
不夠精確,然後我一直以為是那個數字不是完全平方數。
這題原本真的超想放棄,要不是最後那個通靈的觀察我根本不可能做出來,更扯的是賽後問到的每個人都說這是冷知識(!?),果然我真的不會物理QQ
ⲩⲉⲧ ⲁⲛⲟⲧⲏⲉꞅ 𝓵ⲟ𝓰ⲓⲛ ⲣⲁ𝓰ⲉ
目標很簡單,就是登入網頁然後拿到 flag。
完全沒有任何 Web CTF 的相關背景,盯著程式碼看了非常久總算感覺 Json 的那邊感覺有點小怪,看起來像是直接把內容替換上去,想說不然傳傳看奇怪東西像是 " 之類的,然後網頁就壞了,也更加確定我的猜測。
照著前面的程式碼生出
username: casper", showflag: true, "a":"b
password: ", password: , "a":"b
然後就成功拿到 flag 了
事後被提醒才想起來這好像叫 injection xd
Microcheese
原本在研究 Microchess,結果就發現變成兩題了,把兩題打開比對程式碼後發現只差兩行,然後這題就被秒掉了。
Microchess
目標是跟 AI 玩一場先手必輸的 nim 然後你是先手,贏了才可以拿到 flag。
看完整段程式碼後找不到明顯的遊戲 bug,但因為有儲存遊戲的設定,然後儲存方式是加密後儲存,感覺可以操作的點一定就在這邊,原本想說是不是可以直接 reverse 回去盤面,但怎麼查怎麼試都失敗QQ
最後一天的早上開了提示,查到一個叫 Length extension attack 的東西才突然驚覺原來那個 block 充滿漏洞xd 於是照著維基百科上面講的方式去做就順利得到先手必勝盤面,flag 成功到手!
原本看到是賽局覺得終於有自己擅長的東西了,結果根本毫無關聯,不過學到新的 hashing function 破解技巧也很酷就是了。
後記
最後幾個小時都在搞 microchart,結果因為不會做模 256 下的高斯消去而壓線失敗,小可惜。
最終名次是 rk68,對於新手而言應該不算太糟(?) 總之有進就好xd