14 KiB
Nginx
从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家)!
支持HackTricks的其他方式:
- 如果您想看到您的公司在HackTricks中做广告或下载PDF格式的HackTricks,请查看订阅计划!
- 获取官方PEASS & HackTricks周边产品
- 探索PEASS家族,我们的独家NFTs
- 加入 💬 Discord群 或 电报群 或 关注我们的Twitter 🐦 @carlospolopm。
- 通过向HackTricks和HackTricks Cloud github仓库提交PR来分享您的黑客技巧。
即时提供的漏洞评估和渗透测试设置。从任何地方运行完整的渗透测试,使用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_pass
和internal
指令
**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 配置错误和漏洞。
参考资料
- https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/
- http://blog.zorinaq.com/nginx-resolver-vulns/
- https://github.com/yandex/gixy/issues/115
即时可用的漏洞评估和渗透测试设置。从任何地方运行完整的渗透测试,使用 20 多种工具和功能,从侦察到报告。我们不取代渗透测试人员 - 我们开发定制工具、检测和利用模块,让他们有更多时间深入挖掘、弹出 shell 并享受乐趣。
{% embed url="https://pentest-tools.com/" %}
从零开始成为 AWS 黑客高手 htARTE(HackTricks AWS 红队专家)学习 AWS 黑客技术!
支持 HackTricks 的其他方式:
- 如果您想看到您的 公司在 HackTricks 中做广告 或 下载 PDF 版本的 HackTricks,请查看 订阅计划!
- 获取 官方 PEASS & HackTricks 商品
- 探索 PEASS 家族,我们的独家 NFTs 收藏品
- 加入 💬 Discord 群组 或 电报群组 或 关注 我们的 Twitter 🐦 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github 存储库提交 PR 来分享您的黑客技巧。