Nginx是支持世界上所有网站三分之一的Web服务器。 Detectify Crowdsource已检测到一些常见的Nginx错误配置,如果不进行检查,将使您的网站容易受到攻击。以下是在攻击者利用它们之前发现一些最常见的错误配置的方法。
Nginx是Internet上最常用的Web服务器之一,因为它轻巧,模块化并且具有用户友好的配置格式。在Detectify,我们为成千上万的客户扫描Nginx中的配置错误和安全漏洞。我们的Crowdsource网络会定期提交影响Nginx的新的有趣漏洞,然后将其作为安全性测试实施到我们的Web应用程序扫描程序中。
我们使用Google BigQuery分析了从GitHub下载的近50,000个唯一的Nginx配置文件。有了这些数据,我们可以发现不同配置错误的普遍程度。
服务器 { 根/ etc / nginx; 位置/hello.txt { try_files $ uri $ uri / = 404; proxy_pass http://127.0.0.1:8080/; } }
root指令指定Nginx的根文件夹。在上面的示例中,根文件夹是/ etc / nginx,这意味着我们可以访问该文件夹中的文件。上面的配置没有/的位置(location / {...}),只有/hello.txt的位置。因此,将对root指令进行全局设置,这意味着对/的请求会将您带到本地路径/ etc / nginx。
像GET /nginx.conf这样简单的请求将显示存储在/etc/nginx/nginx.conf中的Nginx配置文件的内容。如果将根设置为/ etc,则对/nginx/nginx.conf的GET请求将显示配置文件。在某些情况下,可以访问其他配置文件,访问日志,甚至可以进行HTTP基本身份验证的加密凭据。在我们收集的近50,000个Nginx配置文件中,最常见的根路径如下:
服务器 { 监听80 default_server; 服务器名称 _; 位置/ static { 别名/ usr / share / nginx / static /; } 位置/ api { proxy_pass http:// apiserver / v1 /; } }
借助斜杠偏移配置错误,由于缺少斜杠,因此有可能沿路径上移一步。 Orange Tsai在Blackhat的演讲“ Breaking Parser Logic!”中使这项技术广为人知。在本次演讲中,他展示了location指令与alias指令结合使用的缺失斜杠如何使读取Web应用程序的源代码成为可能。鲜为人知的是,它还可以与其他指令(例如proxy_pass)一起使用。让我们来分解一下正在发生的事情以及它为什么起作用。
如果Nginx服务器运行服务器可以访问的以下配置,则可以假定只能访问http:// apiserver / v1 /下的路径。
当请求http:// server / api / user时,Nginx将首先规范化URL。然后,它查看前缀/ api是否与URL匹配,在这种情况下,URL会匹配。然后,从URL中删除该前缀,以便保留路径/ user。然后将此路径添加到proxy_pass URL中,从而得到最终URL http:// apiserver / v1 // user。请注意,URL中存在双斜杠,因为location指令不以斜杠结尾,并且proxy_pass URL路径以斜杠结尾。大多数Web服务器会将http:// apiserver / v1 // user标准化为http:// apiserver / v1 / user,这意味着即使配置错误,所有内容仍将按预期运行,并且可能不会引起注意。
通过请求http://server/api../可以利用这种错误配置,这将导致Nginx请求标准化为http:// apiserver /的URL http://apiserver/v1/../。这可能产生的影响取决于利用这种错误配置可以达到的效果。例如,这可能导致Apache服务器状态通过URL http://server/api../server-status公开,或者可以使那些不打算公开访问的路径可访问。
Nginx服务器配置错误的一个迹象是,当URL中的斜杠被删除时,服务器仍然返回相同的响应。例如,如果http:// server / api / user和http:// server / apiuser返回相同的响应,则服务器可能容易受到攻击。这将导致发送以下请求:
一些框架,脚本和Nginx配置不安全地使用Nginx存储的变量。这可能会导致诸如XSS,绕过HttpOnly保护,信息泄露甚至在某些情况下甚至是RCE之类的问题。
主要问题是Nginx会将所有URL发送到以.php结尾的PHP解释器,即使该文件在光盘上不存在。正如Nginx创建的“陷阱和常见错误”文档中概述的那样,这是许多Nginx配置中的常见错误。
如果PHP脚本试图基于SCRIPT_NAME定义基本URL,则将发生XSS。
与Nginx变量有关的另一个错误配置是使用$ uri或$ document_uri而不是$ request_uri。 $ uri和$ document_uri包含规范化的URI,而Nginx中的规范化包括URL解码URI。 Volema发现,在Nginx配置中创建重定向会导致CRLF注入时,通常使用$ uri。
HTTP请求的新行字符为\ r(回车)和\ n(换行)。对新行字符进行URL编码将导致以下字符%0d%0a的表示形式。如果将这些字符包含在对服务器的配置错误的请求(例如http:// localhost /%0d%0aDetectify:%20clrf)中,由于$ uri变量包含URL解码的new行字符。
HTTP / 1.1 302临时移动 伺服器:nginx / 1.19.3 内容类型:text / html 内容长度:145 连接:保持活动状态 位置:https://example.com/ 检测:clrf
在某些情况下,用户提供的数据可以视为Nginx变量。目前尚不清楚为什么会发生这种情况,但是如本H1报告所示,这种情况并不罕见或不容易测试。如果搜索错误消息,我们可以看到它是在SSI过滤器模块中找到的,从而表明这是由于SSI引起的。
我们扫描了这种错误配置,发现了几个实例,用户可以在其中打印Nginx变量的值。发现的易受攻击实例的数量有所下降,这可能表明已对其进行了修补。
使用Nginx的proxy_pass,可以拦截后端创建的错误和HTTP标头。如果要隐藏内部错误消息和标头,以便由Nginx处理,则这非常有用。如果后端回答一个,Nginx将自动提供自定义错误页面。但是,如果Nginx不理解这是HTTP响应怎么办?
如果客户端向Nginx发送了无效的HTTP请求,则该请求将按原样转发到后端,后端将使用其原始内容进行应答。然后,Nginx将无法理解无效的HTTP响应,而会将其转发给客户端。想象这样的uWSGI应用程序:
如果后端的响应状态大于300,proxy_intercept_errors将提供自定义响应。在上面的uWSGI应用程序中,我们将发送500错误,Nginx将拦截该错误。
proxy_hide_header几乎可以自我解释;它将从客户端隐藏任何指定的HTTP标头。
默认情况下,merge_slashes指令设置为“ on”,这是一种将两个或多个正斜杠压缩为一个的机制,因此///将变为/。如果Nginx用作反向代理,并且被代理的应用程序容易受到本地文件包含的影响,则在请求中使用多余的斜杠可能会留出利用空间。 Danny Robinson和Rotem Bar对此进行了详细描述。
我们已经创建了一个GitHub存储库,您可以在其中使用Docker来设置您自己的易受攻击的Nginx测试服务器,以及本文中讨论的一些错误配置,然后尝试自己找到它们!
Nginx是一个非常强大的Web服务器平台,很容易理解为什么它被广泛使用。但是,通过灵活的配置,您可以犯错误,从而可能会对安全产生影响。请勿勾选这些常见的错误配置,以免让攻击者轻易地入侵您的网站。 Detectify可以检测所有这些错误配置,如果您没有时间手动检查自己,则可以帮助您保护网站免受潜在攻击者的侵害。立即注册免费的2周试用版,开始使用!