常见的 Nginx 配置错误,使您的 Web 服务器可以被攻击
Nginx 是为世界上三分之一的网站提供的 Web 服务器。检测众包已检测到一些常见的 Nginx 错误配置,如果不加检查,则会使您的网站容易受到攻击。下面介绍如何在攻击者利用它们之前找到一些最常见的错误配置。
更新:检测安全顾问弗朗斯·罗森(Frans Rosen)发表了一些研究,深入探讨了他在帖子中关于检测实验室的一些新颖的 Web 服务器错误配置:中间件、无处不在的中间件 - 以及许多用于修复的配置错误
Nginx 是互联网上最常用的 Web 服务器之一,因为它重量轻、模块化且具有用户友好的配置格式。在检测时,我们为成千上万的客户扫描 Nginx 中的配置错误和安全漏洞。我们的众包网络定期提交影响 Nginx 的新且有趣的漏洞,然后我们将这些漏洞作为安全测试实施到我们的 Web 应用扫描仪中。
我们分析了从 GitHub 下载的近 50,000 个独特的 Nginx 配置文件与谷歌 BigQuery。有了这些数据,我们可以找出不同的配置错误有多常见。
本文将揭示以下 Nginx 配置错误:
- Missing root location
- Unsafe variable use
- Raw backend response reading
- merge_slashes set to off
缺少根位置;
server {
root /etc/nginx;
location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}
根指令指定了 Nginx 的根文件夹。在上述示例中,根文件夹是/等/nginx,这意味着我们可以到达该文件夹内的文件。上述配置没有位置/(位置/{...),仅用于/你好.txt。因此,根指令将在全球范围内设置,这意味着请求/将带您到本地路径/等/nginx。
像GET /nginx.conf一样简单的请求将揭示存储在/等/nginx/nginx.com 中的 Nginx配置文件的内容。如果根被设置为/等, GET请求/nginx/nginx.com将显示配置文件。在某些情况下,可以访问其他配置文件、访问日志,甚至加密凭据以进行 HTTP 基本身份验证。
在我们收集的近 50,000 个 Nginx 配置文件中,最常见的根路径如下:
Off-By-Slash
server {
listen 80 default_server;
server_name _;
location /static {
alias /usr/share/nginx/static/;
}
location /api {
proxy_pass http://apiserver/v1/;
}
}
由于Off-By-Slash错误,由于缺少斜线,可以沿着路径前进一步。奥兰治蔡使这项技术众所周知,在他的黑帽谈话"打破帕瑟逻辑! 在这次谈话中,他展示了位置指令中缺少的尾随斜线与别名指令如何能够读取 Web 应用程序的源代码。鲜为人知的是,这也适用于其他指令,如proxy_pass。让我们细分正在发生的事情以及为什么这行得通。
location /api {
proxy_pass http://apiserver/v1/;
}
Nginx 服务器运行以下可在服务器上访问的配置,因此可能假定只能访问http://apiserver/v1/下的路径。
http://server/api/user -> http://apiserver/v1//user
请求http://server/api/user时,Nginx 将首先使 URL 正常化。然后,它会查看前缀/api是否与 URL 匹配,在这种情况下,它确实符合 URL。然后从 URL 中删除前缀,以便留下路径/用户。然后将此路径添加到proxy_pass URL 中,从而产生最终的 URL http://apiserver/v1//user。请注意,URL 中有双斜线,因为位置指令不会以斜线结束,而proxy_pass URL 路径以斜线结束。大多数网络服务器都会将http://apiserver/v1//user正常化到http://apiserver/v1/user,这意味着即使配置错误,一切都将如预期的那样工作,而且可能会被忽视。
这种配置错误可以通过请求http://server/api../来利用,这将导致Nginx请求将URL http://apiserver/v1/../规范化为http://apiserver/。 这可以产生的影响取决于当利用此错误配置时可以达到什么效果。例如,它可能导致 Apache 服务器状态暴露在 URL http://server/api../server-status中,或者它可能使无法公开访问的路径变得可访问。
Nginx 服务器存在此错误配置的一个迹象是,当删除 URL 中的斜线时,服务器仍然返回相同的响应。例如,如果两者都http://server/api/user并返回相同的响应,则服务器可能很脆弱。这将导致发送以下请求:http://server/apiuser
http://server/api/user -> http://apiserver/v1//user
http://server/apiuser -> http://apiserver/v1/user
不安全的可变使用
某些框架、脚本和 Nginx 配置不安全地使用 Nginx 存储的变量。这可能导致诸如 XSS、绕过 HttpOn 保护、信息披露,在某些情况下甚至 RCE 等问题。
SCRIPT_NAME
配置如下:
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}
主要问题是,Nginx 将向 PHP 翻译发送任何 URL,以.php结束,即使光盘上不存在文件。这是许多Nginx配置中常见的错误,如Nginx创建的"陷阱和常见错误"文档中所概述的那样。
如果 PHP 脚本尝试根据SCRIPT_NAME定义基本 URL,则将发生XSS;
<?php
if(basename($_SERVER['SCRIPT_NAME']) ==
basename($_SERVER['SCRIPT_FILENAME']))
echo dirname($_SERVER['SCRIPT_NAME']);
?>
GET /index.php/<script>alert(1)</script>/index.php
SCRIPT_NAME = /index.php/<script>alert(1)</script>/index.php
使用$uri可导致 CRLF 注射
与Nginx变量相关的另一个错误配置是使用$uri或$document_uri,而不是$request_uri。$uri和$document_uri包含规范化的 URI,而 Nginx 中的规范化包括 URL 解码 URI。 Volema发现,在 Nginx 配置中创建重定向时,通常使用$uri,从而导致 CRLF 注射。
易受攻击的Nginx配置的一个例子是:
location / {
return 302 https://example.com$uri;
}
HTTP 请求的新行字符为\r(运输返回)和\n(线路馈送)。URL编码新的行字符导致以下表示字符%0d%0a。当这些字符包含在http://localhost/%0d%0aDetectify:%20clrf到配置错误的服务器的请求中时,服务器将使用名为"检测"的新标题进行响应,因为$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 变量。目前还不清楚为什么会发生这种情况,但这不是那么罕见或容易测试,因为在这个H1报告中看到。如果我们搜索错误消息,我们可以看到它被发现在SSI过滤器模块,从而揭示这是由于SSI。
测试此值的一种方法是设置引用器标题值:
$ curl -H 'Referer: bar' http://localhost/foo$http_referer | grep 'foobar'
我们扫描了此错误配置,并发现了几个用户可以打印 Nginx 变量值的实例。已发现的脆弱实例数量已经减少,这可能表明这是修补的。
原始后端响应读数
随着Nginx的proxy_pass,有可能拦截由后端创建的错误和HTTP头。这是非常有用的,如果你想隐藏内部错误消息和标题,所以他们反而由Nginx处理。Nginx 将自动提供自定义错误页面,如果后端答案与一个。但是, 如果 Nginx 不明白这是 Http 的反应呢?
如果客户向 Nginx 发送无效的 HTTP 请求,该请求将按照原样转发到后端,后端将对其原始内容进行回答。然后,Nginx 不会理解无效的 HTTP 响应,只需将其转发给客户端。想象一下这样的 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;
}
如果后端的响应状态大于 300,则proxy_intercept_errors将提供自定义响应。在上面的 uWSGI 应用程序中,我们将发送一个500 错误,该错误将被 Nginx 截获。
proxy_hide_header几乎是自我解释的:它将向客户端隐藏任何指定的HTTP标头。
如果我们发送一个正常的GET请求,Nginx 将返回:
HTTP/1.1 500 Internal Server Error
Server: nginx/1.10.3
Content-Type: text/html
Content-Length: 34
Connection: close
但是,如果我们发送无效的 HTTP 请求,例如:
GET /? XTTP/1.1
Host: 127.0.0.1
Connection: close
我们将获得以下响应:
XTTP/1.1 500 Error
Content-Type: text/html
Secret-Header: secret-info
Secret info, should not be visible!
merge_slashes出发了
默认情况下,merge_slashes指令设置为"开启",这是将两个或多个向前斜线压缩成一个的机制,因此///将成为/。如果 Nginx 被用作反向代理,并且正在提交的应用程序易受本地文件包含的影响,则在请求中使用额外的斜线可能会为开发它留出空间。这是丹尼罗宾逊和罗特姆酒吧详细描述。
我们发现了33个nginx配置文件,merge_slashes设置为"关闭"。
自己试试
我们创建了一个 GitHub 存储库,您可以使用 Docker 设置您自己的易受攻击的 Nginx 测试服务器,其中讨论了本文中讨论的一些错误配置,并尝试自己找到它们!
https://github.com/detectify/vulnerable-nginx
进一步阅读:
结论
Nginx 是一个非常强大的 Web 服务器平台,它很容易理解为什么它被广泛使用。但是,通过灵活的配置,您可以做出可能具有安全影响的错误。不要让攻击者通过不检查这些常见的错误配置来破解您的网站太容易。
转发来源:https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/
文章来源:刘俊涛的博客 欢迎关注公众号、留言、评论,一起学习。
__________________________________________________________________________________
若有帮助到您,欢迎点击推荐,您的支持是对我坚持最好的肯定(*^_^*)
你要保守你心,胜过保守一切。
本文来自博客园,作者:刘俊涛的博客,转载请注明原文链接:https://www.cnblogs.com/lovebing/p/14484632.html