前言
最近一直在面试,感觉有好多想搞的东西没时间搞,不面了,收收心搞技术了
在一次src挖掘中遇到了XXL-JOB,不得不说bp的RouteVulScan插件还是有点用的,简单总结一下
简单使用
XXL-Job是一个springboot架构搭建的分布式任务调度平台,主要用于解决大规模分布式系统中的任务调度和管理问题。
源码结构:
1 | - /xxl-job-admin :调度中心,项目源码 |
XXL-JOB分为:
admin后台管理页面(默认端口8080)
和executor任务执行器(原作者给了两个示例,端口分别为9999,9998)
直接访问返回{"code":500,"msg":"invalid request, HttpMethod not support."}
管理界面大概长这个样子
默认账号密码为admin/123456
操作起来也很简单
job(任务)
任务有两种
BEAN模式
Bean模式任务,每个任务对应一个Java或者java方法,指定JobHandler,需要使用@XxlJob()
标签提前进行注册
GLUE模式(Java)
任务以源码方式存在数据库中,支持通过Web IDE在线更新,实时编译和生效,因此不需要指定JobHandler。
executor(执行器)
实际上是一台内嵌Server,原作者提供springboot 版本执行器,可直接使用
请求流程
“调度中心”向“执行器”发送http调度请求:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23地址格式:{执行器内嵌服务根地址}/run
Header:
XXL-JOB-ACCESS-TOKEN : {请求令牌}
请求数据格式如下,放置在 RequestBody 中,JSON格式:
{
"jobId":1, // 任务ID
"executorHandler":"demoJobHandler", // 任务标识
"executorParams":"demoJobHandler", // 任务参数
"executorBlockStrategy":"COVER_EARLY", // 任务阻塞策略,可选值参考 com.xxl.job.core.enums.ExecutorBlockStrategyEnum
"executorTimeout":0, // 任务超时时间,单位秒,大于零时生效
"logId":1, // 本次调度日志ID
"logDateTime":1586629003729, // 本次调度日志时间
"glueType":"BEAN", // 任务模式,可选值参考 com.xxl.job.core.glue.GlueTypeEnum
"glueSource":"xxx", // GLUE脚本代码
"glueUpdatetime":1586629003727, // GLUE脚本更新时间,用于判定脚本是否变更以及是否需要刷新
"broadcastIndex":0, // 分片参数:当前分片
"broadcastTotal":0 // 分片参数:总分片
}
响应数据格式:
{
"code": 200, // 200 表示正常、其他失败
"msg": null // 错误提示消息
}“执行器”中接收请求,“执行器”执行任务逻辑;
“执行器”http回调“调度中心”调度结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18说明:执行器执行完任务后,回调任务结果时使用
------
地址格式:{调度中心根地址}/api/callback
Header:
XXL-JOB-ACCESS-TOKEN : {请求令牌}
请求数据格式如下,放置在 RequestBody 中,JSON格式:
[{
"logId":1, // 本次调度日志ID
"logDateTim":0, // 本次调度日志时间
"handleCode":200, // 200 表示任务执行正常,500表示失败
"handleMsg": null
}
]
响应数据格式:
{
"code": 200, // 200 表示正常、其他失败
"msg": null // 错误提示消息
}漏洞
Hessian反序列化(XxlJob<=2.1.2)
XXL-JOB <= 2.0.2,其/xxl-job-admin/api接口可以未授权访问,该接口存在Hessian2反序列化漏洞curl -XPOST -H "Content-Type: x-application/hessian" --data-binary @test.ser http://127.0.0.1:8080/xxl-job-admin/api
关于Hessian2反序列化前面nacos已经写了,这里不仅有原生链,还可以打spring链实现jndi
Spring framework jndi反序列化
漏洞sink点在org/springframework/jndi/JndiTemplate#lookup
中
1 | public Object lookup(final String name) throws NamingException { |
所以接下来就是寻找哪里可以调用JndiTemplate#lookup
调用栈如下:
lookup:179, JndiTemplate (org.springframework.jndi)
lookup:96, JndiLocatorSupport (org.springframework.jndi)
doGetSingleton:271, SimpleJndiBeanFactory (org.springframework.jndi.support)
doGetType:279, SimpleJndiBeanFactory (org.springframework.jndi.support)
getType:245, SimpleJndiBeanFactory (org.springframework.jndi.support)
getType:238, SimpleJndiBeanFactory (org.springframework.jndi.support)
getOrder:136, BeanFactoryAspectInstanceFactory (org.springframework.aop.aspectj.annotation)
getOrder:223, AbstractAspectJAdvice (org.springframework.aop.aspectj)
getOrder:66, AspectJPointcutAdvisor (org.springframework.aop.aspectj)
toString:147, AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder (org.springframework.aop.aspectj.autoproxy)
equals:392, XString (com.sun.org.apache.xpath.internal.objects)
equals:104, HotSwappableTargetSource (org.springframework.aop.target)
putVal:635, HashMap (java.util)
客户端命令执行漏洞(2.2.0<=XxlJob<=2.4.0)
executor的/run接口未授权可以自定义任务,从而导致任意代码执行
executor默认没有配置认证,未授权的攻击者可以通过RESTful API接口执行任意命令。
当客户端命令执行漏洞(XxlJob>=2.2.0),可以使用默认accessToken绕过
ssrf获取
XXL-JOB-ACCESS-TOKEN
内存马注入
没找到执行器端口,遇到了再写