Nginx
Reading time: 20 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
Missing root location
Nginxサーバーを構成する際、rootディレクティブはファイルが提供される基本ディレクトリを定義する重要な役割を果たします。以下の例を考えてみてください:
server {
root /etc/nginx;
location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}
この構成では、/etc/nginx
がルートディレクトリとして指定されています。この設定により、指定されたルートディレクトリ内のファイル、例えば /hello.txt
へのアクセスが可能になります。しかし、特定の場所(/hello.txt
)のみが定義されていることに注意することが重要です。ルートロケーション(location / {...}
)の設定はありません。この省略により、ルートディレクティブはグローバルに適用され、ルートパス /
へのリクエストが /etc/nginx
の下のファイルにアクセスできるようになります。
この構成から生じる重要なセキュリティ上の考慮事項があります。単純な GET
リクエスト、例えば GET /nginx.conf
は、/etc/nginx/nginx.conf
にある Nginx 設定ファイルを提供することで、機密情報を露出させる可能性があります。ルートを /etc
のようなあまり機密性の高くないディレクトリに設定することで、このリスクを軽減できますが、それでも他の重要なファイル、他の設定ファイル、アクセスログ、さらには HTTP ベーシック認証に使用される暗号化された資格情報への意図しないアクセスを許可する可能性があります。
Alias LFI Misconfiguration
Nginx の設定ファイルでは、「location」ディレクティブを注意深く検査する必要があります。Local File Inclusion (LFI) として知られる脆弱性は、以下のような構成を通じて意図せず導入される可能性があります。
location /imgs {
alias /path/images/;
}
この設定は、サーバーが /imgs../flag.txt
のようなリクエストを意図したディレクトリの外にあるファイルにアクセスしようとする試みとして解釈するため、LFI攻撃に対して脆弱です。これは実際には /path/images/../flag.txt
に解決されます。この欠陥により、攻撃者はウェブ経由でアクセスできるべきではないサーバーのファイルシステムからファイルを取得することができます。
この脆弱性を軽減するために、設定を次のように調整する必要があります:
location /imgs/ {
alias /path/images/;
}
More info: https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/
Accunetix テスト:
alias../ => HTTP status code 403
alias.../ => HTTP status code 404
alias../../ => HTTP status code 403
alias../../../../../../../../../../../ => HTTP status code 400
alias../ => HTTP status code 403
Unsafe path restriction
次のページを確認して、次のようなディレクティブをバイパスする方法を学んでください:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
Proxy / WAF Protections Bypass
Unsafe variable use / HTTP Request Splitting
caution
脆弱な変数 $uri
と $document_uri
があり、これを $request_uri
に置き換えることで修正できます。
正規表現も脆弱である可能性があります:
location ~ /docs/([^/])? { … $1 … }
- 脆弱
location ~ /docs/([^/\s])? { … $1 … }
- 脆弱でない(スペースをチェック)
location ~ /docs/(.*)? { … $1 … }
- 脆弱でない
Nginx 設定の脆弱性は、以下の例で示されています:
location / {
return 302 https://example.com$uri;
}
HTTPリクエストにおいて、文字 \r (キャリッジリターン) と \n (ラインフィード) は新しい行の文字を示し、そのURLエンコード形式は %0d%0a
で表されます。これらの文字をリクエストに含めると(例: http://localhost/%0d%0aDetectify:%20clrf
)、誤って設定されたサーバーは Detectify
という新しいヘッダーを発行します。これは、$uri 変数がURLエンコードされた新しい行の文字をデコードするため、レスポンスに予期しないヘッダーが含まれることになります。
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.19.3
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://example.com/
Detectify: clrf
CRLFインジェクションとレスポンススプリッティングのリスクについて詳しく学ぶには、https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/を参照してください。
この技術はこのトークで説明されていますが、いくつかの脆弱な例と検出メカニズムが含まれています。例えば、ブラックボックスの観点からこの誤設定を検出するには、次のリクエストを使用できます:
https://example.com/%20X
- 任意のHTTPコードhttps://example.com/%20H
- 400 Bad Request
脆弱な場合、最初のリクエストは「X」として返され、任意のHTTPメソッドが使用され、2番目のリクエストはHが有効なメソッドではないためエラーが返されます。したがって、サーバーは次のようなものを受け取ります:GET / H HTTP/1.1
これによりエラーがトリガーされます。
他の検出例は次のとおりです:
http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x
- 任意のHTTPコードhttp://company.tld/%20HTTP/1.1%0D%0AHost:%20x
- 400 Bad Request
そのトークで示された脆弱な構成のいくつかは次のとおりです:
$uri
が最終URLにそのまま設定されていることに注意してください。
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
- 再度、
$uri
がURLに含まれていることに注意してください(今回はパラメータ内です)。
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
- 現在、AWS S3にいます
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}
Any variable
ユーザー提供データが特定の状況下でNginx変数として扱われる可能性があることが発見されました。この挙動の原因はやや不明ですが、珍しいことではなく、確認するのも簡単ではありません。この異常はHackerOneのセキュリティレポートで強調されており、こちらで見ることができます。エラーメッセージのさらなる調査により、NginxのコードベースのSSIフィルターモジュール内での発生が特定され、サーバーサイドインクルード(SSI)が根本的な原因であることが明らかになりました。
この誤設定を検出するために、変数の印刷をテストするためにリファラーヘッダーを設定するコマンドを実行できます:
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
この設定ミスに関するスキャンは、ユーザーによってNginx変数が印刷される複数のインスタンスを明らかにしました。しかし、脆弱なインスタンスの数の減少は、この問題を修正するための努力がある程度成功していることを示唆しています。
生のバックエンドレスポンスの読み取り
Nginxは、バックエンドによって生成されたエラーやHTTPヘッダーを傍受するための機能をproxy_pass
を通じて提供し、内部エラーメッセージやヘッダーを隠すことを目的としています。これは、Nginxがバックエンドエラーに応じてカスタムエラーページを提供することによって実現されます。しかし、Nginxが無効なHTTPリクエストに遭遇すると、問題が発生します。そのようなリクエストは、受信した通りにバックエンドに転送され、バックエンドの生のレスポンスはNginxの介入なしにクライアントに直接送信されます。
uWSGIアプリケーションに関する例を考えてみましょう:
def application(environ, start_response):
start_response('500 Error', [('Content-Type', 'text/html'), ('Secret-Header', 'secret-info')])
return [b"Secret info, should not be visible!"]
これを管理するために、Nginxの設定で特定のディレクティブが使用されます:
http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}
- proxy_intercept_errors: このディレクティブは、Nginxがステータスコードが300を超えるバックエンドレスポンスに対してカスタムレスポンスを提供できるようにします。これにより、例として挙げたuWSGIアプリケーションにおいて、
500 Error
レスポンスがNginxによって捕捉され、処理されることが保証されます。 - proxy_hide_header: 名前が示すように、このディレクティブは指定されたHTTPヘッダーをクライアントから隠し、プライバシーとセキュリティを向上させます。
有効なGET
リクエストが行われると、Nginxは通常通り処理し、秘密のヘッダーを明らかにすることなく標準のエラーレスポンスを返します。しかし、無効なHTTPリクエストはこのメカニズムをバイパスし、生のバックエンドレスポンスが露出し、秘密のヘッダーやエラーメッセージが含まれる結果となります。
merge_slashesをオフに設定
デフォルトでは、Nginxの**merge_slashes
ディレクティブはon
に設定されており、URL内の複数のスラッシュを1つのスラッシュに圧縮します。この機能はURL処理を簡素化しますが、特にローカルファイルインクルージョン(LFI)攻撃に対して脆弱なアプリケーションの背後にある脆弱性を隠す可能性があります。セキュリティ専門家のDanny RobinsonとRotem Bar**は、このデフォルトの動作に関連する潜在的なリスクを指摘しています。特にNginxがリバースプロキシとして機能する場合です。
このようなリスクを軽減するために、これらの脆弱性に対して感受性のあるアプリケーションには**merge_slashes
ディレクティブをオフにする**ことが推奨されます。これにより、NginxはURL構造を変更することなくアプリケーションにリクエストを転送し、基盤となるセキュリティ問題を隠さないようにします。
詳細については、Danny RobinsonとRotem Barを確認してください。
Macliciousレスポンスヘッダー
この書き込みに示されているように、ウェブサーバーからのレスポンスに存在する場合、特定のヘッダーがNginxプロキシの動作を変更します。これらはドキュメントで確認できます:
X-Accel-Redirect
: Nginxにリクエストを指定された場所に内部リダイレクトするよう指示します。X-Accel-Buffering
: Nginxがレスポンスをバッファリングするかどうかを制御します。X-Accel-Charset
: X-Accel-Redirectを使用する際のレスポンスの文字セットを設定します。X-Accel-Expires
: X-Accel-Redirectを使用する際のレスポンスの有効期限を設定します。X-Accel-Limit-Rate
: X-Accel-Redirectを使用する際のレスポンスの転送レートを制限します。
例えば、ヘッダー**X-Accel-Redirect
はNginx内で内部リダイレクトを引き起こします。したがって、root /
のようなNginx設定と、ウェブサーバーからのレスポンスにX-Accel-Redirect: .env
が含まれていると、Nginxは/.env
**の内容を送信します(パストラバーサル)。
マップディレクティブのデフォルト値
Nginxの設定において、map
ディレクティブはしばしば認可制御の役割を果たします。一般的な誤りはデフォルト値を指定しないことで、これが無許可のアクセスにつながる可能性があります。例えば:
http {
map $uri $mappocallow {
/map-poc/private 0;
/map-poc/secret 0;
/map-poc/public 1;
}
}
server {
location /map-poc {
if ($mappocallow = 0) {return 403;}
return 200 "Hello. It is private area: $mappocallow";
}
}
default
がない場合、悪意のあるユーザーは/map-poc
内の未定義のURIにアクセスすることでセキュリティを回避できます。Nginxマニュアルでは、そのような問題を避けるためにデフォルト値を設定することを推奨しています。
DNSスプーフィング脆弱性
特定の条件下でNginxに対するDNSスプーフィングは可能です。攻撃者がNginxが使用するDNSサーバーを知っていて、そのDNSクエリを傍受できる場合、DNSレコードをスプーフィングできます。ただし、NginxがDNS解決に**localhost (127.0.0.1)**を使用するように設定されている場合、この方法は効果がありません。Nginxでは、次のようにDNSサーバーを指定できます:
resolver 8.8.8.8;
proxy_pass
と internal
ディレクティブ
proxy_pass
ディレクティブは、リクエストを他のサーバーにリダイレクトするために使用されます。内部または外部のいずれかです。internal
ディレクティブは、特定の場所が Nginx 内部でのみアクセス可能であることを保証します。これらのディレクティブ自体は脆弱性ではありませんが、その設定はセキュリティの欠陥を防ぐために慎重に検討する必要があります。
proxy_set_header Upgrade & Connection
nginx サーバーが Upgrade および Connection ヘッダーを渡すように設定されている場合、h2c Smuggling attack を実行して保護された/内部エンドポイントにアクセスすることができます。
caution
この脆弱性により、攻撃者は proxy_pass
エンドポイント (http://backend:9999
の場合) との直接接続を確立することができます。その内容は nginx によってチェックされません。
/flag
を盗むための脆弱な設定の例は こちら です。
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/privkey.pem;
location / {
proxy_pass http://backend:9999;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
location /flag {
deny all;
}
warning
proxy_pass
が http://backend:9999/socket.io
のような特定の path を指していても、接続は http://backend:9999
に確立されるため、その内部エンドポイント内の他のパスに連絡することができます。したがって、proxy_pass の URL にパスが指定されていても関係ありません。
自分で試してみる
Detectify は、この記事で説明したいくつかの誤設定を持つ脆弱な Nginx テストサーバーを Docker を使用してセットアップできる GitHub リポジトリを作成しました。自分でそれらを見つけてみてください!
https://github.com/detectify/vulnerable-nginx
静的解析ツール
GIXY
Gixy は Nginx 設定を分析するツールです。Gixy の主な目的は、セキュリティの誤設定を防ぎ、欠陥の検出を自動化することです。
Nginxpwner
Nginxpwner は、一般的な Nginx の誤設定や脆弱性を探すためのシンプルなツールです。
参考文献
- https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/
- http://blog.zorinaq.com/nginx-resolver-vulns/
- https://github.com/yandex/gixy/issues/115
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。