CakeCTF 2021 Writeup(nostrings, Hash browns)
プログラム内のデータと何らか計算したデータを比較する場合、 プログラム内のデータを楽に取得できるGhidra Scriptを使って解くのが便利。 ということでGhidra Scriptを使ったWriteup
とはいっても、Ghidra特有の部分はtoAddr
とgetBytes
くらい
nostrings
Ghidraで見ると入力した文字列に対して、DAT__00104020の、計算した値と比較していることがわかる。
Flagに使用される文字列はアルファベット大文字小文字、数字、_?!{}
くらいであろうことが、stringsの一覧からわかるので
Ghidra Scriptを作成する。
import string flag_ch = string.ascii_letters + string.digits + '_?!{}' print(flag_ch) flag = '' for i in range(0x40): for c in flag_ch: tmp = chr(getBytes(toAddr(0x104020 + (ord(c) * 0x7f + i)),1)[0]) if tmp == c: flag += c break print(flag) # CakeCTF{th3_b357_p14c3_70_hid3_4_f14g_i5_in_4_f14g_f0r357}
CakeCTF{th3_b357_p14c3_70_hid3_4_f14g_i5_in_4_f14g_f0r357}
Hash browns
こちらも読んでみると入力された文字列の奇数番目のmd5の先頭10桁と偶数番目のsha256の先頭10桁を比較していることがわかる。
md5の比較する対象のデータは順番通りだが、sha256の比較する対象のデータはf
関数で順番がいじってある。
今回は使われる文字列がわからないので、記号はstring.punctuation
を使用した。
import string import hashlib flag_ch = string.ascii_letters + string.digits + flag.punctuation flag = '' def f(a,b): if b == 0: return 1,0 else: d, c = f(b, a % b) d = d - (c * (a // b)) return c,d for i in range(0x25): k = f(i,0x25)[0] if k < 0: k = k + 0x25 for c in flag_ch: md5 = hashlib.md5(c).hexdigest()[:10] calc_val = ''.join([chr(j) for j in getBytes(toAddr(0x1020a0 + (0xb * i)),0xa)]) if md5 == calc_val: flag += c break for c in flag_ch: sha256= hashlib.sha256(c).hexdigest()[:10] calc_val = ''.join([chr(j) for j in getBytes(toAddr(0x102240 + (0xb * k)), 0xa)]) if sha256 == calc_val: flag += c break print(flag) # CakeCTF{(^o^)==(-p-)~~(=_=)~~~POTATOOOO~~~(^@^)++(-_-)**(^o-)_486512778b4}
CakeCTF{(^o^)==(-p-)~~(=_=)~~~POTATOOOO~~~(^@^)++(-_-)**(^o-)_486512778b4}
おわりに
気づいたのが8/29 13時頃だったのが一番の反省。