CpawCTF 挑戦記
アカウントのパスがわからなくなって最初からやり直しに…。
writeup作成の可否は書かれていなかったので、一応メモを残す(自分用)けど、畳んでおきます。
レベル1
Q1.[Misc] Test Problem
flag: cpaw{this_is_Cpaw_CTF}
Q6.[Crypto] Classical Cipher
Caesar暗号。この辺でデコードする。
Caesar cipher: Encode and decode online — Cryptii
flag: cpaw{Caesar_cipher_is_classical_cipher}
Q7.[Reversing] Can you execute ?
$ file exec_me exec_me: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=663a3e0e5a079fddd0de92474688cd6812d3b550, not stripped
64ビットLinux環境で動くELF実行ファイル。chmod +x
をしてから実行。
flag: cpaw{Do_you_know_ELF_file?}
Q8.[Misc] Can you open this file ?
$ file open_me open_me: Composite Document File V2 Document, Little Endian, Os: Windows, Version 10.0, Code page: 932, Author: ?v??, Template: Normal.dotm, Last Saved By: ?v??, Revision Number: 1, Name of Creating Application: Microsoft Office Word, Total Editing Time: 28:00, Create Time/Date: Mon Oct 12 04:27:00 2015, Last Saved Time/Date: Mon Oct 12 04:55:00 2015, Number of Pages: 1, Number of Words: 3, Number of Characters: 23, Security: 0
wordファイルなので、拡張子をdocにして開く。
flag: cpaw{Th1s_f1le_c0uld_be_0p3n3d}
Q9.[Web] HTML Page
ソースのheadタグ、メタデータ内にフラグがある。
flag: cpaw{9216ddf84851f15a46662eb04759d2bebacac666}
Q10.[Forensics] River
ファイルに付加されるメタ情報(Exif)はExiftool等で見られる。
$ exiftool river.jpg (snip) GPS Position : 31 deg 35' 2.76" N, 130 deg 32' 51.73" E (snip)
緯度経度から、Google mapで見てみると、甲突川。
flag: cpaw{koutsukigawa}
Q11.[Network]pcap
wireshark開くと、1番目の通信がdataを送っているので、見るとフラグ。
flag: cpaw{gochi_usa_kami}
ごちうさは神。
Q12.[Crypto]HashHashHash!
SHA-1。既知のハッシュ値なので、google検索で出てくる。
flag: cpaw{shal}
Q14.[PPC]並べ替えろ!
p = [15,1,93,52,66,31,87,0,42,77,46,24,99,10,19,36,27,4,58,76,2,81,50,102,33,94,20,14,80,82,49,41,12,143,121,7,111,100,60,55,108,34,150,103,109,130,25,54,57,159,136,110,3,167,119,72,18,151,105,171,160,144,85,201,193,188,190,146,210,211,63,207] p.sort(reverse=true) x = ''.join(map(str, p))
flag: cpaw{2112102072011931901881711671601591511501461441431361301211191111101091081051031021009994938785828180777672666360585755545250494642413634333127252420191815141210743210}
レベル2
Q13.[Stego]隠されたフラグ
左上と右下に小さくモールス信号が書かれている。-.-. .--. .- .-- .... .. -.. -.. . -. ..--.- -- . ... ... .- --. . ---... -.--.-
オンラインデコーダに貼り付けて、デコードされた文字列をフラグの形式に整形する。
flag: cpaw{hidden_message:)}
Q15.[Web] Redirect
Wiresharkとかでもいいが、Google Chromeの開発者ツールを起動した状態でサイトにアクセスすると、Networkタブに遷移が記録される。
302で誘導される最初のサイトのレスポンスヘッダにフラグがセットされている。
flag: cpaw{4re_y0u_1ook1ng_http_h3ader?}
Q16.[Network+Forensic]HTTP Traffic
Wiresharkで開き、Export Object > HTTP
で全てをexportする。
"network100"ファイルに.html
拡張子を付け、そのディレクトリ配下にcss/
、js/
、img/
ディレクトリを作って.css、.js、*.imgをそれぞれ配置する。
ブラウザでローカルのnetwork100.htmlファイルを開くと動作する。
flag: cpaw{Y0u_r3st0r3d_7his_p4ge}
Q17.[Recon]Who am I ?
OSINT問題かな?アカウント名とゲーム名でぐぐると、チーム名が載った画像が引っかかってくる。
(今やwriteupの方が沢山引っかかってくるけど)
flag: cpaw{parock}
Q18.[Forensic]leaf in forest
pcapファイルに見せかけたほぼテキストファイル。
In [8]: with open('misc100', 'rb') as f: ...: data = f.read() ...: data = data[16:].decode() ...: s = '' ...: for d in data: ...: if d not in 'lovelive!': ...: s += d ...: ans = ''.join([s[i] for i in range(0, len(s), 3)]) ...: print(ans.lower()) cpaw{mgrep}
いつもながらスクリプトが拙くてかなしい
flag: cpaw{mgrep}
Q19.[Misc]Image!
zipファイル内の構成を見るとdocファイルっぽいので、拡張子を.docにして開く。
flag: cpaw{It_is_fun__isn't_it?}
Q20.[Crypto]Block Cipher
第2引数(key)に数値を与えて、その文字数単位のブロックで逆順にするコード。
In [24]: c = 'cpaw{ruoYced_ehpigniriks_i_llrg_stae}'[5:-1] ...: for key in range(1, 10): ...: a = ''.join([c[i:i+key][::-1] for i in range(0, len(c), key)]) ...: print('cpaw{' + a + '}') cpaw{ruoYced_ehpigniriks_i_llrg_stae} cpaw{urYoec_dheipngriki_s_illgrs_ate} cpaw{ourecYe_diphingkiri_sll__gratse} cpaw{Your_deciphering_skill_is_great}
key=4の時それっぽい文字列になる。大文字の出現位置から予測しても良いと思う。
flag: cpaw{Your_deciphering_skill_is_great}
Q21.[Reversing]reversing easy!
出題文ではフラグを出す処理を入れ忘れたらしいが、意図的にカッコ内を出力しないようにしているように見えるけども。
flag: cpaw{yakiniku!}
Q22.[Web]Baby's SQLi - Stage 1-
まずはSQL文を書くだけの練習。select * from palloc_home;
flag: cpaw{palloc_escape_from_stage1;(}
Q28.[Network] Can you login?
FTPの通信。TCP stream 2でログインに成功しているのでFollow TCP streamでそれを見ると、ユーザがcpaw_user
、パスワードが5f4dcc3b5aa765d61d8327deb882cf99
であることがわかる。
あとはFTPクライアントなりftpコマンドなりで接続すればよいが、フラグファイルが隠しファイルなことに注意。
ftp> ls -al 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxr-xr-x 2 ftp ftp 42 Jun 18 2019 . drwxr-xr-x 2 ftp ftp 42 Jun 18 2019 .. -rw-r--r-- 1 ftp ftp 39 Sep 01 2017 .hidden_flag_file -rw-r--r-- 1 ftp ftp 36 Sep 01 2017 dummy 226 Directory send OK. ftp> get .hidden_flag_file local: .hidden_flag_file remote: .hidden_flag_file 200 PORT command successful. Consider using PASV. 150 Opening BINARY mode data connection for .hidden_flag_file (39 bytes). 226 Transfer complete. 39 bytes received in 0.00 secs (314.8 kB/s) $ cat .hidden_flag_file cpaw{f4p_sh0u1d_b3_us3d_in_3ncryp4i0n}
flag: cpaw{f4p_sh0u1d_b3_us3d_in_3ncryp4i0n}
レベル3
Q23.[Reversing]またやらかした!
エンコードされた文字列を1文字ずつ0x19とxorしている。
In [12]: c = 'zixnbo|kwxt88d' ...: a = map(lambda x: chr(ord(x)^0x19), c) ...: print(''.join(a)) cpaw{vernam!!}
flag: cpaw{vernam!!}
Q24.[Web]Baby's SQLi - Stage 2-
Stage 1で露出していたURLからスタート。
パスワードが不明なので、ユーザ名をporisuteru'--
としてパスワードの比較処理をコメントアウトしてしまえばよい。
flag: cpaw{p@ll0c_1n_j@1l3:)}
Q26.[PPC]Remainder theorem
sympyに中国人剰余定理をしてくれる関数があったので使った(よくわかってない)。
In [13]: from sympy.ntheory.modular import crt, solve_congruence ...: crt([1584891, 3438478], [32134, 193127]) Out[13]: (mpz(35430270439), 5449612835898)
flag: cpaw{35430270439}
Q29.[Crypto] Common World
eが小さく、m ^ e < nの時、暗号文cのe乗根をとれば復号できる(Low Public-Exponent Attack)。
plain RSAに対する攻撃手法を実装してみる - ももいろテクノロジー
In [4]: import gmpy ...: (e, N) = (11, 236934049743116267137999082243372631809789567482083918717832642810097363305512293474568071369055296264199854438630820352634325357252399203160052660683745421710174826323192475870497 ...: 31910541843564682049486498778728694181722465907349721276848061838715247787844960300818709714859953420605531880765790249385018069509164657587891653174207695111052900478342826045671331500781211263 ...: 24292962573135255062070874755393037370225871941084361327579792733915942991371762279249041261612340053215837208367332056390526155380543994526696374001050284285457518440362296574128444690349708075 ...: 62336527158965779903175305550570647732255961850364080642984562893392375273054434538280546913977098212083374336482279710348958536764229803743404325258229707314844255917497531735251105389366176228 ...: 741806064378293682890877558325834873371615135474627913981994123692172918524625407966731238257519603614744577) ...: c = 8026569097414028678544788252507676885180098650578316907708079767703580521524864046515944642619342226391242306739265171912028296893331471878068562946628474512130359449575972147131813412236671 ...: 5904 ...: m = gmpy.root(c, e)[0] ...: print(m) 424311244315114354
なお、ヒントで同じ平文を異なるeで暗号化したc'が与えられているが、 この場合、Common Modulus Attackを使うこともできる。
flag: cpaw{424311244315114354}