TrendMicro CTF(TMCTF) 2015 Online Qualifier 解けた問題などWriteup
Trendmicro CTF 2015のOnline Qualifier(TMCTF)をやってみました。
大学の友人がCTFにやる気を出していたので、今回はいつものチームではなく大学の友人3人でチーム"sagume"として出ました。
結果としては700点ほどしかとれませんでしたが、大学の友人に教えたり教えられたりとワイワイやりながらやるCTFは楽しかったです。
以下Writeup
Prog100
Click on the different color.
http://ctfquest.trendmicro.co.jp:43210/click_on_the_different_color
一つだけ違う色のタイルが表示され、それをクリックすると次に飛ぶといった問題。
進んで行くにつれてタイル数が増えていく。
イメージはこんな感じ。 http://game.ioxapp.com/eye-test/game.html
<html> <head> <title>Choose the different color</title> <script type=text/javascript src="/js/jquery.min.js"></script> <script type=text/javascript> <!-- function clicked(e) { var x=e.layerX-e.target.x; var y=e.layerY-e.target.y; window.location.href='/5cfe6d025d390ffa640c8cd3ac83b0e560705a001826?x='+x+'&y='+y; } // --> </script> </head> <body> <img src="/img/5cfe6d025d390ffa640c8cd3ac83b0e560705a001826.png" onClick="clicked(event)"> </body> </html>
解法
htmlを取得してBeautifulSoupで解析、画像を取得して、順番に色のデータのリストを作ってその中で一つしかないものを抽出してリクエストを送信。
最初は目grepでやってたけど、16x16からつらくなったのでスクリプト化した。 適当に分割して中心付近を適当に取得すれば行けるやろって感じで進めていくと、64くらい?から2x2px, 1x1pxになって悲しみを背負った。
# -*- coding: utf-8 -*- from PIL import Image from bs4 import BeautifulSoup import requests import sys HEADERS = { 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25', 'Accept-Language': 'ja,en-us;q=0.7,en;q=0.3', 'Accept': 'text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1' } def calc(num, imgpath): img = Image.open(imgpath) width, height = img.size box = (5, 5, width, height) img = img.crop(box) colors = [] width, height = img.size ds = (width + 1) / num for i in range(num): wmin = int(ds * i) wmax = int(ds * (i + 1)) for j in range(num): k = num * i + j hmin = int(ds * j) hmax = int(ds * (j + 1)) box = (wmin, hmin, wmax, hmax) c = img.crop(box) choice_pixel = (wmin, hmin) pixelcolor = img.getpixel(choice_pixel) colors.append((pixelcolor, (i + 1, j + 1), choice_pixel)) only_color_list = [c for c, _, _ in colors] for c, p, choicepix in colors: if only_color_list.count(c) == 1: print("FOUND!", choicepix) print(p) return choicepix else: return None base_url = "http://ctfquest.trendmicro.co.jp:43210" i = 2 r = requests.get(base_url + '/click_on_the_different_color', headers=HEADERS) post_ans_url = base_url + '/click_on_the_different_color' while True: print(i) html = BeautifulSoup(r.text) img_url = base_url + html.body.img["src"] filename = img_url[:-4] print(filename) r = requests.get(img_url, headers=HEADERS) with open("./image-tmp.png", "wb") as fp: fp.write(r.content) p = calc(i, "./image-tmp.png") if p is None: with open("result.png", "wb") as fp: print("CONTINUE") fp.write(r.content) r = requests.get(post_ans_url, headers=HEADERS) continue print(filename) filename = img_url[42:-4] post_ans_url = base_url + filename + "?x={0}&y={1}".format(p[0] + 5, p[1] + 5) print(post_ans_url) r = requests.get(post_ans_url, headers=HEADERS) if r.text == "Too late": print("TOOLATE!! EXIT") quit() i += 1
TMCTF{U must have R0807 3Y3s!}
汚いコードですがご容赦ください
Prog200
Calculate it.
nc ctfquest.trendmicro.co.jp 51740
計算問題。nc で接続すると式が降ってくるので計算して返す。
[1] 1 - 9 = -8
[2] 8 + 5 - 67 = -54
[3] 63 + 861 * 48 - 3 = 41388
[4] 273 + 9533 * 7888 + 162 * 627 = 75298151
[5] 75 * 95410 - 3 + 8284 * 92 - 5137 = 7912738
[6] 4879 * 80 + 4671 - 3 * 3961 - 69872 * 7063 =
途中からローマ数字や英単語数字が出てくる。
[35] ( CLXXXIX - MMCCLXIII ) * ( VII + 5288 ) * DLXXVIII + CMXLVI =
[46] four thousand, two hundred forty * ( 309,912 + four hundred twenty seven ) * ( six hundred twenty one thousand, eight hundred thirty one - twenty thousand, four hundred sixty seven ) * eight hundred forty + eighty eight thousand, nine hundred twenty three =
解法
式を受け取り、eval()する。途中のローマ数字や単語数字はググッてパース出来る関数を探してきた。
ただし、連なっている単語数字の判定が必要だったので、その部分を書いた。
具体的には、1単語で変換可能なものは次の単語も見て、それも合わせて再変換する。その後、また次の単語も見て再変換...を繰り返して、Exceptionが吐かれた=変換不能となったら終了とした。
solve.py
# -*- coding: utf-8 -*- import telnetlib import prog200libs tn = telnetlib.Telnet() tn.open("ctfquest.trendmicro.co.jp", 51740) i = 1 while True: msg = tn.read_until(b" = ").decode() print("[{0}] {1}".format(i, msg), end="") raw = msg[:-3].replace(',', '') # roman def roman_check(raw): for r in ('M', 'D', 'C', 'L', 'X', 'V', 'I'): if r in raw: return True return False transformed = [] for a in raw.split(): if roman_check(a) and a not in ('-', '+', '*', '/'): t = str(prog200libs.roman_to_num(a)) transformed.append(t) else: transformed.append(a) else: raw = ' '.join(transformed) # text to int transformed = [] split_raw = raw.split() index = 0 while index < len(split_raw): try: s = split_raw[index] res = str(prog200libs.text2int(split_raw[index])) while index < len(split_raw): try: s += " " + split_raw[index + 1] res = str(prog200libs.text2int(s)) except: break index += 1 transformed.append(res) except: transformed.append(split_raw[index]) index += 1 else: raw = ''.join(transformed) ans = eval(raw) print(ans) tn.write(str(ans).encode() + b'\n') i += 1
prog200libs.py
def roman_to_num(roman): num = 0 r_n = { 'M': 1000, 'D': 500, 'C': 100, 'L': 50, 'X': 10, 'V': 5, 'I': 1 } pre = 0 for i in range(len(roman) - 1, -1, -1): c = roman[i] if not c in r_n: raise Exception('有効なローマ数字になっていない!: {}'.format(c)) n = r_n[c] if n >= pre: num += n pre = n else: num -= n return num def text2int(textnum, numwords={}): if not numwords: units = [ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", ] tens = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"] scales = ["hundred", "thousand", "million", "billion", "trillion"] numwords["and"] = (1, 0) for idx, word in enumerate(units): numwords[word] = (1, idx) for idx, word in enumerate(tens): numwords[word] = (1, idx * 10) for idx, word in enumerate(scales): numwords[word] = (10 ** (idx * 3 or 2), 0) current = result = 0 for word in textnum.split(): if word not in numwords: raise Exception("Illegal word: " + word) scale, increment = numwords[word] current = current * scale + increment if scale > 100: result += current current = 0 return result + current
結果
[100] 4364133 - 953,422 + one hundred ninety one million, four hundred ninety seven thousand, three hundred eighty five * ( three hundred fifty two + four million, forty eight thousand sixty nine ) * ( 3 + 75 ) * ( twelve + 33660154 ) * ( 83664191 + five hundred fifty eight thousand, three hundred fifty nine ) = 171430368741839902987854582089711 [101] Congratulations! The flag is TMCTF{U D1D 17!}
Analysis-defensive 300
This is a REAL backdoor network traffic!
Tracing hacker's footprint to find the key!If you can get "the password", please submit "TMCTF{
}" as your answer. Hint:
Poison Ivy / admin
attach: zipfile(pcap)
pcapファイルが渡される。中身はPoizon Ivyのトラフィックログのようだ。
開いてみてもただ暗号化されたパケットが流れているだけでとくに得られる情報はない。
Poizon Ivyは標的型攻撃などで使用される最も有名なRATツール(Remote Administration Tool)の一つ。現在でも様々な亜種が生まれており、最近でも新しい機能が追加され、改良され続けている。*1。
C&Cサーバーとの通信やリモートシェルによるコマンドの実行、暗号化など基本的な動作に加え、マルウェア(バックドア)のビルド機能、スクリーンショット、プラグイン機能などを備えており、目的に合わせたマルウェアを作成可能である。
あまりにも有名なため、セキュリティベンダによる解析が進められており、動作解析レポートも公開されている。
解法
PIVYのトラフィック(pcap)を解析し、標的となっている端末内のデータを取得する。
PIVYは通信の初めに256byteの暗号化キー(平文)を格納しており、それを使用して通信を行う*2ため、解読が可能。Camellia cipherが使用されている。
手作業で一つ一つ暗号化解除するのだるい...と思っていたら、MITREがChopshop
というProtocol Analysis/Decoder Frameworkを出しており、これを使用すれば良いとFireeyeのレポート*3に書いてあった。
github.com
早速kali linuxに落としてきて、make
して起動。make時にいろんな依存ライブラリが必要なのでインストールが大変.....
使用方法はchopshop内のDocsを参考に色々試してみた。pluginの中にpoisonivy_23x
というモジュールが入っているのでこれを使用する。コマンドは--help
やDocsを参考に頑張って組み立てた。
./chopshop -f /vboxshare/tmctf/net.pcap "poisonivy_23x -p /usr/local/lib/python2.7/dist-packages/camcrypt/camellia.so -f -c -l " -s save
実行すると以下の様なログが出る
>> ~/Documents/ctf/tmctf/chopshop root@murasa# ./chopshop -f /vboxshare/tmctf/net.pcap "poisonivy_23x -p /usr/local/lib/python2.7/dist-packages/camcrypt/camellia.so -f -c -l " -s save Warning Legacy Module poisonivy_23x! Starting ChopShop (Created by MITRE) Initializing Modules ... Initializing module 'poisonivy_23x' Running Modules ... [2015-09-04 17:43:44 JST] Poison Ivy Version: 2.32 [2015-09-04 17:43:44 JST] *** Host Information *** PI profile ID: ctf IP address: 192.168.0.100 Hostname: ADMIN-PC Windows User: Administrator Windows Version: Windows XP Windows Build: 2600 Service Pack: Service Pack 3 [2015-09-04 17:43:58 JST] *** Directory Listing Initiated *** Directory: C:\WINDOWS\ [2015-09-04 17:43:58 JST] *** Directory Listing Sent *** PI-directory-listing-1.txt saved.. [2015-09-04 17:44:57 JST] *** Service Listing Sent *** PI-service-listing-2.txt saved.. [2015-09-04 17:45:06 JST] *** Screen Capture Sent *** PI-extracted-file-3-screenshot.bmp saved.. Shutting Down Modules ... Shutting Down poisonivy_23x Module Shutdown Complete ... ChopShop Complete
-sで指定したディレクトリに書き出されるので確認する。
>> ~/Documents/ctf/tmctf/chopshop/save root@murasa# ls -la total 844 drwxr-xr-x 2 root root 4096 Sep 27 03:31 . drwxr-xr-x 14 root root 4096 Sep 27 03:27 .. -rw-r--r-- 1 root root 9738 Sep 27 18:34 PI-directory-listing-1.txt -rw-r--r-- 1 root root 810054 Sep 27 18:34 PI-extracted-file-3-screenshot.bmp -rw-r--r-- 1 root root 29544 Sep 27 18:34 PI-service-listing-2.txt
bmpに答えが書いてあった。
TMCTF{May_Flower}
セキュリティベンダっぽい問題で面白いなと思いました。こういうセキュリティっぽい問題増えて欲しいですね。
Analysis-defensive 100
取り組みだすのが遅すぎて解答を提出できなかったけど、終了後答えが出たので書いておきます。早起きすべきだった。
vonnというx64のELFが渡されるのでリバースエンジニアリングして動作を解析する問題。
そのまま実行すると自分自身を消してしまう。また、VM検知が入っておりマルウェアっぽい挙動をする。
解法
gdbで動かしながら実行する。
mainの最初でVM検知が入っており、それにより分岐が行われるみたいなので、jumpして次の動作へ飛ばした。
すると、...,,,...
を/tmp以下に生成するというマルウェアっぽい動きをするので、確認するとコレも実行ファイルだった。そのまま続けると...,,,...
に動作を移行し、終了すると自己を消去する。動作を続けると終了へ飛ぶ判定があるので、その部分を飛ばすとフラグprintへ移行した。
TMCTF{ce5d8bb4d5efe86d25098bec300d6954}
提出できなかったないけど多分これ
まとめ
TMCTF、セキュリティ寄りの問題も多く、非常に楽しめました。少しばかりエスパーっぽい問題が多いという声もありますが、おそらく経験で補える範囲だと思うので精進したいです。
あと、24時間という時間の割に問題数がそれなりにあったので、見れてない問題も多かったです。Writeup見ながらやります。
*1:https://www.jpcert.or.jp/magazine/acreport-poisonivy.html
*2:http://www.trendmicro.com/cloud-content/us/pdfs/security-intelligence/white-papers/wp-detecting-apt-activity-with-network-traffic-analysis.pdf
*3:https://www.fireeye.com/content/dam/fireeye-www/global/en/current-threats/pdfs/rpt-poison-ivy.pdf