![見出し画像](https://assets.st-note.com/production/uploads/images/139689895/rectangle_large_type_2_36d4ed36edba243a8730be701547de1f.jpeg?width=1200)
#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になっています。
![](https://assets.st-note.com/img/1714966916369-sGJlj2LUsA.png?width=1200)
/forum/admin.phpにアクセスすると、フラグが取得できました。
welcome to the admin zone
The flag is: flag{XXXXXXXXXXXXXXXXXXX}
まとめ
DEFCONのCTFは、今回はじめて真剣に取り組みましたが、1問解けて満足しています。難しい問題もどんどんチャレンジしていけるように、さらに自己研鑽していきたいと思います。
Reversingをもっと磨いて、来年もっと解けるようにがんばります!
P.S.
公開されたソースコードを見てみたら、Elixirで書かれていました。なぜPHPのフリをしたのか、よくわかりません。暗黙の型変換は、SQLで起こっているようでした。
EOF