Nginx

ゼロからヒーローまでのAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricks をサポートする他の方法:

脆弱性評価とペネトレーションテストのための即座に利用可能なセットアップ。20以上のツールと機能を備えた完全なペンテストをどこからでも実行し、レコンからレポート作成まで対応します。私たちはペンテスターを置き換えるのではなく、カスタムツール、検出、およびエクスプロイトモジュールを開発して、より深く掘り下げたり、シェルをポップしたり、楽しんだりする時間を与えます。

ルートロケーションが見つかりません

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 /nginx.conf のような単純な GET リクエストは、/etc/nginx/nginx.conf にある Nginx 設定ファイルを提供することで、機密情報を公開する可能性があります。ルートを /etc のようなより機密性の低いディレクトリに設定することで、このリスクを軽減できますが、他の重要なファイルへの意図しないアクセスを許可する可能性があります。これには、他の設定ファイル、アクセスログ、さらにはHTTP基本認証に使用される暗号化された資格情報などが含まれます。

Alias LFI Misconfiguration

Nginxの設定ファイルでは、"location" ディレクティブを注意深く検査する必要があります。次のような構成を通じて、ローカルファイルインクルージョン(LFI)として知られる脆弱性が誤って導入される可能性があります。

location /imgs {
alias /path/images/;
}

この構成は、/imgs../flag.txtのようなリクエストをサーバーが解釈し、意図されたディレクトリの外のファイルにアクセスしようとしていると解釈するため、LFI攻撃に対して脆弱です。これにより、/path/images/../flag.txtに解決されます。この欠陥により、攻撃者はウェブを介してアクセスすべきでないサーバーのファイルを取得できます。

この脆弱性を緩和するために、構成を次のように調整する必要があります:

location /imgs/ {
alias /path/images/;
}

詳細はこちら: 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

安全でないパス制限

以下のページをチェックして、次のようなディレクティブをバイパスする方法を学んでください:

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}
pageProxy / WAF Protections Bypass

危険な変数の使用 / HTTPリクエストの分割

脆弱な変数 $uri$document_uri があり、これらは $request_uri に置き換えることで修正できます。

正規表現も脆弱になる可能性があります:

location ~ /docs/([^/])? { … $1 … } - 脆弱

location ~ /docs/([^/\s])? { … $1 … } - 脆弱ではない(スペースをチェック)

location ~ /docs/(.*)? { … $1 … } - 脆弱ではない

以下の例で、Nginx構成の脆弱性が示されています:

location / {
return 302 https://example.com$uri;
}
<p>The characters \r (Carriage Return) and \n (Line Feed) signify new line characters in HTTP requests, and their URL-encoded forms are represented as `%0d%0a`. Including these characters in a request (e.g., `http://localhost/%0d%0aDetectify:%20clrf`) to a misconfigured server results in the server issuing a new header named `Detectify`. This happens because the $uri variable decodes the URL-encoded new line characters, leading to an unexpected header in the response:</p>
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

リンクhttps://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/でCRLFインジェクションとレスポンス分割のリスクについて詳しく学びます。

また、この技術はこのトークで脆弱な例と検出メカニズムとともに説明されています。たとえば、このミス構成をブラックボックスの観点から検出するために、次のリクエストを使用できます:

  • 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;
}
  • 再度、URL内に $uri があることに注目してください(今回はパラメーターの中にあります)

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;
}

任意の変数

特定の状況下で、ユーザー提供データNginx変数 として扱われる可能性があることが発見されました。この振る舞いの原因はやや理解しづらいですが、珍しいわけではなく、簡単に検証できるわけでもありません。この異常はHackerOneのセキュリティレポートで強調されており、こちらで閲覧できます。エラーメッセージのさらなる調査により、その発生箇所がNginxのコードベースのSSIフィルターモジュール内で特定され、Server Side Includes (SSI) がその原因であることが明らかになりました。

この設定ミスを検出するために、次のコマンドを実行できます。これには、refererヘッダーを設定して変数の印刷をテストする必要があります:

