この週末に開催されていた noxCTF 2018 にチームで参加していました。
解いた問題について Write-up を記載します。
Guess The String
解き方
添付ファイルはELF実行形式。
( Hash ) MD5 : e701e054a1e1f6ab452c6c623b71c6c9 SHA1 : 6e946d07f6cdd6aa987eedfe074bfbc26198d95a SHA256 : 87c3b19f97c4fe7499b8c8ed0b7122d9461138123b1eec485496783f91c00f77 SSDEEP : 192:RazYwJHF95GFYMQTa4wMkcQozaFvFsNrzsSi:SDHt1MQvnkcraFvFs ( File command ) ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=2a4501d573ee12ca1024974849d31c6fe6f111f6, not stripped ( TrID ) 50.1% (.) ELF Executable and Linkable format (Linux) (4025/14) 49.8% (.O) ELF Executable and Linkable format (generic) (4000/1)
IDAとデバッガで読める範囲だったので、こつこつ動かして動作を解析。 以下を11関数のチェックをすべて満たすものなら通る様子。
アドレス <関数名> 0x555555554cd0 <O0OO0O0O0O> ・文字列長が11ならOK 0x555555554ce4 <OOO00O0O00> ・スペースが含まれていなければOK 0x555555554cf8 <O0OO0O0O00> ・1文字目が "B" でなく、1文字目 * 2文字目 = 0xd96 であればOK 0x555555554d0c <O000O00O00> ・((1文字目 xor 2文字目) xor 3文字目) = 0x31 であればOK 0x555555554d1c <OO000OO000> ・3文字目より4文字目の方が文字コードが大きい ・3文字目を2乗したときの下位8ビット と 4文字目を2乗したときの下位8ビット が等しい 0x555555554d2c <O0OO0O00OO> ・5文字目と6文字目の文字コードが素数 ・5文字目 xor 6文字目 = 0x7e 0x555555554d3c <OOO00O00O0> ・(7文字目 sar 1) が素数 ・(6文字目 sub 0x2a) * 0x2 が 7文字目と等しい 0x555555554d4c <OO00O0O000> ・(8文字目が 0x2f より大きい) ・(8文字目が 0x39 以下) ・((8文字目 sar 2)*4) と8文字目が等しい 0x555555554d5c <O00OOOO000> ・不明 0x555555554d6c <OOOOO00O00> ・(9文字目 + 0x9) が10文字目と等しい 0x555555554d7c <O00OO0O0OO> ・(10文字目の文字コードを1ずつ減らして足し合わせる) の下位8ビットが11文字目と等しい #不明とした 0x555555554d5c は特に気にしなくても通ったので調べずに放置。
上記の条件を満たす文字を一つ一つつなぎ合わせていくと、例えば以下の文字が得られる。 判定は甘いので条件を満たす文字は幾通りかある。
J/TlC=&8*TJ %^JvC=&8*TJ
これを投入することでフラグが得られる。
$ nc chal.noxale.com 22234 Enter your string: J/TlC=&8*TJ Good job. Here is your flag: noxCTF{A5semb1y_Is_Grea7}
フラグ
noxCTF{A5semb1y_Is_Grea7}
更新履歴
- 2018-09-17 解き方のみを記載する形に修正。