polictf 2017 Writeup

目錄

  1. Crypto 96: Splyt
  2. Crypto 301: Lucky Consecutive Guessing (Cracking linear congruential generators)
  3. Grab Bag 117: JSfuck
  4. Forensics 379: Open Sesame
  5. Forensics 432: Stegocat


Crypto 96: Splyt

0x00. 背景

題目提供了 challenge.json、splyt.py 及其他檔案。我是 black-box testing 的,很多東西都沒看過。

隨意執行一次 splyt.py,輸出為:

寫個 Hello World! 到 a.in,然後用  ./splyt.py split a.in 10 7 > a.json 會得到:

如果隨便選出 7 行,用 ./splyt.py join a.json  則有機會回復成 Hello World!,如果少於 7 行的話則變成一堆亂碼。所以確認這個是個 (有 bug 的) secret sharing 程式。

0x01. 思路與題解

打開 challenge.json,裡面是這樣子的:

看起來集齊四個 secret 就可以召喚 flag,然而留意剛剛產生的 a.json 那邊:

  • “Hello World!” 對應第一行的  238, 12, 19, 19, 22, 198, 253, 22, 25, 19, 11, 199,兩個 l 都是 19、而 d 跟 e 分別是 11 和 12,估計 a, b, …, z 分別對應 \(n\), \(n+1\), …, \(n+25\)。
  • 如果把第四行的  253, 27, 34, 34, 37, 213, 13, 37, 40, 34, 26, 214 跟第七行的  208, 237, 244, 244, 247, 168, 223, 247, 250, 244, 236, 169 數字相減,會得出: 45, -210, -210, -210, -210, 45, -210, -210, -210, -210, -210, 45,是經過 mod 255。

這問題其實很簡單,思路如下:

  1. 假設第一行的答案跟第二行的一樣
  2. 嘗試用 splyt.py 把 json 變回來,如果出現 flag 就完成了。
  3. 如果沒有出現 flag,把第一行的數字整行都 +1,再跳到第二步。

寫了一段代碼把思路實現,得出 flag: flag{r3us1ng_r4nd0m_1s_n0t_fun}。慢著,哪裡有用過 random?


Crypto 301: Lucky Consecutive Guessing

0x00. 背景

這個 challenge 有點像我在 VXCTF 出過的 Epic Random RNG… 它會從一個 random number generator 抽出一個數字,然後你要預測這個是甚麼數字。只要反覆猜中一百次左右你就可以得到 flag 了。

我也嘗試猜了幾次,很成功地沒有猜中。只看到了數字應該是 32 bits 的。(另外,連續猜中一百次的難度就跟你連續中 135 次六合彩頭獎一樣,所以別妄想可以盲猜就可以取得 flag。)

幸好,作者也有提供 source code。當中最受矚目的是以下這部份:

0x01. 思路與題解

除了 seed 以外,所有數字都是經過這個 Linear Congruential Generator 產生出來的。簡單來說,它會跟據現在的 state (\(s\)),作出以下運算:

  1. 把 state 更新:\(s’ \leftarrow (as+b) \text{ mod } 2^{85}\),
  2. 輸出數字:把 \(s’\) 變成二進制後,將最左的 32 bits 輸出。

當中 a = 0x66e158441b6995b = 0xb  是已經提供的數字。

我參考了 https://crypto.stackexchange.com/questions/10608/how-to-attack-a-fixed-lcg-with-partial-output,發現可以用相同的邏輯來做這一題 (詳情後補)按這裡看代碼。

打破那個極之細小的機率後,我們終於得到了 flag: flag{LCG_1s_m0re_brok3n_th4n_you_th!nk}


Grab Bag 117: JSfuck

0x00. 背景

I was writing some valid ECMAScript to print your flag but my fingers slipped and I added several unwanted characters. Could you please fix it for me?

0x01. 思路與題解

下載了它的程序碼之後,看到的是這個 Javascript 程式碼:

可能對一般寫 Javascript 的人比較陌生,但是這真是 Javascript - 它只用到  ()+[]! 這六個字元就可以寫成任何 Javascript 程式碼,這種方法叫作 JSfuck

普通的 JSfuck 程式碼可以直接丟到瀏覽器的 console 看結果,例如下面的代碼就會輸出 alert(1)

然而,題目所給的程式碼不能這樣做… 最簡單的原因是因為作者「不小心」輸入了幾個字元進去了。如果用肉眼來看的話,應該等到佛誕… 所以一邊看,一邊寫代碼解決 (代碼後補,這版本醜得不能直視)

把製成品丟到 console,得出 flag: flag{I f***ed my brain so hard i enjoyed it}


Forensics 379: Open Sesame

0x00. 背景

題目提供了一個 GQRX 檔 (gqrx_20170117_220606_433000000_8000000_fc.raw),名字的格式普遍是  gqrx_DATE_TIME_FREQ_SAMPLERATE_DEVICE.raw,意味著這個檔案的 sample rate 是 8MHz。

0x01. 思路與題解

用  sox -t raw -e floating-point -b 32 -r 8000000 gqrx_20170117_220606_433000000_8000000_fc.raw t.wav 來得到 t.wav,用 Audacity 看一下:

提示有一句「MM53200」,Google 找到了對應的 encoder (http://www.farnell.com/datasheets/105708.pdf)。

Audacity 裡面的 bits 為 “01011001001011001011011001001011011011”,首兩個 bits 估計為同步用,其後 36 個 bits 分成 12 組,011 解碼為 0、001 解碼為 1。Decode 後得出 flag 為 011010011000


Forensics 432: Stegocat

0x00. 背景

這個 challenge 只提供了 miaowth.mjpg 這個動畫檔,下面是動畫的其中一幀:

0x01. 思路與題解

嘗試用 hexdump 取得該 jpg 檔的十六進制編碼。一般的 JPG 檔開頭跟結尾會以 FF D8 FF E0 及 FF D9 表示,然而這次不同。下圖可以看到在應有的結尾後還有 00 30 30 64 63 EB 27 一段編碼。

我寫了這段代碼來從 .mjpg 提取 .jpg 檔,以及讀取  FF D9 後面的第一個字元。結果提取了以下這段文字,而 flag 已經在裡面了。


發表迴響