2022-06-04 14:00 – 2022-06-05 14:00 (JST)に開催されたSECCON Beginners CTF 2022のWriteupです。
前回に引き続き友人であるmaa氏との2人チームで出場し、1067pt獲得して全1121チーム中67位でした。
Writeup
Welcome (welcome)
開始直後にDiscordでアナウンスされるフラグのコピペRTA。
ctf4b{W3LC0M3_70_53CC0N_B361NN3R5_C7F_2022}
Quiz (reversing)
stringsしたら出てきた
$ strings quiz | grep ctf4b
ctf4b{w0w_d1d_y0u_ca7ch_7h3_fl4g_1n_0n3_sh07?}
CoughingFox (crypto)
# problem.py
from random import shuffle
flag = b"ctf4b{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}"
cipher = []
for i in range(len(flag)):
f = flag[i]
c = (f + i)**2 + i
cipher.append(c)
shuffle(cipher)
print("cipher =", cipher)
リスト型に格納されたフラグの各要素について、( f[i] + i )^2 + i という計算が行われシャッフルされたものが出力されるので、そのまま逆の処理を書いてflagを復元しました。
# solver.py
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]
for i in range(len(cipher)):
for c in cipher:
s = math.sqrt(c-i)-i
if s%1==0:
print (int(s).to_bytes(2, byteorder = "big").decode(), end="")
ctf4b{Hey,Fox?YouCanNotTearThatHouseDown,CanYou?}
phisher (misc)
ホモグラフ攻撃をOCRで再現している問題。
送信した文字列が指定のフォントで画像に変換され、その画像をOCRした結果が www.example.com と一致しかつ www.example.com に含まれる文字が使われていなければflagが手に入る。
Homoglyph Attack Generatorなるものがあったのでこれを使ってメンバーと協力しながら1文字ずつ通る文字を探していった。
ctf4b{n16h7_ph15h1n6_15_600d}
H2 (misc)
main.goのソースコードと大量のパケットが記録されたpcapデータが渡される。
// main.go
package main
import (
"net/http"
"log"
"fmt"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
const SECRET_PATH = "<secret>"
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == SECRET_PATH {
w.Header().Set("x-flag", "<secret>")
}
w.WriteHeader(200)
fmt.Fprintf(w, "Can you find the flag?\n")
})
h2s := &http2.Server{}
h1s := &http.Server{
Addr: ":8080",
Handler: h2c.NewHandler(handler, h2s),
}
log.Fatal(h1s.ListenAndServe())
}
パスが正しいときだけx-flagというヘッダーが渡されるようなので、pcapデータをWireSharkで開き下記フィルタで絞ると当該通信が見つかった。
http2.header.name == x-flag
ctf4b{http2_uses_HPACK_and_huffm4n_c0ding}
textex (web)
TeXを書くとPDFに変換して出力してくれるサービス。“flag”という文字が含まれていると弾かれてしまうので以下のように分割しマクロで置換することで回避し、/input でflagファイルの中身を出力する。
\documentclass{article}
\begin{document}
\def\fl{../../fl}
\def\ag{ag}
\input{\fl\ag}
\end{document}
これでローカル(配布Docker)上では動作したのだが、同じコードをサーバー側に投げるとエラーで弾かれてしまい困っていた。(他の参加者が同様の内容でDiscord上で質問しているのも複数回見かけた。)
flagの形式が ctf4b{XXX} であるため、\input で flag を埋め込んだ際に {} が特殊文字として認識されてしまっているということに途中で気づき、{} を置換する方法を探していたが、結局数式モードで出力し、消えた {} を復元・下付き文字を_に変換などの微調整を行うことで強引に解決
ctf4b{15_73x_pr0n0unc3d_ch0u?}
追記:
終了後に公開された 作問者writeup によると、\verbatiminput等を使うのが想定解らしい。