見出し画像

#128 [defcon quals 2024] Gilroy

 2024-05-04 09:00 〜 2024-05-06 09:00でDEFCON CTFの予選が開催されました。いつものように、個人での参戦です。

 1問クリアを目標に取り組んで、なんとか得意なWeb問が解けました。解答者数も多い簡単な問題でしたが、記念にWriteupを残したいと思います。

Gilroy

PHP製のフォーラムサイトです。フロントはPhoenixというJSのフレームワークが使われている(?)ようで、バックエンドは純PHPのようです。

サイトの機能をざっと見てみると、

  • 会員登録

  • 会員詳細

  • ログイン

  • ログアウト

  • スレッド登録

  • スレッド詳細

  • コメント登録

とシンプルな作りになっています。

会員には、normal、banned、adminの3種類のgroupがあって、とりあえずadminを目指せばいいかなと考えて調査しました。

会員のgroup指定

 普通に会員登録すると、normal会員として登録されます。しかし、groupというパラメータを指定すると、入力した値で登録できることがわかりました。

0 => banned
1 => normal
2 => admin

素直に"2"を指定すると、「すでにadminが存在します」というエラーではじかれます。ここをなんとか突破できれば、adminになれそうです。

Type Juggling

いろいろ試してみると、groupの入力値はintとstringが混同して扱われているようでした。

$group = $_POST["group"];

if ($group == "2") {
  // admin exists error
}

$user = new User;
if (!$group) {
  $user->group = 1; // normal
} else {
  $user->group = (int) $group;
}

プログラムはこんな感じかなと推測できます。とすれば、入力値を工夫してバリデーションを回避できそうです。

PHPは型がゆるい言語で、型変換の際に多少の差を吸収してくれます。例えば、

"1" => 1
"1test" => 1
"001" => 1

型を意識しなくともうまいことやってくれるので、便利ではありますが、この仕様はバグのもとにもなります。詳しくは、Type Jugglingを参照ください。

さて、Type Jugglingを悪用して攻略しましょう。
groupに"02"を指定してみます。

_csrf_token=EjxIRUMtO00bVEQdHn87c0pYDnxGZmsoJZp6wkS4Ulpgi0j131aKk61b
&name=admin
&password=password
&password_confirmation=password
&group=02

すると、エラーにならず登録できました。
会員詳細ページを確認すると、ちゃんとadminになっています。

/forum/admin.phpにアクセスすると、フラグが取得できました。

welcome to the admin zone
The flag is: flag{XXXXXXXXXXXXXXXXXXX}


まとめ

 DEFCONのCTFは、今回はじめて真剣に取り組みましたが、1問解けて満足しています。難しい問題もどんどんチャレンジしていけるように、さらに自己研鑽していきたいと思います。

 Reversingをもっと磨いて、来年もっと解けるようにがんばります!

P.S.
公開されたソースコードを見てみたら、Elixirで書かれていました。なぜPHPのフリをしたのか、よくわかりません。暗黙の型変換は、SQLで起こっているようでした。

EOF

この記事が気に入ったらサポートをしてみませんか?