こんにちは、今回は Webアプリケーションにおける深刻な脆弱性「SSRF(Server-Side Request Forgery)」について、基本から応用的な攻撃手法、PoC、対策までChatGPTに幅広くまとめてもらって「この一連の流れを技術ブログとしてqiitaに投稿したいので原稿書いて」として原稿も書かせてみました。
💡 SSRFとは?
SSRF(Server-Side Request Forgery) は、攻撃者がサーバーに対して意図しないリクエストを送信させる脆弱性です。
🔁 通常の通信フロー
[ユーザー] → [Webサーバー] → [外部リソース]
🔥 SSRFがあると…
[攻撃者] → [Webサーバー]
↓
内部API / ローカルファイル / クラウドメタデータ などにアクセス
🎯 SSRFでできる攻撃一覧
① 内部サービススキャン
http://target.com/fetch?url=http://127.0.0.1:8000
http://target.com/fetch?url=http://10.0.0.5:8080
② AWSなどのクラウドメタデータアクセス
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-instance
🛡️ モダンなクラウド環境におけるSSRF対策(IMDSv2など)
最近のクラウドサービスでは、SSRFによる メタデータ情報の窃取 への対策が導入されています。以下に主要クラウドの現状をまとめます。
🔒 AWS: IMDSv2 の導入
従来(IMDSv1)の仕様:
-
http://169.254.169.254/latest/meta-data/
にそのままGETアクセスで情報取得可能 - SSRFで簡単にIAMロールのクレデンシャルを盗めた
現在(IMDSv2):
- 一時的なTokenの取得 → Token付きでメタデータ取得
- Tokenがないリクエストは拒否される
-
PUT
メソッドで Token を取得し、X-aws-ec2-metadata-token
ヘッダーが必須
例:
# トークン取得
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# メタデータ取得(トークン必須)
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/
対策まとめ:
対策項目 | 内容 |
---|---|
IMDSv2を強制 | インスタンスメタデータサービスのバージョン制限 |
メタデータサービスの無効化 | 必要ない場合は完全にオフにできる |
IAMロールの最小権限化 | stolen credential でも最小被害に留める |
☁️ GCP: Metadata-Flavor: Google ヘッダーによる制御
メタデータエンドポイント:
http://metadata.google.internal/computeMetadata/v1/
対策:
GCPでは Metadata-Flavor: Google
ヘッダーが 必須。
curl "http://metadata.google.internal/computeMetadata/v1/instance/id" \
-H "Metadata-Flavor: Google"
対策ポイント:
対策 | 内容 |
---|---|
強制ヘッダー | SSRFでこのヘッダーを付けるのは難しい |
ロール権限制御 | 最小権限のサービスアカウントが推奨 |
☁️ Azure: Metadata=true クエリパラメータの使用
エンドポイント:
http://169.254.169.254/metadata/instance?api-version=2021-02-01
ヘッダー:
Metadata: true
対策:
Azureでは、上記ヘッダーが ないとエラーになります。
curl "http://169.254.169.254/metadata/instance?api-version=2021-02-01" \
-H "Metadata: true"
🔍 攻撃者から見た今のクラウド状況
クラウド | 旧脆弱性 | 現在の保護 | SSRFでの難易度 |
---|---|---|---|
AWS | GETでクレデンシャル取得可(IMDSv1) | IMDSv2トークン必須 | 難しい(gopher://でPUTは難しい) |
GCP | ヘッダー強制(Metadata-Flavor) | SSRFで付与不可 | 難しい |
Azure | Metadata: true 必須 | SSRFでヘッダー付与困難 | 難しい |
③ ファイル読み取り(file://スキーム)
file:///etc/passwd
file:///proc/self/cwd/index.php
file:///proc/self/environ
④ /proc/
を使ったテクニック
パス | 内容 |
---|---|
/proc/self/cwd/index.php |
現在のPHPスクリプトのソースコード取得 |
/proc/self/environ |
環境変数(User-AgentなどからWebShell注入) |
/proc/self/status |
実行中のUIDやメモリなど |
/proc/net/fib_trie |
内部ネットワーク情報 |
/proc/self/fd/0 |
オープン中ファイルの参照 |
📡 応用テクニック
✅ DNSリバウンド攻撃(DNS Rebinding)
http://evil.com → 127.0.0.1 に名前解決を切り替え
→ 外部に見せかけて、内部にアクセスさせる
✅ gopher:// スキームを使った任意コマンド注入
例:Redisに直接コマンドを送信
gopher://127.0.0.1:6379/_FLUSHALL
✅ SSRF → RCE(最終的なリモートコード実行)
内部で動いている管理画面・Webhookなどにアクセスできる場合:
- Jenkins
- GitLabのWebhook
- 内部APIがCSRF対策なし
- SSRF経由でコード注入できるサービス(Redis、MongoDBなど)
🧪 実際のPoC例(PHP)
<?php
if (isset($_GET['url'])) {
$url = $_GET['url'];
$data = file_get_contents($url); // ← SSRFの元凶
echo htmlspecialchars($data);
}
?>
攻撃例:
http://target.com/vuln.php?url=file:///proc/self/cwd/index.php
http://target.com/vuln.php?url=http://169.254.169.254/latest/meta-data/
🔐 対策まとめ
対策 | 内容 |
---|---|
スキーム制限 |
http , https 以外を禁止(file://, gopher://, ftp://などブロック)
|
ホスト/IPフィルタ |
localhost , 127.0.0.1 , 169.254.x.x , 10.x.x.x などへのアクセスを拒否 |
ホワイトリスト | 許可された外部ドメインのみ通信可能にする |
open_basedir |
file:// を使ったファイル読み取りを制限 |
IMDSv2の利用(AWS) | EC2メタデータへの安全なアクセスを強制(token化) |
URL検証 |
parse_url() + filter_var() でスキーム・ホストチェック |
📝 まとめ
- SSRFは単なる情報取得にとどまらず、クラウド乗っ取り・コード実行・横展開の起点になり得る
- 以前は「SSRF=クラウド乗っ取り」になりがちだったが、IMDSv2・強制ヘッダー化などによりハードルが大きく上がった
- ただし、古いクラウド設定や内部HTTPプロキシ経由でのバイパスなどはまだ存在する
- 特に
file:///proc/
を活用した手法 や DNSリバウンド、gopher:// は応用範囲が広く、WAFやネットワーク制御をバイパスできることもある - 想定外の通信を許さないように、スキーム、IP、ドメインを厳格に制限するのが重要
- 防御側は「SSRFそのものを発生させない」設計が最重要
🔗 参考資料
🧠 ご意見歓迎!
「ここが分かりづらい」「この攻撃例も紹介してほしい」などあれば、ぜひコメントで教えてください!
記事が参考になったら LGTM いただけると励みになります 💚