Fetch the Flag CTF 2022 解説:Juggalo Central
Alexander Kraev
2022年11月10日
0 分で読めますFetchに参加してくれてありがとう! 一緒に参加してくれた何千人ものプレイヤーの皆さん、Fetch the Flag CTFへのご参加ありがとうございました。また、チャレンジの作成、テスト、解説記事の執筆に携わったSnykerの皆さんにも心から感謝します!
Snykの2022年Fetch the Flagに参加したものの、Juggalo Centralのチャレンジをクリアできなかった方は、ぜひこの先をお読みください。解法を一緒に見ていきましょう!
解説
まず、一般的なログインフォームがあるWebサイトへのリンクがあり、usernameとpasswordの2つの入力欄があります。また、.php拡張子のファイルもあります。まずはWebサイトを見てみましょう。
Webサイト
前述のとおり、ページには2つの入力欄とピエロの画像があります。最初にページのソース、.cssファイル、さらには画像も確認しましたが、役立ちそうなものは見つかりませんでした。気づいたのは、エラーメッセージが2種類あることです。「admin」のような一般的なユーザー名を使った場合と、「qweasdzxc」のような適当な文字列を使った場合で異なっていました。
コード
index.phpの中には、getFlag、searchUserByName、validateCredentailsという3つの関数がありました。
最初の関数getFlagは、flagというデータベーステーブルを呼び出し、最初に見つかった行を返します。少し考えた結果、探しているキーはこのテーブルに保存されているとわかりました。
2つ目の関数searchUserByNameは、$usernameという入力変数をもとにユーザーを検索します。結果があれば、その結果を返します。ここで気づいたのは、次の行です。
つまり、この関数は1行だけを返すとは限りません(ユーザー名は一意だと思っていたのですが)。同じユーザー名のユーザーが複数いる場合は、すべて返します。後になって、次の関数の処理のため、これは役に立たないとわかりました。CTFでは、こういうこともあります。
3つ目の関数validateCredentailsは、POSTリクエストの本文からユーザー名とパスワードを読み取り、searchUserByNameを呼び出して、そのユーザー名のユーザーがいるかを確認します。ランダムな文字列のユーザー名でエラーメッセージが異なる理由もわかりました。存在しないユーザー名を入力すると、関数は「Juggalo not found!」を返します。一方、存在するユーザー名でパスワードを間違えると、「Invalid credalo」というエラーメッセージが表示されます。
有効なユーザー名を見つける
次に、有効な認証情報を探します。「admin」のようなよくある値を試したところ、「Invalid credalo」というエラーメッセージが表示されました。前のステップでコードを分析したことで、ユーザー名の値が「admin」のユーザーがいるとわかります。
最初の推測
有効なユーザー名がわかったので、次はパスワードを突破する方法を考えます。このユーザーにアクセスできないというエラーメッセージが表示されるのは、次のコード行が原因です。
条件式の左辺では、データベースからユーザーのパスワードを取得しています。右辺には、ユーザーが指定した2つの変数usernameとpasswordを含むmd5ハッシュの先頭20文字があります。
最初に思いついたのは、この条件から、有効なパスワードは20文字の文字列だということでした。結論から言うと、これは間違いでした。
2つ目の推測
しばらくチャレンジについて考えた後、別の考えが浮かびました。この行では!=比較演算子を使っています。そこでPHPの公式ドキュメントを開き、PHPでの比較演算子の動作を確認しました。ドキュメントの!=演算子のすぐ隣にある一文の意味がわかりませんでした。
待って、「型のジャグリング」って何だろう?説明を読んでから、もう一度チャレンジのWebページを開きました。あのピエロはまだそこにいて、こちらを見つめていました。
ハッキング
PHPには「型のジャグリング」という仕組みがあることがわかりました。このトピックについて調べ、オンラインでPHPのテストをいくつか実行した結果、次の条件を思いつきました。
驚いたことに、これは「true」を返しました。PHPが両方のオペランドを数値に変換するためです。「admin」ユーザーの正しいパスワードを見つけるには、「0e」で始まり、その後が数字だけのmd5ハッシュを生成すればよいのです(substrの使用箇所を考えると、その後に少なくとも18文字が必要です)。
スクリプト
正しいハッシュを見つけるPythonスクリプトをご紹介します。
1分ほどで、このスクリプトから得た認証情報を使ってJuggalo CentralのWebページにログインできました。
Fetch the Flagのその他の解法
ほかのフラグをどう見つけたか知りたいですか?Fetch the Flagの解法ページで、詳しい手順をご覧ください。



