SSRF on HostHeader Poisoning を確認するツールを作った

---
### はじめに
ホストヘッダを改ざんしてSSRFできるかどうかのリストが多くなってきたのでWindows Script Hostで自動化してみた。

---
### ホストヘッダを改ざんしたSSRF

:::note info
診断対象のWebサイトの手前に(ステルスを含む)WAF/LBなどのリバースプロキシがいて、そいつが任意のサーバへ転送可能である。
:::

という状態。

1. 診断対象にTCP/SSL接続して・・・
1. Hostヘッダを診断対象ではないホスト名にしたHTTPリクエストを送ると・・・
1. 診断対象とは異なる別のWebサイトへhttpリクエストメッセージが飛んでいく・・・

というような状態かどうかを調べるツール

図だとこんな感じ

![想定しているネットワーク図](http://rocketeer.dip.jp/sanaki/free/free167a.png)

あまりない状態だけど、クラウドの普及に伴い気軽にLB/WAFを通信経路上に配置できるので、昔よりは少し多いような気がしないでもないような気がする。

インターネット側のホスト名(FQDN)が指定できれば、**匿名プロキシ**だし、内部ネットワークのホスト名が指定できると、クラウド環境とかだと少し危険なSSRFという事になる。

---
### ssrfHostPoisonCheck.vbsの設計

1. 「【ホスト名】【/で始まるパス】」という行を入力してもらい
1. 【ホスト名】をHostヘッダに、【/で始まるパス】をリクエストラインにしたテキストファイルを一時ファイルとして生成する(「Connection: close」ヘッダも追加して1往復後に閉じるようにする)
1. そのテキストファイルを通信プログラム([StreamRelay.NET.exe](http://rocketeer.dip.jp/sanaki/free/free119.htm))に食わせる
1. サーバからの返答(HTTPレスポンスライン)を出力する
1. 次の行に移る

という繰り返し処理

おまけ機能として、SSL2/SSL3/TLS1.0/TLS1.1/TLS1.2で接続できるかどうか、TRACE/TRACK/OPTIONS/NONAMEメソッドでの反応を調べる繰り返し処理も埋め込んでみたけど、これはおまけ機能

---
### 使い方

1. nc.exeとかsslcatとかでも使えるとは思うけど、通信プログラムに[StreamRelay.NET.exe](http://rocketeer.dip.jp/sanaki/free/free119.htm)を前提としているので、[StreamRelay.NET.exe](http://rocketeer.dip.jp/sanaki/free/free119.htm)をダウンロードして、インストールする(解凍する)
1. [StreamRelay.NET.exe](http://rocketeer.dip.jp/sanaki/free/free119.htm)には、.NET FRamework4以上が必要です
1. [ssrfHostPoisonCheck.vbs](rocketeer.dip.jp/sanaki/free/free167.htm)をダウンロードしてインストールする(解凍する)
1. [ssrfHostPoisonCheck.vbs](rocketeer.dip.jp/sanaki/free/free167.htm)をテキストエディタで開き、[StreamRelay.NET.exe](http://rocketeer.dip.jp/sanaki/free/free119.htm)のパスに89行目(ver1.2の場合)を書き換える
1. コマンドラインから以下のコマンドで実行できます。

```shell-session:
c:\> cscript.exe ssrfHostPoisonCheck.vbs
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.

usage: cscript.exe ssrfHostPoisonCheck.vbs <<ListFile>> <<TargetHost/IP>> <<TargetPort>> <<Options>>
       Options
            -ssl : Enable SSL/TLS
            -VirtualHostName <<HostName>> : Set VirtualHostName
            -RoleName <<RoleName>> : Set Role-Name
            -DefaultPath <<Path>> : Set Default URL Path
            -SSLProtocolCheck : SSL/TLS Protocol Check
            -HttpMethodCheck : HTTP Method Check

                   ver1.2
                   create by active@window.goukaku.com
```

---
### SSRFのリストファイルの元ネタとなるURLの一覧とか

- [emadshanab/google SSRF](https://gist.github.com/emadshanab/245cfbd58747847a6b78a7390194bef9)
- [A New Era of SSRF - Exploiting URL Parser in Trending Programming Languages!](https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf)
- [SSRF脆弱性を利用したGCE/GKEインスタンスへの攻撃例](https://blog.ssrf.in/post/example-of-attack-on-gce-and-gke-instance-using-ssrf-vulnerability/)
- [There's more than one way to write an IP address](https://ma.ttias.be/theres-more-than-one-way-to-write-an-ip-address/)
- [Abusing HTTP hop-by-hop request headers](https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers)
- [jhaddix/cloud_metadata.txt](https://gist.github.com/jhaddix/78cece26c91c6263653f31ba453e273b)
- [mrtc0/cloud-service-metadata-api-list.md](https://gist.github.com/mrtc0/60ca6ba0fdfb4be0ba499c65932ab42e)
- [SSRF(Server Side Request Forgery)徹底入門](https://blog.tokumaru.org/2018/12/introduction-to-ssrf-server-side-request-forgery.html)
- [SSRF対策としてAmazonから発表されたIMDSv2の効果と限界](https://blog.tokumaru.org/2019/12/defense-ssrf-amazon-ec2-imdsv2.html)
- [サイボウズ脆弱性報奨金制度で認定されたSSRF](https://akaki.io/2018/ssrf_in_cybozu)
- [SSRFを利用したメール送信ドメインの乗っ取り](https://akaki.io/2018/smtp_domain_takeover)
- [「CODE BLUE 2018」参加レポート（岩間編）](https://techblog.securesky-tech.com/entry/2018/11/05/121307)

---
### SSRFのリストファイルの書式

<UL>
 <LI>空行は無視
 <LI>行頭が「#」はコメントとみなす
 <LI>行単位で、「【ホスト名】【/で始まるパス】」という書式
 <LI>行単位で、「【/で始まるパス】」という書式の場合は、ホストヘッダには既定値が入る
 <LI>ホストヘッダの既定値とは、スクリプトの引数で指定する(-VirtualHostNameオプション)、または接続先ホスト名に指定した値(&lt;&lt;TargetHost/IP&gt;&gt; オプション)のこと
 <LI>「\${DEFAULT_PATH}」と「\${ROLE_NAME}」のマクロがある(これらはスクリプトの引数で設定できる)
 <LI>「\${DEFAULT_PATH}」の既定値は空文字列
 <LI>「\${ROLE_NAME}」の既定値は「DefaultRole」
</UL>

---
### 例えば・・・

SSRFのリストファイルのサンプル

<table border="1">
<tr><th>list.lst</th></tr>
<tr><td>
169.254.169.254/latest/user-data<br>
169.254.169.254/latest/meta-data/<br>
169.254.169.254:80/latest/user-data<br>
169.254.169.254:80/latest/meta-data/<br>
www.ntt.com/<br>
127.0.0.1/${DEFAULT_PATH}<br>
/-_-http://www.example.com/
</td></tr>
</table>

```shell-session:
c:\> cscript.exe ssrfHostPoisonCheck.vbs list.lst 192.0.2.1 443 -ssl -VirtualHostName www.example.com -DefaultPath webapp/login
```

---
### 一般的には・・・

- <b>「-DefaultPath」</b>には診断対象の起点となるURLのパスでよいと思う
- <b>「&lt;&lt;TargetHost/IP&gt;&gt;」</b>にはDNSで名前解決したIPアドレスを入れて・・・
- <b>「-VirtualHostName」</b>に、診断対象のホスト名を指定する
- 大抵はSSL/TLSなので<b>「-ssl」</b>オプションは必須

・・・かな・・・

---
### おまけ

- <b>「-SSLProtocolCheck」</b>は、「&lt;&lt;TargetHost/IP&gt;&gt;」に対してSSL2/SSL3/TLS1.0/TLS1.1/TLS1.2で接続できるかどうか試します
- <b>「-HttpMethodCheck」</b>は、「TRACE/TRACK/NONAME/OPTIONS」メソッドを試してみます

---
### デバグモード

ver1.2の場合は、[ssrfHostPoisonCheck.vbs](rocketeer.dip.jp/sanaki/free/free167.htm)の72行の「IsDebug」の値を「1」にすると、デバグモードになって、テンポラリフォルダに、送信したHTTPリクエストメッセージと、受信したHTTPレスポンスメッセージを保持したデバグファイルが生成されます。

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)