在攻防演练中,XXL-Job的API未授权Hessian2反序列化漏洞常成为突破目标系统的关键入口。该漏洞存在于XXL-Job 2.0.2及更低版本中,因API接口未做权限校验,且默认使用Hessian2序列化协议处理请求,攻击者可构造恶意反序列化数据,实现远程命令执行。本文结合实战场景,从环境搭建、漏洞分析到JavaChain绕WAF攻击,完整复现漏洞利用全流程。
一、漏洞背景与影响范围
XXL-Job是一款分布式任务调度框架,广泛应用于企业级系统的定时任务管理。其漏洞核心在于**/api接口未授权访问与Hessian2反序列化风险**的叠加:
– 未授权访问: JobApiController 类的 /api 接口标注 @PermessionLimit(Limit=false) ,直接禁用权限校验,任何用户无需认证即可访问。
– 反序列化风险:接口通过 HessianSerializer 处理请求数据,Hessian2协议在反序列化过程中未做安全校验,攻击者可注入恶意对象,触发 readObject 等方法执行恶意代码。
影响范围:仅XXL-Job 2.0.2及更低版本,高版本已通过增加权限校验、限制序列化类等方式修复该漏洞。
二、漏洞复现环境搭建
1. 基础环境准备
– JDK版本:jdk8u65(需选择低版本JDK,高版本JDK对RMI/LDAP远程调用的限制会影响漏洞利用)。
– XXL-Job源码:从GitHub下载2.0.2版本(
https://github.com/xuxueli/xxl-job)。
– 数据库:使用Docker快速部署MySQL,命令如下:
bash
# 拉取MySQL镜像并启动容器
docker pull mysql:latest
docker run -itd –name mysql-xxljob -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
# 测试数据库连接
mysql -h 127.0.0.1 -u root -p
2. 配置XXL-Job与数据库关联
1. 创建数据库:登录MySQL后,创建名为 xxl-job 的数据库,字符集设为 utf8mb4 ,排序规则为 utf8mb4_0900_ai_ci 。
2. 导入初始化SQL:进入XXL-Job源码的 doc/db 目录,执行SQL脚本初始化表结构:
bash
mysql -h 127.0.0.1 -u root -p xxl-job < tables_xxl_job.sql
3. 修改配置文件:编辑
xxl-job-admin/src/main/resources/application.properties ,更新数据库连接信息:
properties
# 数据库连接配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl-job?Unicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
3. 启动XXL-Job服务
运行
xxl-job-admin/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java 的 main 方法,启动服务。访问
http://127.0.0.1:8080/xxl-job-admin/toLogin ,出现登录页面即表明环境搭建成功(无需登录即可利用 /api 接口)。
三、漏洞原理深度分析
1. 未授权访问根源
在 JobApiController.java 中, /api 接口的 @PermessionLimit(Limit=false) 注解是关键:
– 该注解由XXL-Job自定义, Limit=false 表明跳过登录拦截,任何请求都能进入接口处理逻辑。
– 接口映射通过 AdminBiz.MAPPING 实现,等价于 @RequestMapping(“/api”) ,攻击者可直接向该路径发送请求。
2. Hessian2反序列化调用链
接口处理流程中,反序列化漏洞出目前 parseRequest 方法:
1. 请求解析:
ServletServerHandler.parseRequest() 读取HTTP请求体的字节流,调用
HessianSerializer.deserialize() 进行反序列化。
2. 无校验反序列化:Hessian2序列化协议默认支持多种类的反序列化,且未过滤危险类(如
javax.naming.InitialContext ),攻击者可构造包含恶意调用链的Hessian2数据。
3. 命令执行触发:当恶意数据被反序列化时,会触发预设的调用链(如JDK原生链、Spring链),最终执行 Runtime.getRuntime().exec() 等命令执行代码。
核心调用链简化如下:
HTTP请求 → /api接口(未授权)→ 读取请求字节流 → Hessian2反序列化 → 触发恶意调用链 → 远程命令执行
四、漏洞利用实战
1. 基础利用:生成Hessian2恶意Payload
使用 JavaChain 工具(一款Java反序列化Payload生成框架)生成Hessian2格式的恶意数据,步骤如下:
1. 选择Payload类型:打开JavaChain,选择 Hessian2Payload ,调用JDK原生反序列化链(适配低版本JDK)。
2. 配置命令:设置需执行的命令(如 calc.exe 弹出计算器,或 ifconfig 查看网络配置)。
3. 生成Payload:工具自动生成Hessian2格式的二进制Payload,可导出为Base64编码便于传输。
2. 发送攻击请求
通过 curl 或Burp Suite向 /api 接口发送POST请求,需注意:
– Content-Type:必须设为 x-application/hessian ,否则服务器不会使用Hessian2反序列化处理。
– 请求体:填入Base64解码后的Hessian2恶意数据。
示例 curl 命令:
bash
curl -X POST http://192.168.1.137:8080/xxl-job-admin/api
-H “Content-Type: x-application/hessian”
-H “User-Agent: curl/8.7.1”
–data-binary @payload.bin # payload.bin为Hessian2恶意数据文件
执行后,目标服务器会弹出计算器(Windows环境)或返回 ifconfig 结果(Linux环境),证明漏洞利用成功。
五、进阶技巧:JavaChain绕WAF攻击
在实际攻防中,目标系统常部署WAF拦截 /api 接口请求或恶意Payload,可通过以下两种方式绕过:
1. 路径绕过:双斜杠替换单斜杠
部分WAF仅拦截 /xxl-job-admin/api 路径,将路径改为 //api (如 /xxl-job-admin//api )即可绕过。缘由是Web服务器会自动将多个斜杠合并为单个斜杠,而WAF可能未处理这种路径规范化。
2. Payload混淆:添加脏数据
使用JavaChain的“脏数据混淆”功能,在恶意Payload中插入大量随机垃圾数据(如随机集合类、无效类名),干扰WAF的特征检测:
1. 配置混淆参数:在JavaChain中设置 dirtyCollectionSize=10000 (生成1万个随机集合类封装恶意对象), overlongMode=1 (混合UTF-8超长编码)。
2. 生成混淆Payload:工具会生成包含大量脏数据的超长Payload,WAF因无法识别恶意特征而放行,服务器解析时则会自动忽略脏数据,正常触发反序列化。
绕过成功后,即使WAF拦截常规请求,混淆后的请求仍能触发命令执行,例如执行 ifconfig 获取目标服务器网络信息。
六、漏洞修复提议
1. 版本升级:将XXL-Job升级至2.0.3及以上版本,高版本已移除 /api 接口的未授权配置,并限制Hessian2反序列化的类范围。
2. 临时防护(无法升级时):
– 在服务器层面(如Nginx)拦截 /api 接口,仅允许信任IP访问。
– 修改 JobApiController.java 的 @PermessionLimit(Limit=true) ,启用权限校验。
3. JDK版本限制:部署高版本JDK(如jdk8u121+),禁用RMI/LDAP远程调用,降低反序列化漏洞的利用成功率。
总结
XXL-Job的API未授权Hessian2反序列化漏洞,本质是“未授权访问+危险反序列化”的典型组合漏洞。通过本文的环境搭建、漏洞分析与绕WAF实战,可清晰掌握该漏洞的利用逻辑。在实际防护中,除升级版本外,还需加强API接口的权限管控与序列化协议的安全配置,避免成为攻击者的突破口。
暂无评论内容