Shikata Ga Nai

Private? There is no such things.

SSRFのブラックリスト型フィルタを回避する方法

Hello there, ('ω')ノ

一部のアプリケーションでは、SSRFを防ぐためにブラックリストベースの入力フィルタ を実装しています。
例えば、以下のような 特定のホストやパスをブロック することがあります。

ブロックされる可能性のある値:
- 127.0.0.1localhost などのローカルホスト
- 169.254.169.254(AWSメタデータサービス)
- /admin/internal などの管理ページ

しかし、ブラックリスト方式のフィルタは回避が可能 であり、以下の方法を使用すれば SSRF攻撃を実行できる可能性があります。


1. 127.0.0.1 の異なる表現を使用する

アプリケーションが 127.0.0.1 をブロックしていても、IPアドレスの表記方法を変える ことで回避できることがあります。

IP表記の種類
通常のIP 127.0.0.1
ループバックの短縮形 127.1
10進数表記 2130706433 (127.0.0.1 を10進数に変換)
16進数表記 0x7F000001
8進数表記 017700000001

💡 これらの表記を試すと、フィルタを回避できる場合があります。


2. 127.0.0.1 に解決されるドメインを利用する

アプリケーションが 127.0.0.1localhost を明示的にブロックしている場合、別のホスト名を登録し、それが127.0.0.1に解決するようにする ことで回避できます。

手順

  1. 攻撃者がコントロールするドメインを取得
    • 例: evil.com
  2. DNSレコードを127.0.0.1に設定
    • evil.com -> 127.0.0.1
  3. SSRFリクエストを送信 http stockApi=http://evil.com/admin

アプリケーションは evil.com を許可していても、実際には 127.0.0.1 にリクエストを送ることになる。

💡 spoofed.burpcollaborator.net などの Burp Collaborator を利用すると、簡単にこの攻撃を実行できる!


3. URLエンコーディングや大文字小文字の変更

一部のフィルタは、特定の文字列を完全一致でチェック していることがあるため、以下の方法で回避できる場合があります。

① URLエンコーディング

オリジナル エンコード後
http://127.0.0.1/admin http://127.0.0.1/%61%64%6D%69%6E (/admin をエンコード)

💡 フィルタが「/admin を含むURLをブロックする」場合でも、エンコードするとバイパスできる可能性がある。

② 大文字小文字の変更

一部のフィルタは 「localhost」や「admin」などの固定文字列のみチェック している場合があります。

http://LOCALHOST/admin
http://127.0.0.1/AdMiN

💡 文字の大文字小文字を変更するだけで、フィルタを回避できることがある。


4. リダイレクトを利用する

SSRFのブラックリストフィルタが 特定のドメインやパスのみをチェックしている場合リダイレクトを利用する ことでフィルタを回避できます。

手順

  1. 攻撃者がリダイレクト用のURLを用意
    • 例: http://evil.com/redirect?url=http://127.0.0.1/admin
  2. リダイレクトを使ったSSRF攻撃 http stockApi=http://evil.com/redirect
  3. サーバーはリダイレクトを処理し、結果的に http://127.0.0.1/admin にリクエストを送る

「evil.comは許可されている」ため、フィルタを回避できる!

💡 リダイレクトの際に http → https に切り替えると、一部のフィルタを回避できる場合がある!


5. HTTPヘッダーの改ざん

一部のフィルタは、URLのみをチェックし、リクエストヘッダーを厳密に検証しない 場合があります。
この場合、Host ヘッダーを改ざんするとSSRFを実行できる可能性があります。

POST /product/stock HTTP/1.1
Host: 192.168.0.68
Content-Type: application/x-www-form-urlencoded
Content-Length: 118

stockApi=http://trusted.com
X-Forwarded-Host: 127.0.0.1

trusted.com のリクエスト」として処理されるが、実際には 127.0.0.1 にアクセス!

💡 一部のプロキシやロードバランサーが X-Forwarded-Host を適用するため、これを悪用すると内部サーバーにアクセスできる!


6. ブラックリストではなくホワイトリストを使用する

ブラックリスト方式の問題点: - 回避しやすい(上記のテクニックで突破可能) - 新しい攻撃手法が追加されると、その都度更新が必要

安全な対策として、ブラックリストではなく「ホワイトリスト方式」を使うべき!許可するドメインを厳密に定義し、それ以外のリクエストを拒否する!

ALLOWED_DOMAINS = ["api.weliketoshop.net"]

def is_valid_url(url):
    return any(domain in url for domain in ALLOWED_DOMAINS)

この方法なら、攻撃者が意図しないリクエストを送ることが難しくなる!


7. まとめ

ブラックリスト対策 回避方法
127.0.0.1localhost をブロック IPの異なる表現(2130706433, 0x7F000001)
特定のドメインのみ許可 127.0.0.1 に解決するドメインを使用
/admin などのパスをブロック URLエンコード(%61%64%6D%69%6E)
HTTP/HTTPSのみ許可 gopher://file:// を利用
リダイレクト禁止 自作のリダイレクトページを利用
ヘッダー改ざん防止 X-Forwarded-Host を悪用

🚨 ブラックリスト方式のフィルタは簡単にバイパス可能!
🚀 ホワイトリスト方式のフィルタを使用し、厳格なアクセス制御を実装しよう!

Best regards, (^^ゞ