この週末に開催されていた DefCamp CTF Qualification 2018 にチームで参加していました。
解いた問題について Write-up を記載します。
Memsome (Reverse)
解き方
添付ファイルはELF実行形式。
( Hash ) MD5 : ae0920bb2e98d56f4ee22fa5c83596b2 SHA1 : 84ec862f4024a0063eb565f1c3173b426c95adb9 SHA256 : 4b38b254a823731dbe4cdfc9073382f649d0555dee1b8ded47937aefb4a130de SSDEEP : 768:af6k2dd6kV7IYlQXGfoKrdjyNnJy11fJT0em80iOV3yQdE0jr6YC+Ryj:ay/ikVMYdfouJT+80iOV3yQdE0jr6P ( 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]=2acc3f22c1576a93402ac5c4f3d1f0ef88ca3db5, stripped ( TrID ) 50.1% (.) ELF Executable and Linkable format (Linux) (4025/14) 49.8% (.O) ELF Executable and Linkable format (generic) (4000/1)
普通に動かすとライセンスファイルがないよとエラーが表示される。
$ ./memsom Welcome! Scanning for license file! Unable to open the license file! Can not procced with the instalation.
IDAで見ると .secret-license-file というファイル名っぽい記述が見つかる。 その後に大きく分岐していることもあり、このファイルを読み込んでいそう。 適当な文字列を書き込んだファイルを置いてから再度実行すると表示が変わる。
$ ./memsom Welcome! Scanning for license file! Piracy is bad!
gdb で処理を見てみるが、start だとデバッガが落ちてしまう。
$ gdb -q ./memsom Reading symbols from ./memsom...(no debugging symbols found)...done. gdb-peda$ start No unwaited-for children left. 中止 (コアダンプ)
一旦 run で走らせてから start なら落ちずに動くようだった。 解決策を考えるより早そうなので、そこから ni や si でこつこつ処理を見ていく。
少し進めると入力文字を RO13 で処理している箇所がある。 最終的にどこかで ROT13 で戻す必要がありそう。
更にデバッガ検知判定などを避けつつ進めると、 いくつかの箇所で繰り返し処理が 0x45 だけ実施されていることに気づく。 ファイルに記載した文字列が1文字ずつ 0x45 回ほど切り出して処理されていたため、 ファイルに書き込むべき文字列長が 70 文字らしいことが分かる。 (そういえば IDA で見たときにも 0x45 'E' の表示がちょくちょくあった。)
その先ではファイルに記載した文字を1文字ずつ base64 で変換している箇所もあった。
何度か動かすうちに MD5 らしい文字列が繰り返し表示される箇所があることに気づく。 ファイルに書き込む文字を変えてみたが、同じ値で処理されていた。 数は 0x45 個。
怪しいので列挙して CrackStation にかけてみる。
0 98678DE32E5204A119A3196865CC7B83 1 e5a4dc5dd828d93482e61926ed59b4ef 2 68e8416fe8d00cca1950830c707f1e22 3 226C14D44CD4E179B24B33A4103963C2 4 0B3DFC575614989F78F220E037543E55 md5(md5) ew== { 5 75AC02C02F1F132E6C7314CAD02F17CD 6 DE32F4B8B17A37D87EA7436C6F215A34 7 DE32F4B8B17A37D87EA7436C6F215A34 8 0061f1f351a4cddda4257550dc7d3000 md5(md5) MQ== 1 9 0614AEBDC5C356C2CA0F192C8F6880CB a 75AC02C02F1F132E6C7314CAD02F17CD b DDB8E3FC866990482E44EC0B78AF08BD c 0061f1f351a4cddda4257550dc7d3000 md5(md5) MQ== 1 d DE32F4B8B17A37D87EA7436C6F215A34 e cfff0050c0b39cf3bdde5a373b96b8a1 f DE32F4B8B17A37D87EA7436C6F215A34 10 cfff0050c0b39cf3bdde5a373b96b8a1 11 1E14BF5FDCBF5EC3945729ED48110D23 12 E4AD919D695A4EC3DA99398D075AA21B 13 0F960E74A909D8558EEFD9AB9EE8DBF3 14 E4AD919D695A4EC3DA99398D075AA21B 15 cfff0050c0b39cf3bdde5a373b96b8a1 16 1E14BF5FDCBF5EC3945729ED48110D23 17 0F960E74A909D8558EEFD9AB9EE8DBF3 18 DE32F4B8B17A37D87EA7436C6F215A34 19 2933A2C8540FECA890144972DAAD94C4 md5(md5) Nw== 7 1a DAA65A87E8A3D171B4D141C1BA716E49 1b cfff0050c0b39cf3bdde5a373b96b8a1 1c 0614AEBDC5C356C2CA0F192C8F6880CB 1d 2933A2C8540FECA890144972DAAD94C4 md5(md5) Nw== 7 1e 0061f1f351a4cddda4257550dc7d3000 md5(md5) MQ== 1 1f C97A9650EF8EDF91D8C20734EC20112E md5(md5) Mw== 3 20 40A7E180EDE04D75B827585E9A1A547D 21 DE32F4B8B17A37D87EA7436C6F215A34 22 DAA65A87E8A3D171B4D141C1BA716E49 23 0614AEBDC5C356C2CA0F192C8F6880CB 24 6BD1E27CD9CD034BF3D1D39D3E75B29E 25 40A7E180EDE04D75B827585E9A1A547D 26 2933A2C8540FECA890144972DAAD94C4 md5(md5) Nw== 7 27 2933A2C8540FECA890144972DAAD94C4 md5(md5) Nw== 7 28 0F960E74A909D8558EEFD9AB9EE8DBF3 29 0F960E74A909D8558EEFD9AB9EE8DBF3 2a C97A9650EF8EDF91D8C20734EC20112E md5(md5) Mw== 3 2b C97A9650EF8EDF91D8C20734EC20112E md5(md5) Mw== 3 2c 9AB45911B5716C3104E44A8947BE4CF6 2d DDB8E3FC866990482E44EC0B78AF08BD 2e DE32F4B8B17A37D87EA7436C6F215A34 2f 2933A2C8540FECA890144972DAAD94C4 md5(md5) Nw== 7 30 0061f1f351a4cddda4257550dc7d3000 md5(md5) MQ== 1 31 DDB8E3FC866990482E44EC0B78AF08BD 32 6BD1E27CD9CD034BF3D1D39D3E75B29E 33 2933A2C8540FECA890144972DAAD94C4 md5(md5) Nw== 7 34 DAA65A87E8A3D171B4D141C1BA716E49 35 9AB45911B5716C3104E44A8947BE4CF6 36 E4AD919D695A4EC3DA99398D075AA21B 37 0061f1f351a4cddda4257550dc7d3000 md5(md5) MQ== 1 38 9AB45911B5716C3104E44A8947BE4CF6 39 FC496CE3C3E2E04604C375F7EDC3CBC4 md5(md5) MA== 0 3a DE32F4B8B17A37D87EA7436C6F215A34 3b cfff0050c0b39cf3bdde5a373b96b8a1 3c 0F960E74A909D8558EEFD9AB9EE8DBF3 3d 0061f1f351a4cddda4257550dc7d3000 md5(md5) MQ== 1 3e FC496CE3C3E2E04604C375F7EDC3CBC4 md5(md5) MA== 0 3f 1E14BF5FDCBF5EC3945729ED48110D23 40 DAA65A87E8A3D171B4D141C1BA716E49 41 C97A9650EF8EDF91D8C20734EC20112E md5(md5) Mw== 3 42 FC496CE3C3E2E04604C375F7EDC3CBC4 md5(md5) MA== 0 43 C97A9650EF8EDF91D8C20734EC20112E md5(md5) Mw== 3 44 40A7E180EDE04D75B827585E9A1A547D 45 44E18699A27596EDDD71B7920A04864B md5(md5) fQ== }
右端の文字列は復元された文字列が base64 だったのでデコード結果を付け加えたもの。 とてもフラグっぽい。
ただ「MQ==」の MD5 が表示の 「0061f1f351a4cddda4257550dc7d3000 」 にならないなぁと少し悩む。 ここまで来れば誰かしらすぐに解けそうなのでチームのチャットに結果を流して聞いてみる。 見事にメンバが最後のひと押しを解いてくれた。
さくっとスクリプトを作っていただき、フラグにたどり着いた。 MD5 を復元すると以下の文字列が出力される。
QPGS{9nn149q1n8n825s582sn7684713pn64rp77ss33oqn71qr76o51o0n8s1026303p}
これをROT13するとフラグが得られる。
私は MD5 が合わないと悩んでいたが、スクリプトでは MD5 したものにさらに MD5 していた。 CrackStation の結果を確認し直すと確かに md5(md5) と書かれていた。見落としていた。。。
ブレークポイントした箇所(抜粋)
- 0x555555556c70
- set $rax=0 で進める
- 0x555555556da2
- "Welcome! Scanning for license file!" の表示箇所
- 0x555555556e2d
- ファイル内容を読み取る箇所
- 0x555555556e48
- ROT13
- 0x555555556e96
- set $rax=$rdx で進める
- 0x555555556ee8
- md5 らしいものが出てくるところのひとつ。ここから 0x45個 出てくる。
- 0x5555555587bc
- ここでブレークポイントしておくとハッシュ値が綺麗に分かる。
フラグ
DCTF{9aa149d1a8a825f582fa7684713ca64ec77ff33bda71de76b51b0a8f1026303c}
Broken TV (Misc)
解き方
問題文から URL が与えられる。
https://broken-tv.dctfq18.def.camp/
アクセスすると画面が加工されたテレビの画像が表示される。 目を凝らすと文字が読み取れそうな感じもする。
画像は横にピクセルがずらされているだけのような感じがしたので、 ペイントで Google 検索窓の部分を復元を試みる。結果、以下のように可読文字列が得られた。
同じ要領でいくつかの箇所を復元してみるが、普通の検索結果のようだった。 改めて与えられた URL のソースコードを見ると、時刻によって得られるファイルが異なるような記載があった。 適当なタイミングで定期取得してみると、確かにハッシュ値が異なる。
$ md5sum blur.png* 299d6323aac070406523d5abb22fdc94 blur.png 299d6323aac070406523d5abb22fdc94 blur.png.1 23710719f90cda93ee103b8b744e94c8 blur.png.2 23710719f90cda93ee103b8b744e94c8 blur.png.3 8003468fb6a00cb53ba28738177aad98 blur.png.4 9cefe895abadce980c63f5a91c1c5457 blur.png.5 9cefe895abadce980c63f5a91c1c5457 blur.png.6 9cefe895abadce980c63f5a91c1c5457 blur.png.7 9cefe895abadce980c63f5a91c1c5457 blur.png.8 9cefe895abadce980c63f5a91c1c5457 blur.png.9 9cefe895abadce980c63f5a91c1c5457 blur.png.10 82800d36e44321abb94e45d93d98980e blur.png.11
さらに curl で更新時刻を見てみると1分毎に更新されていそうだと分かる。
curl -v で見た更新時刻: Last-Modified: Sat, 22 Sep 2018 15:32:03 GMT Last-Modified: Sat, 22 Sep 2018 15:33:03 GMT
画像を定期的に取得するシェルを走らせてみる。
while true;do wget https://broken-tv.dctfq18.def.camp/blur.png;sleep 40;echo "********************************"; done
本当は一晩やっていればいい感じの画像が降ってくるのではと思っていたが、 途中でぱらぱらと画像を見ているときに、フラグ文字列(sha256っぽい文字列)にできそうなものがあり気になったので手作業で復元してみる。
ペイントで切り出し、縦に引き伸ばして加工しやすくする。 黒線の端っこを合わせる要領でずれを修正していく。 結果として、以下の画像が得られる。
これを縦に縮小するとフラグが得られる。
フラグ
DCTF{1e20cabc8098b16cfeefb05af0a9032bb953871d6d627e7f88b81d1a3c5fa809}
SimplePassword (Junior)
解き方
添付ファイルはELF実行形式。
( Hash ) MD5 : a274ea5154cd236216b5ef9a1d208460 SHA1 : b4e5e2c417e5cbca034835eb80fbd92b2dd18955 SHA256 : 8c442a8ff2101da43f692c34e26288201d0d7b7e95da3c7322a3226bda792028 SSDEEP : 384:c0an3Cu8t+SkBkue0enIaMwtxsGr30uOjsYqw:E3CzDkB3yPtac0njMw ( 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]=caf8649b898078889978fa4a3be29437124c214c, 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 で見ると何段かの計算した結果と入力値を比較している様子。 簡単には答えが分かりそうにないので、デバッガで動かしてみる。
gdb で動かすと比較対象の数字が分かる。
これを入力するとフラグが得られる。
$ ./SimplePass Password? -366284240 DONE! The flag is DCTF{sha256(your_number)}!
$ echo -n -366284240 | sha256sum 554a58cfad51e0d7df7e8287fa96223780a249b104de60425908abf0b83c69aa
フラグ
DCTF{554a58cfad51e0d7df7e8287fa96223780a249b104de60425908abf0b83c69aa}