文章来源:https://www.acunetix.com/blog/articles/a-fresh-look-on-reverse-proxy-related-attacks
前言
近年来,很多安全研究人员研究攻击的文章中都或多或少涉及到反向代理。在扫描工具能实现检测反向代理种类时,我开始深入研究反向代理的具体实现流程。
最初,我想完全分析代理服务器和Web服务器是如何解析请求,找出一些差异以便将来用于绕过某些限制(开展XSS攻击等)。不幸的是它们有太多的组合了,我不得不专注研究Web服务器和应用服务器。举个例子,当脚本语言(PHP)发生变化时,Apache Web服务器的解析准则也会改变。此外,Web应用所使用的框架,Middleware同样会影响解析。最后,我意识到几乎没人知道如何利用它去攻击。
这项研究的目的是探索反向代理服务及其后端服务器潜在的新攻击向量。在本文的主要部分,我将展示一些易受攻击的配置和利用各种反向代理攻击的例子。研究的第二个目标是分享关于多种情形下反向代理的原始数据,抛砖引玉,方便研究者找到自己的攻击方式(每种特定的情形下取决于后端服务器)。
流程
反向代理的基础思想很简单:作为用户和后端服务器的中间代理服务器。用途多种多样:代替用户请求无法触及的后端内容;“防御”一些攻击;便于分析网络流量等。实现反向代理的方法有很多方法,但流程大致相同。
处理请求-->调整请求-->发送至后端
处理请求:
1、解析:获取请求方式,路径,HTTP类型,Headers,内容。
GET /path HTTP/1.1
Host: example.com
Header: something
看起来很容易,深入研究会发现一些问题。举几个的例子:
-
如果反向代理服务器支持 Absolute-URI, Absolute-URI可能会优先Host header处理?
GET http://other_host_header/path HTTP/1.1 Host: example.com
-
URL由
scheme:[//authority]path[?query][#fragment]
组成,浏览器通常不发送#fragment到服务器。如果发送,反向代理服务器会如何处理#fragment
?
Nginx不处理#fragment
,Apache返回400错误(由于#存在于路径中),其他的把它作为通常的符号处理。 -
如何处理必须被URL编码的特殊内容?
GET /index.php[0x01].jsp HTTP/1.1
2、URL解码:标准规定URL中的特殊字符必须进行URL编码(%-encoding
),比如"
和>
。实际上,路径部分的所有字符都可以URL编码后再发送给服务器。大部分Web服务器处理URL请求时会解码它,包括目标服务器。
GET /index.php HTTP/1.1
GET %2f%69%6e%64%65%78%2e%70%68%70 HTTP/1.1
3、规范化处理路径:大多数Web服务器处理路径有自己的规则,举个例子:
/long/../path/here -> /path/here
/long/./path/here -> /long/path/here
-
如何处理
/..
?,对于Apache,它等于/../
,然而对于Nginx又不一样。/long/path/here/.. -> /long/path/ - Apache /long/path/here/.. -> /long/path/here/.. - Nginx
-
类似的问题,
//
(空目录)是什么情况?Nginx把它转化为单一/
,但是,如果不在首位Apche会把它作为真实目录。//long//path//here -> /long/path/here - Nginx //long/path/here -> /long/path/here - Apache /long//path/here -> /long//path/here - Apache
-
有些Web servers支持一些额外(奇怪)的功能。举个例子:Tomcat和Jetty允许路径中存在特殊参数(
/..;/
)和利用反斜杠目录遍历(\..\
)。
调整请求
在处理完请求后,反向代理服务器会根据特定规则修改请求。需要注意的一点,在许多情况下,反向代理的规则是基于路径。pathA
触发某个规则,pathB
触发另一个。
根据触发的规则和特定配置,反向代理服务器基于已处理路径(解析,URL解码,规范化)或不处理(极少数情况)对请求做出调整。对于研究者来说,注意大小写问题也很重要。下面这个例子,对于反向代理服务器也能够相等?
/path1/ == /Path1/ == /p%61th1/ == /lala/../path1/
转发至后端
反向代理应用适当的规则调整了请求。现在,它必须把请求转发给后端服务器。代理服务器会发送已处理请求还是原始请求?很明显,如果代理服务器已经修改了请求,那么它会发送修改后的,但是,它会执行上述必要的步骤(解析特殊字符等)。如果反向代理服务器只是将用户请求转发给后端,那么不做任何修改是更好的主意?
正如你所见,反向代理的流程单一,步骤简单明了。但是真正实施起来有很大变化,作为攻击方的我们可以利用这一点。
所以,本文描述的攻击要点是反向代理处理请求,做出调整并将其转发到后端。如果我们发现反向代理服务器处理请求的方式与后端服务器处理请求的方式不一样,那么我们可以使用精心构造的路径来攻击后端服务器。我们将使用反向代理服务器的某些默认规则来绕过保护。
攻击研究
Nginx
Nginx是一款知名的Web Server,也很多人用它做反向代理。Nginx支持任意协议的Absolute-URI
且优先级高于Host Header。Nginx对请求中路径做解析,URL解码,规范化处理。它
Nginx有两种有趣的设置方法。
- 结尾处存在
/
location / {
proxy_pass http://backend_server/;
}
在这种情况下,Nginx转发经过处理的所有请求到后端服务器。请求经过阶段一URL解码分析后,Nginx需要再次进行URL编码,再转发到后端。令攻击者兴奋的是Nginx不会像浏览器那样编码的所有字符,例如 ' " < >
。
即使Web应用(后端服务器)易受XSS攻击(从请求路径的参数中直接读取内容),攻击者也无法利用它。因为现代浏览器(除了IE)会对特殊字符进行URL编码。如果这里有个Nginx用作反向代理服务,攻击者发送一个经浏览器URL编码的XSS Payload。Nginx把Payload解码分析处理后,再次编码(由于特性,一些危险字符没有编码),然后转发到后端,这就可能造成XSS攻击。
Browser -> http://victim.com/path/%3C%22xss_here%22%3E/ -> Nginx -> http://backend_server/path/<"xss_here">/ -> WebApp
2 . 结尾处不存在/
location / {
proxy_pass http://backend_server;
}
可以看到,这里少了个斜杠。看起来无关紧要,但是它能使得Nginx代理服务直接转发用户原始请求到后端。如果你发送/any_path/../to_%61pp#/path2
,Nginx会先判断是否有规则再决定是否解码为/to_app
,最终它还是发送/any_path/../to_%61pp#/path2
给后端。类似的改变有助于我们找到差异。
服务端攻击
绕过限制
攻击反向代理最常见的用途。
当想要触及某些受限内容时,攻击者们需要绕过限制。
举个例子:
Nginx作为反向代理服务器,Weblogic作为后端服务器。Nginx阻止用户访问Weblogic管理面板(/console/)。
配置如下
location /console/ {
deny all;return 403;
}
location / {
proxy_pass http://weblogic;
}
可以看到,proxy_pass
后端没有斜杆/
,所以服务器直接转发用户的原始请求。另一个可以绕过限制的要点,Weblogic把#
作为有效成分。所以,攻击者可以构造以下请求进入Weblogic管理面板。
GET /#/../console/ HTTP/1.1
解释一下:当Nginx处理请求时,它无视了#
后面的所有东西,这样可以绕过访问/console/
的限制。它转发原始的/#/../console/
给Weblogic,Weblogic根据规范处理这个路径,所以我们进入了/console/
。
请求错误路由
这里我主要讲两点:由路由到端点;在某种情况,重写路径/查询。
当反向代理只转发请求给后端某一个端点时,这给攻击者造成不能访问后端其他端点的错觉。
例子1
还是熟悉的组合:Nginx+Weblogic. 本例中,Nginx代理只转发请求到Wbelogic某一个特定端点(http://weblogic/to_app
)。因此,只有请求中路径是/to_app
时,Nginx才会转发原始给Weblogic。这种只允许访问/to_app
的情况跟先前的禁止访问Weblogic管理面板(/console/
)有类似之处。
location /to_app {proxy_pass http://weblogic;}
为了触及其他目录,我们必须先弄明白两件事。第一,proxy_pass
和先前例子一样后面没有斜杆。第二,Weblogic支持“path parameters
”(https://tools.ietf.org/html/rfc3986#section-3.3
)。为了方便理解第二点,我举个例子:/path/to/app/here;param1=val1
其中param1
可以通过API连接web app。
我想很多人都知道可以这样做(尤其是在Orange大佬在BlackHat发表演讲后),Tomcat允许一些非常诡异的遍历,比如/..;/..;/
。但是Weblogic有不同的规则,它把第一个;
后面的所有字符视为路径参数。这些东西对攻击者是否有所帮助?
答案是肯定的。让我们来看看这个“魔术”,我们可以访问Weblogic上的任何目录。
GET /any_path_on_weblogic;/../to_app HTTP/1.1
Nginx收到上述请求,它将规范化处理路径。从/any_path_on_weblogic;/../to_app
获取了/to_app
,符合规则。然后转发给后端Weblogic,Weblogic把;
后面的忽略,仅仅处理了/any_path_on_weblogic
。所以,攻击者可以访问任何目录,并且通过增加;
后面的/../
来访问内部的其他内容。
小结
本文介绍了反向代理服务的大致流程以及对潜在攻击向量的一些研究。在后半部分,我将分享一些其他的攻击技术。