mattun_martの日記

CTFとかセキュリティとか.

WhiteHat Contest 2017参加記

shpxというチームでベトナムのCTF WhiteHatContest2017に参加.
チームは200点獲得して76位.私は一問も解けなかった...
ということで簡単に感想でも.

昨年のSECCONからCTFは参加し始めたがCTFで一問も解けなかったのはこれが初めて.
かなり悔しいし,チームメンバーへの申し訳なさが半端ない.
CTFではフォレンジクスのdai lai lakeとREのTuy Hoaに主に取り組んでいた.
dai lai lakeは,apkファイルを解析してflagを見つけ出すような問題.
apkファイルの中身をデコンパイルしたりしてflagを探したりしていたが結局わからず.
あぁ...apkファイル嫌いになりそう.
Tuy Hoaはパスワードの入力を求められるバイナリを解析してflagをゲットする問題.
アセンブリ読んでパスワードチェックの仕組みはわかったのだが,そこからパスワードを予測する方法が思いつかず.

最近空き時間にセキュリティ関連の本を読んだりはしているけどCTF関連のWriteup読んだりや過去問を解いたりということはできてない.
やはりCTFの点取るならやっぱりCTF向けの勉強をするべき.
CTFと実際のセキュリティは同じようで異なる点も多いってのは実感してきた.
バランスと両者をどうつなげるかが重要な気がする.
あと,今はとっつきやすそうな問題から手を付けてるから一度一つの分野を重点的にやったほうがよさそう.
どの分野にするか...

angstromCTF 2017 Writeup

4月下旬にangstromCTF2017にshpxというチームで参加.
1週間という長丁場なCTFだったので,空いてる時間を見つけて参加した感じ.
チームとしては780点獲得して15位だった.
私は8問解いて310点獲得.(そのうち1問はチームメンバーと協力して解いた)

f:id:mattun_mart:20170503034423p:plain

The Beginning(crypto 10)

次のような問題文が書かれている.

Pxevhfx mh tgzlmkhfvmy. Px ahix rhn xgchr hnk vmy. tvmy{utvd_mh_max_ynmnkx}.

ただのシーザー暗号.rot7で復号できる.

Welcome to angstromctf. We hope you enjoy our ctf. actf{back_to_the_future}.

flagはactf{back_to_the_future}.

Knock Knock(crypto 30)

一定の長さの連続したノック音が入った音声ファイルを渡される.
ノック音の回数は1~5であり,それぞれ区切られている.
答えから言うとtap codeという暗号.
次のtap code tableに従ってテキストの各文字が一定の長さの連続したノック音2つに変換されている.
縦の数字が1回目のノック音の回数,横の数字が2回目のノック音の回数.

0 1 2 3 4 5
1 A B C/K D E
2 F G H I J
3 L M N O P
4 Q R S T U
5 V W X Y Z

音声ファイルのノック音をカウントしてみると以下のようになる.

2 3 1 5 3 1 3 5 3 2 1 5 3 5 3 1 1 5 1 1 4 3 1 5

一文字は2つのノック音に暗号化されているので,上記の表に従って復号してみると次のようなメッセージが得られる.

文字番号 1回目 2回目 復号結果
1 2 3 H
2 1 5 E
3 3 1 L
4 3 5 P
5 3 2 M
6 1 5 E
7 3 5 P
8 3 1 L
9 1 5 E
10 1 1 A
11 4 3 S
12 1 5 E

flagはHELPMEPLEASE.
最初はモールス信号かと思った.

Substitution Cipher(crypto 60)

次のような暗号文が渡される.

vfauedwyedmtlwylwnawyjfdzltqilqdezfntmwyewyejzettjedmwyfjlzettjyeilwfplxaenmlmpvbldzqwyxadjzyfjxfddemfqwvfavfatwzlqdplnxqyeilexnlewlnnljsfdjqpqtqwvwyedvfauedsfjjqptvoewyfbvfazllsofnjedwqexfedmvfauanjlwylbenqdljvfayeilwyewtaranvvfayeilwyltaranvfodfwcdfzqdxzyewqcdfzwyewjedwqexfjmlewyzyqtlwnexqusnfpeptvjeilmtqiljedmbvlrqjwldulzyqtlxnfwljgaledmqdufbsnlyldjqptlwfvfajeiljtqiljvfamfdwzedwwylwnawyplueajlmllsmfzdqdsteuljvfamfdwwetcepfawewsenwqljvfazedwblfdwyewzettvfadllmblfdwyewzettzlajlzfnmjtqclyfdfnufmltfvetwvzlajlwyljlzfnmjejwylpeucpfdlwfetqoljsldwmloldmqdxjfblwyqdxvfaajllbejesaduytqdlqyeildlqwylnwylwqbldfnwylqdutqdewqfdwflrsteqdbvjltowfebedzyfnqjljedmjtllsjadmlnwylptedclwfowylilnvonllmfbqsnfiqmlwyldgaljwqfdjwylbeddlnqdzyquyqsnfiqmlqwqmnewylnvfahajwjeqmwyedcvfaedmzldwfdvfanzevfwylnzqjlqjaxxljwvfasqucasezlesfdedmjwedmesfjwlqwylnzevqmfdwxqilemebdzyewvfawyqdcvfanlldwqwtlmwf{olzxffmbldhljjls}


単一換字式暗号なので頻度分析をして地道に解読していけば良い.
こちらを使いながら頻度分析し,vimを使って予測したアルファベットを大文字に置換していった.
文字出現頻度分析ツール - instant tools
例えばこの問題の場合,lの出現頻度が一番多いのでEに対応しており,次に出現頻度の高いwはTに対応していると予想.
TとEがわかれば,出現率の高いTyEの文字列はTHEである可能性が高いので,yはHに対応していると予想.こんな感じで分析結果や英文によく出る単語などの知識を駆使して頑張る.

頑張って解読した結果は次の通り.

youcanthandlethetruthsonweliveinaworldthathaswallsandthosewallshavetobeguardedbymenwithgunswhosgonnadoityouyoultweinbergihaveagreaterresponsibilitythanyoucanpossiblyfathomyouweepforsantiagoandyoucursethemarinesyouhavethatluxuryyouhavetheluxuryofnotknowingwhatiknowthatsantiagosdeathwhiletragicprobablysavedlivesandmyexistencewhilegrotesqueandincomprehensibletoyousaveslivesyoudontwantthetruthbecausedeepdowninplacesyoudonttalkaboutatpartiesyouwantmeonthatwallyouneedmeonthatwallweusewordslikehonorcodeloyaltyweusethesewordsasthebackbonetoalifespentdefendingsomethingyouuseemasapunchlineihaveneitherthetimenortheinclinationtoexplainmyselftoamanwhorisesandsleepsundertheblanketoftheveryfreedomiprovidethenquestionsthemannerinwhichiprovideitidratheryoujustsaidthankyouandwentonyourwayotherwiseisuggestyoupickupaweaponandstandaposteitherwayidontgiveadamnwhatyouthinkyoureentitledto{fewgoodmenjessep}

flagは{fewgoodmenjessep}.

単一換字式暗号は頻度分析で解読できることは知っていたが,実際にやったのは初めて.
途中で一部文字の対応が間違っていて苦戦した.
結構慣れが必要な気がする.

USB Encryption(forensics 30)

DEFUND.dmgという名前のdmgファイルを渡される.
7zipで中身を見てみるとDEFUND.dmg\Thumbs.us\com1.{2227a280-3aea-1069-a2de-08002b30309d}\zᄆ요ᄚ\Dᄆ\の中にflag.txtがあった.
flag.txtの中にflagが書かれている.

flagはactf{not_quite_usb_encryption}.

最初はdmgファイルの中身をmacで見て,中に唯一入っていたUSBセキュリティソフトの名前がflagだと思って悩んでた.(ヒントに実際のソフトウェアとか書かれてたし...)

Image Trickery(forensics 50)

次のようなpngファイルを渡される.
f:id:mattun_mart:20170503041046p:plain

バイナリエディタに突っ込んで,bitimageを見てみると下のほうに規則的な模様がある.
画像の中に情報が埋め込まれてるっぽい.いわゆるステガノグラフィ―.
f:id:mattun_mart:20170503041008p:plain

Image Magickを使って画像をエッジ処理してみるとQRコードが出てきた.
f:id:mattun_mart:20170503040519p:plain

このままだと読み込めなかったのでImage Magickを使って2値化処理.
f:id:mattun_mart:20170503040549p:plain

このQRコードを読み込むと,次のURLが出てくる.
http://pastebin.com/S9De6WYA

このページにあるデータをBASE64でデコードするとdata URIsvgファイルが出てくるので,開くと画像の中にflagが書いてある.
f:id:mattun_mart:20170503040608p:plain

falgはactf{fa1L_F15H}

Document(forensics 60)

破損したessay.docxファイルを渡される.
ワードで開こうとしても破損していて開けない.修復もできない.
docxファイルはXML形式のファイルzipしたものなので,拡張子をzipに変更して中身を見てみるとessay.zip\word\document2.xmlの中にflagがある.

flagはactf{too_bad_for_zip_recovery}

Captcha1(web 70)

チームメンバーと一緒に解いた.

色が赤,青,緑色,形が四角,三角,円のいずれかの図形が散りばめられた画像.そして,特定の色,形の図形の数とpin番号を入力するフォームがあるページが表示される.(スクショ取るの忘れた...)
pin番号は3桁なので総当たりで破れる範囲.後は画像に表示された特定の図形の数をどうにかすればよい.
図形の数は間違った数が入力されてもまた同じ図形の数について問われるので,図形の数が当たるまで同じPINでリクエストを投げる.
これを001~999すべてのpinで試す.

チームメンバーがrubyで書いてくれた.図形の数は1~10の範囲で回した.

