setodaNote

忘れる用のメモ書き

DefCamp CTF Qualification 2018 Write-up

この週末に開催されていた DefCamp CTF Qualification 2018 にチームで参加していました。

ctftime.org

解いた問題について 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/

アクセスすると画面が加工されたテレビの画像が表示される。 目を凝らすと文字が読み取れそうな感じもする。

f:id:soji256:20180924194420p:plain
Broken TV

画像は横にピクセルがずらされているだけのような感じがしたので、 ペイントで Google 検索窓の部分を復元を試みる。結果、以下のように可読文字列が得られた。

f:id:soji256:20180924194603p:plain
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っぽい文字列)にできそうなものがあり気になったので手作業で復元してみる。

f:id:soji256:20180924195329p:plain
フラグ感のある列を含む画像

f:id:soji256:20180924203537p:plain
フラグ感のある列(拡大)

ペイントで切り出し、縦に引き伸ばして加工しやすくする。 黒線の端っこを合わせる要領でずれを修正していく。 結果として、以下の画像が得られる。

f:id:soji256:20180924195501p:plain
復元した画像

これを縦に縮小するとフラグが得られる。

フラグ

DCTF{1e20cabc8098b16cfeefb05af0a9032bb953871d6d627e7f88b81d1a3c5fa809}

f:id:soji256:20180924195605p:plain
フラグ

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 で動かすと比較対象の数字が分かる。

f:id:soji256:20180924201143p:plain
比較対象の数字

これを入力するとフラグが得られる。

$ ./SimplePass 
Password?
-366284240
DONE! The flag is DCTF{sha256(your_number)}!
$ echo -n -366284240 | sha256sum 
554a58cfad51e0d7df7e8287fa96223780a249b104de60425908abf0b83c69aa

フラグ

DCTF{554a58cfad51e0d7df7e8287fa96223780a249b104de60425908abf0b83c69aa}