問題リンク

https://play.picoctf.org/practice/challenge/521

概要

ログインフォームが与えられ、「emailは特定したので 侵入してね」というもの

サイトURLとEmailとは別に、パスワードのリストも与えられます

本問は“Crack the Gate 1”という問題の続きという位置づけ

予備知識

X-Forwarded-For ヘッダー

リクエストヘッダーの一種です。 端的に言えば、元のクライアントのIPアドレスをウェブサーバーに 伝えるためのHTTPヘッダーフィールドです

以下サイトがわかりやすいです

パスワードリスト攻撃

何らかの手法で手に入れたIDとパスワードのリストを使って サービスに不正ログインを試みるという、攻撃手法の一種です

今回の問題では、ID固定でパスワードのリストが与えられており、 これを使って擬似的にパスワードリスト攻撃を仕掛けます

解き方

パスワードリストをとりあえず試すと、2回目の試行でToo many failed attempt. Please try again in 20 minutes.となってしまいブロックされます

前の問題(Crack the Gate 1)のバックドアである X-Dev-Acess: yesを設定してもダメです

「システムはユーザーがコントロールするHeaderを信頼するかも」 というヒントが問題文で与えられていて、どうやらX-Forwarded-Forの値(IPアドレス)を書き換えながら 攻撃を仕掛ければこちらのIPアドレスを偽装することができるらしいです

やり方としては、burpsuiteのIntruderタブからPitchfork attackを選び、

  • リクエストヘッダーのX-Forwarded-Forを書き換え続ける
  • リクエストボディのpasswordフィールドでパスワードリストの全パターンを試す

ということをすればOKです

実際に攻撃を仕掛けると、以下のようなResultが得られます

RequestPayload1Payload2Status codeResponse receiveErrorTimeoutLengthComment
1100l9xKfsH0200250falsefalse252
2101rCRnekkE200202falsefalse368
3102wqMh5SQT200196falsefalse252
41039JL7BM3W200194falsefalse252
5104OtrkErZU200209falsefalse252
6105xr5N5yun200203falsefalse252
7106FAfQ34Dr200261falsefalse252
8107xAzOtoGy200205falsefalse252
9108NT4Vm1FC200191falsefalse252
10109aRhrp17j200204falsefalse252
111105vcxz5xZ200184falsefalse252
12111SooyOtMf200232falsefalse252
13112qpTlHqaG200207falsefalse252
141130AwkENeB200160falsefalse252
15114tfkwkm3g200189falsefalse252
16115UToyxdBs200204falsefalse252
17116NWj5rDBm200204falsefalse252
18117LiVR9e3g200306falsefalse252
191183v6avTIP200197falsefalse252
20119jcEoe8hx200204falsefalse252

上記は攻撃1回ごとに対応するレスポンスの統計値を表しているのですが、 Length(つまりレスポンスの長さ)に注目すると一つだけ長さが368のものが見つかります

このレスポンスメッセージを見ると

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 132
ETag: W/"84-YU0prW3G343RIgpFiAp27XVBezo"
Date: Thu, 20 Nov 2025 09:50:30 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"success":true,
"email":"ctf-player@picoctf.org",
"firstName":"pico",
"lastName":"player",
"flag":"picoCTF{xff_byp4ss_brut3_1c447e47}"}

といった形でフラグが得られたのでクリアです

補足: 現実のサービスではこの攻撃は通用するの?

結論として、X-Forwarded-Forを書き換えてIPを偽装する攻撃は現代的な開発&デプロイを されているサイトには通用しません (以下、X-Forwarded-ForをXFFと略します)

理由は以下の通りです

  • ブラウザは基本的にXFFを送らず、“XFFがクライアントから送られてきたらなら絶対に信用しない"がデファクトスタンダードである
  • CloudflareやAWS ALBのようなサービスはクライアントが勝手に設定したXFFを破棄したり上書きする
  • Epress, DjangoやRailsも特殊な引数設定をしない限りXFFを信用しません

よって、現代的なフレームワークを使った開発をしていて、ちゃんとしたデプロイが行われているサービスには 基本的にXFFを書き換えてIPを偽装することはできません

注意として、

  • Expressでは、app.set('trust proxy', true);を設定するとXFFを信用してしまうらしい
  • その他のフレームワークでも設定次第ではXFFを信用してしまう(かもしれない)

らしいので、バックエンド開発をする時はフレームワークによっては気をつけましょう。 特にVibe Coding時、気づかないうちに設定されていたりしたら地獄を見ます


参考文献