require ‘net/http’
require ‘uri’

# POST
(ARGV[0]..ARGV[1]).each do |pin|
 STDERR.puts ‘pin:’ + format(“%03d”, pin)
 10.times do |n|
   res = Net::HTTP.post_form(URI.parse(‘http://web.angstromctf.com:1342/’),{‘question1’ => n.to_s, ‘pin’ => format(“%03d”, pin)})
   unless res.body.include?(‘Bad’)
        STDERR.puts res.body
        unless res.body.include?(‘Wrong’)
          puts “flag get”
          exit(0)
        end
        break
   end
 end
end

PINの値は612.
flagはactf{comp_abstract_art_2F239B}

感想

割と多くの問題を解けたのは良かったが,得点の高い問題はまだなかなか解けない.
他に取り組んでいた問題としては,Broken PasscodeとかHeadphonesとか.
Broken Passcodeはapkファイル解析してAndroidManifest.xmlのmeta-dataの鍵っぽいのは見つけたけどそこからアプローチ法が全く分からず時間を浪費.
かなり粘着してたので解きたかったなぁ...
3月4月とCTFに出てみて思ったのは見切りも大事ということ.
結構ひとつの問題に粘着してしまうところがある.
あと今回pwnの問題をチームメンバーが一人でサクサク解いてしまったのすごい.というか彼強い.
就活中なのであまりがっつりCTFできないけど,pwn系も解けるように地道に頑張りたい.

VolgaCTF 2017 Quals writeup

VolgaCTF 2017 Qualsにshpxというチームで参加.
私は日曜に予定が入っていたため土曜のみ参加だった.
チームとしては700点,個人としては150点獲得し117位.
すでにwriteupは出ているが,自分のためにもwriteup書く.

VC (crypto 50)

A.pngとB.pngという画像を渡される.ここからフラグを探し出す.
A.pngとB.pngの差分を取ればフラグが出てくる.
ImageMagickコマンドラインツールで以下のコマンド実行し2つの画像の差分画像を生成.

composite -compose difference A.png B.png diff.png

次のような差分画像が生成され,その中にフラグがある.
f:id:mattun_mart:20170328012218p:plain

この問題他のチームメンバーが先に解いていたのに気づかず自分も解いていた.

Keypass (reverse 100)

入力したパスフレーズから鍵を生成するプログラムkeypassとaes-128-cbcで暗号化されたzipファイルflag.zip.encが渡される.
keypassでいろいろパスフレーズを入力してみると,生成される鍵に結構被りがあることがわかる.

  • ./keypass aa -----> BWf81zF%SdkxL*jL.
  • ./keypass aaaa -----> BWf81zF%SdkxL*jL.
  • ./keypass bbbb -----> BWf81zF%SdkxL*jL.

ここでおそらく生成される鍵のパターンはそこまで多くなく,総当たりでいけそうと予想.
とりあえずアルファベットと数字を使った4ケタのパスフレーズから鍵を生成して復号してみるとすぐに復号できた.
ただし,ヒントにOpenSSL 1.1.0eが使われていることが書かれているため,このバージョンを使用する必要がある.

# -*- coding:utf-8 -*-
from itertools import product
import subprocess

chars = 'abcdefghijklmnopqrstuvwxyz1234567890'
key_list = []
patterns = product(chars, repeat=4)
for pt in patterns:
	command = "./keypass " + ''.join(pt)
	key = subprocess.check_output(command.split(" "))
	if key not in key_list:
		key_list.append(key)
		key = key.strip()
		
		command = "openssl enc -aes-128-cbc -d -pass pass:\"" + key + "\" -in flag.zip.enc -out flag.zip"
		proc = subprocess.Popen(command.strip(" "), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

		result = proc.stdout.read()
		proc.wait()

		if proc.returncode == 0:
			print "decrypt OK"
			print key
			break

あとは復号したzipファイルを解凍してフラグゲット.

$python decrypt.py
decrypt OK
\M)R<.DDe/:;d>JZP

$unzip flag.zip
Archive:  flag.zip
 extracting: flag.txt 

$cat flag.txt
VolgaCTF{L0ve_a11_trust_@_few_d0_not_reinvent_the_wh33l}

ちょっと試したらすぐに解けてしまったためあまり逆アセンブルしたコードを読んでいないが,鍵生成処理はパスフレーズの各文字のXORを取った値をseedとしてパスフレーズを生成しているらしい.

 4004e8: 48 0f be 07           movsx  rax,BYTE PTR [rdi]
 4004ec: 48 83 c7 01           add    rdi,0x1
 4004f0: 48 31 c2              xor    rdx,rax
 4004f3: 48 39 cf              cmp    rdi,rcx
 4004f6: 75 f0                 jne    4004e8 <__libc_start_main@plt+0x68>

結局256通りに絞られるみたい.

感想

その他にもAngry Guessting Gameなどにトライしていたが,reversing力全然足りてない感をかなり感じた.
少しずつレベル上げていきたい.