$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’

システム全体でこの設定ミスをスキャンすると、複数のインスタンスでユーザーによってNginx変数が表示される可能性があることが明らかになりました。ただし、脆弱なインスタンスの数の減少から、この問題に対するパッチ適用の取り組みがある程度成功していることが示唆されています。

バックエンドの生のレスポンスの読み取り

Nginxは、proxy_passを介してバックエンドによって生成されたエラーやHTTPヘッダーを傍受する機能を提供しており、内部エラーメッセージやヘッダーを隠すことを目的としています。これは、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エラーレスポンスがNginxによってインターセプトされて処理されることを保証します。

  • proxy_hide_header: その名前が示すように、このディレクティブは特定のHTTPヘッダーをクライアントから隠します。これによりプライバシーとセキュリティが向上します。

有効なGETリクエストが行われると、Nginxは通常通り処理し、秘密のヘッダーを明らかにせずに標準のエラーレスポンスを返します。ただし、無効なHTTPリクエストはこのメカニズムをバイパスし、秘密のヘッダーやエラーメッセージを含む生のバックエンドレスポンスが公開されます。

merge_slashesをoffに設定

デフォルトでは、Nginxの**merge_slashesディレクティブonに設定されており、URL内の複数のスラッシュを単一のスラッシュに圧縮します。この機能は、URL処理を効率化する一方で、特にNginxの背後にあるアプリケーションに存在するローカルファイルインクルージョン(LFI)攻撃に対して脆弱なアプリケーションにおいて、偶然にも脆弱性を隠す可能性があります。セキュリティ専門家のDanny RobinsonRotem Bar**は、特にNginxがリバースプロキシとして機能する場合に、このデフォルトの動作に関連する潜在的なリスクを指摘しています。

このようなリスクを緩和するために、これらの脆弱性に対して感染しやすいアプリケーションでは、merge_slashesディレクティブをoffに設定することが推奨されています。これにより、NginxがURL構造を変更せずにアプリケーションにリクエストを転送することが保証され、基礎となるセキュリティの問題を隠さないようになります。

詳細については、Danny Robinson and Rotem Barを参照してください。

Maclicious Response Headers

この解説に示されているように、Webサーバーからの応答に特定のヘッダーが存在すると、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内で内部リダイレクトを引き起こします。そのため、nginx構成にroot /のようなものがあり、Webサーバーからの応答にX-Accel-Redirect: .envがあると、nginxは/.env**の内容を送信します(パストラバーサル)。

Mapディレクティブのデフォルト値

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スマグリング攻撃が実行され、保護された/内部エンドポイントにアクセスできる可能性があります。

この脆弱性により、攻撃者は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;
}

proxy_passが特定のパスを指していたとしても、例えばhttp://backend:9999/socket.ioのような場合でも、接続はhttp://backend:9999と確立されるため、その内部エンドポイント内の他のパスにアクセスできます。つまり、proxy_passのURLにパスが指定されていても問題ありません。

自分で試してみる

Detectifyは、この記事で議論されているいくつかのミス構成を持つ脆弱なNginxテストサーバーをDockerを使用して設定し、それらを自分で見つけてみることができるGitHubリポジトリを作成しました!

https://github.com/detectify/vulnerable-nginx

静的解析ツール

GixyはNginx構成を分析するツールです。Gixyの主な目標はセキュリティミス構成を防止し、欠陥検出を自動化することです。

Nginxpwnerは一般的なNginxミス構成と脆弱性を探すためのシンプルなツールです。

参考文献

脆弱性評価およびペネトレーションテストのための即座に利用可能なセットアップ。20以上のツールと機能を備えた完全なペンテストをどこからでも実行します。私たちはペンテスターを置き換えるのではなく、彼らに時間を戻してより深く掘り下げたり、シェルをポップしたり、楽しんだりするためのカスタムツール、検出、およびエクスプロイトモジュールを開発しています。

ゼロからヒーローまでのAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

Last updated