hacktricks/network-services-pentesting/pentesting-web/nginx.md

14 KiB
Raw Blame History

Nginx

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS红队专家

支持HackTricks的其他方式

即时提供的漏洞评估和渗透测试设置。从任何地方运行完整的渗透测试使用20多种工具和功能从侦察到报告。我们不取代渗透测试人员 - 我们开发定制工具、检测和利用模块让他们有更多时间深入挖掘、弹出shell并享受乐趣。

{% embed url="https://pentest-tools.com/" %}

缺少根位置

配置Nginx根目录的基本要点

在配置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 基本认证的加密凭据。

别名 LFI 配置错误

在 Nginx 的配置文件中,需要仔细检查 "location" 指令。一个称为本地文件包含 (LFI) 的漏洞可能会通过类似以下配置而不经意地引入:

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

这种配置容易受到LFI攻击因为服务器会将类似/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

不安全的路径限制

查看以下页面以了解如何绕过诸如:

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

不安全的变量使用

以下示例演示了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注入和响应拆分的风险请访问https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/.

任何变量

发现在某些情况下用户提供的数据可能被视为Nginx变量。这种行为的原因仍然有些难以捉摸但并不罕见也不容易验证。这一异常在HackerOne的一份安全报告中得到了突出可以在此处查看。对错误消息的进一步调查导致在Nginx代码库的SSI过滤模块中确定了其发生的位置将服务器端包含SSI确定为根本原因。

检测此配置错误,可以执行以下命令,其中涉及设置引用者标头以测试变量打印:

$ 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 Robinson和Rotem Bar**已经强调了与此默认行为相关的潜在风险特别是当Nginx充当反向代理时。

为了减轻这种风险,建议关闭merge_slashes指令以防止这些漏洞易受攻击的应用程序。这样可以确保Nginx将请求转发给应用程序而不会更改URL结构从而不会掩盖任何潜在的安全问题。

有关更多信息,请查看Danny Robinson和Rotem Bar

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配置为使用**localhost (127.0.0.1)**进行DNS解析则此方法无效。Nginx允许如下指定DNS服务器

resolver 8.8.8.8;

proxy_passinternal指令

**proxy_pass指令用于将请求重定向到其他服务器,可以是内部或外部。internal**指令确保某些位置仅在Nginx内部可访问。虽然这些指令本身并非漏洞但它们的配置需要仔细检查以防止安全漏洞。

proxy_set_header Upgrade & Connection

如果nginx服务器配置为传递Upgrade和Connection标头则可能会执行h2c Smuggling attack以访问受保护/内部端点。

{% hint style="danger" %} 此漏洞将允许攻击者与proxy_pass端点(在本例中为http://backend:9999建立直接连接nginx不会检查其内容。 {% endhint %}

这里窃取/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;
}

{% hint style="warning" %} 请注意,即使 proxy_pass 指向特定的 路径,比如 http://backend:9999/socket.io,连接也会建立在 http://backend:9999,因此您可以访问内部端点中的任何其他路径。因此,在 proxy_pass 的 URL 中指定路径并不重要。 {% endhint %}

亲自尝试

Detectify 创建了一个 GitHub 存储库,您可以使用 Docker 设置自己的易受攻击的 Nginx 测试服务器,其中包含本文讨论的一些配置错误,并尝试自行查找它们!

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

静态分析工具

GIXY

Gixy 是一个用于分析 Nginx 配置的工具。Gixy 的主要目标是防止安全配置错误并自动化缺陷检测。

Nginxpwner

Nginxpwner 是一个简单的工具,用于查找常见的 Nginx 配置错误和漏洞。

参考资料

即时可用的漏洞评估和渗透测试设置。从任何地方运行完整的渗透测试,使用 20 多种工具和功能,从侦察到报告。我们不取代渗透测试人员 - 我们开发定制工具、检测和利用模块,让他们有更多时间深入挖掘、弹出 shell 并享受乐趣。

{% embed url="https://pentest-tools.com/" %}

从零开始成为 AWS 黑客高手 htARTEHackTricks AWS 红队专家)学习 AWS 黑客技术!

支持 HackTricks 的其他方式: