前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >xxl-job2.3.1 SSRF漏洞分析与思考

xxl-job2.3.1 SSRF漏洞分析与思考

作者头像
叔牙
发布2024-11-23 16:20:44
发布2024-11-23 16:20:44
49100
代码可运行
举报
运行总次数:0
代码可运行

微信公众号:PersistentCoder关注可了解更多的教程。

📢 提示: 靶场来自个人云服务器,真实网络环境渗透测试请严格遵守《中国网络信息安全法》,请勿轻易用于他人线上网络环境安全测试,本人不承担任何法律责任。

一、漏洞概述

先看一下官方对CVE-2022-43183的描述。

从xxl-job官网看到2.3.1到2.4.0的版本变更日志.

从表面来看,2.4.0+版本修复了CVE-2022-43183的SSRF漏洞,主要影响2.3.1及以下版本。

二、关于SSRF

1.SSRF漏洞概念

SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。

因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内网。也就是说可以利用一个网络请求的服务,当作跳板进行攻击。

SSRF 形成的原因往往是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。如:从指定URL地址获取网页文本内容,加载指定地址的图片,下载等。利用的就是服务端的请求伪造。ssrf是利用存在缺陷的web应用作为代理攻击远程和本地的服务器。

2.SSRF漏洞原理

SSRF的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。例如,黑客操作服务端从指定URL地址获取网页文本内容,加载指定地址的图片等,利用的是服务端的请求伪造。SSRF利用存在缺陷的Web应用作为代理攻击远程和本地的服务器。

3.xxl-job中的SSRF

低版本xxl-job,用户从攻击机向xxl-job-admin发送请求,然后xxl-job-admin将恶意请求转发给xxl-job-executor,或者自己冒充的执行器,从而实现获取敏感数据以及服务器入侵。

对于xxl-job,SSRF漏洞可以实现如下目的:

  • 获取accessToken: 对于没有使用默认accessToken的调度服务,可以利用该漏洞获取accessToken。
  • 利用accessToken攻击executor机器:比如远程命令执行,包括shell反弹获取机器操作权限。

三、漏洞利用

1.控制台搜索

对于Fofa网络空间引擎:

代码语言:javascript
代码运行次数:0
复制
app="XXL-JOB" || title="任务调度中心"

其他搜索引擎不做过多介绍,感兴趣自行研究:

  • https://hunter.qianxin.com/
  • https://search.censys.io/
  • https://www.shodan.io/
  • https://www.zoomeye.hk/

本文使用自己的云服务器实现漏洞分析与复现,跳过此步骤。

2.爆破控制台

使用burpsuite拦截登录请求,并发送到intruder(此步骤使用自己服务器或者开源靶场做实验!!!):

然后加载本地的弱口令字典,字典越庞大,爆破的概率越高:

添加好弱口令密码字典后,点击右上角的start attack,如果密码库够强大,如果xxl-job控制台确实使用了弱口令密码,那么大概率能够爆破,爆破结束后将结果按照length排序,成功的长度与失败的长度不一样。

点击对应响应内容看到响应码200成功,并且正确返回了XXL_JOB_LOGIN_IDENTITY对应的cookie值,说明登录成功了,这时候拿到对应的爆破密码就可以登录调度控制台了。

其实这里登录控制台成功就可以创建glueShell任务来反弹shell了,不过本篇重点介绍SSRF获取accessToken以及利用,对于控制台getshell不再展开介绍。

3.创建普通账号获取accessToken

先创建一个普通账号:

然后用如下python脚本启动一个http服务,模拟executor:

启动服务器监听8080端口:

然后使用普通账号登录成功后的cookie发送请求:

然后到用python启动的http服务看日志输出:

accessToken明文传输已经拿到了。。。。。。

4.accessToken延伸利用

在获取了accessToken之后,如果调度中心与executor内网通信,那么还不能使用accessToken在公网反弹executor机器,在控制台的任务列表看到注册机器地址后,如果是公网ip和端口,那么久可以利用accessToken去反弹shell。

通过工具检测后,不存在默认accessToken,无法直接使用工具反弹,但是我们上一步已经获取到了自定义的accessToken了,那么好说直接上硬菜”burpsuite“。

burpsuite的intruder和repeater都可以实现发送请求,这里使用intruder模块:

然后在payloads填入刚刚获取到的accessToken:

然后发起请求,就能反弹shell到另外一台测试机了,具体内容可参考另外一篇文章xxl-job默认accessToken绕过RCE

四、漏洞原理

看一下logDetailCat接口:

代码语言:javascript
代码运行次数:0
复制
@RequestMapping("/logDetailCat")
@ResponseBody
public ReturnT<LogResult> logDetailCat(String executorAddress, long triggerTime, long logId, int fromLineNum){
  try {
    ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(executorAddress);
    ReturnT<LogResult> logResult = executorBiz.log(new LogParam(triggerTime, logId, fromLineNum));
    //...省略...
    return logResult;
  } catch (Exception e) {
    return new ReturnT<LogResult>(ReturnT.FAIL_CODE, e.getMessage());
  }
}

原因在于executor的执行地址executorAddress是可以自定义传入的,然后通过XxlJobScheduler的getExecutorBiz方法包装成执行器客户端,并且把accessToken传了进去。

而调用执行器客户端log方法查询日志的时候会把accessToken明文带过去,并且致命的时候并不会校验address的合法性:

代码语言:javascript
代码运行次数:0
复制
public ReturnT<LogResult> log(LogParam logParam) {
    return XxlJobRemotingUtil.postBody(this.addressUrl + "log", this.accessToken, this.timeout, logParam, LogResult.class);
}

这也就出现前边所说的使用python启动的http服务模拟executor,能够收到调度中心的请求,并且从header中取到了accessToken了。

五、新版本漏洞真的修复了吗?

开篇有介绍2.4.0版本修复了CVE-2022-43183 SSRF漏洞,但是真的修复了吗?

我们先看一下2.4.0与2.3.1的修复SSRF漏洞的核心变更:

从代码来看,2.4.0版本logDetailCat接口入参删掉了executorAddress和triggerTime,也就是说不再允许自定义executorAddress,任务执行器地址从有效的日志中来获取,从而解决非法executorAddress导致的accessToken泄漏问题。

xxl-job控制台有相当比例存在默认密码以及弱口令密码,或者说比较简单的密码策略,假如通过默认密码或者工具爆破,拿到了admin或者其他管理账号密码,我们还能拿到accessToken吗?答案是可以的。

为了验证我们直接用2.4.2版本。前边的拿到管理员账密步骤跳过。

然后还是用python启动一个http服务模拟executor,并监听8080端口:

代码语言:javascript
代码运行次数:0
复制
python3 server.py

然后在xxl-job控制台创建任务执行器,注册方式选择手动注册,这样方便我们模拟executor,并且能够让调度中心能够向我们的executor发送请求:

然后选择刚创建的任务执行器创建任务:

创建好任务后,点击执行,手动触发任务:

然后到python启动的http服务看日志输出:

那我请问,这个SSRF漏洞修复了吗?我甚至有点混乱~

六、accessToken滥用是原罪

其实个人认为,上述这些问题的原因在于网络参与者识别对方身份时,不同的场景策略选择问题,accessToken本身没有错,举一个例子,A和B之间有接口调用,约定了token为xxxxxx,那么这个简单场景没问题,A发起的时候带上token,请求到B的时候,B验证token的合法性来识别调用的有效性。

那么针对于xxl-job调度中心和执行器交互的场景,不管合不合理,我提几个假设:

  • 如果不能添加执行器,还有没有问题,也就是执行器提前预设好的,甭管怎么预设
  • 任务注册不管是自动还是手动,关闭公网ip注册
  • 任务注册到调度中心的ip,受调度中心管控,类似白名单或者ip池的东西
  • 调度中心向执行器发请求,必须是受可信ip白名单或者ip池管控

也许按照这些中的某些观点改造之后,安全性会有所提升。

另外站在accessToken的角度再做思考:

  • 如果accessToken换一种身份,叫做对称加密的秘钥,由调度中心和执行器提前约定好,做本地化存储,不在网络传输,通过accessToken秘钥身份解析双方请求的合法性,结合内网、白名单之类的辅助能力,是不是解决了accessToken传输中泄漏的问题。
  • 干脆就不用accessToken了,调度中心与执行器之间通过内网交互,做好白名单和端口限制,是不是也能解决问题。

以上仅代表个人观点,看官还需自行斟酌~

七、解决方案

1.升级到安全版本

升级到相对较新的,暂时没有发现漏洞的版本。比如现在可以升级到2.4.2版本。

2.升级控制台密码策略

控制台搭建好的第一件事,把admin的密码改掉,使用复杂的密码策略。

如果密码很简单,那么很容易被爆破,并且现在有很多开源的弱口令密码字典,不要存在侥幸心理。

3.内网交互

内网交互天然多一层安全保证,对于xxl-job来说,我个人认为只需要把控制台访问的http端口暴露即可,调度中心与执行器之间交互,比如任务注册、任务执行完全可以通过内网通信来做。

4.关闭公网回调端口

这一条和第3条有点像,xxl-job执行器默认暴露端口9999,有些小可爱直接把端口暴露到公网,通过网络搜索引擎,通过关键词加端口,一搜一大推,可以单个甚至批量渗透,对于这种敏感的业务端口非必要就关闭公网暴露。

5.ip相互加白

如果有条件,可以考虑针对xxl-job二开或者功能扩展,实现相互加白的能力,增加一层防护能力。

6.accessToken增强

这里存在两层语义,一是也使用强密码自定义accessToken,另外一层语义是,直接改掉或者弃用accessToken,使用对称加密或者非对称加密的方式来实现调度中心与任务执行器交互。

参考

https://github.com/xuxueli/xxl-job

https://avd.aliyun.com/detail?id=AVD-2022-43183

https://www.xuxueli.com/xxl-job/#7.32%20%E7%89%88%E6%9C%AC%20v2.3.1%20Release%20Notes[2022-05-21]

https://github.com/xuxueli/xxl-job/commit/9293c61ca0a8d54afdfb27cc568885ae639a14dc#diff-d0eff4dddf92908520c5ce8a56f180b3915b25aabc9603192da02a3748aa8759

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PersistentCoder 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、漏洞概述
  • 二、关于SSRF
    • 1.SSRF漏洞概念
    • 2.SSRF漏洞原理
    • 3.xxl-job中的SSRF
  • 三、漏洞利用
    • 1.控制台搜索
    • 2.爆破控制台
    • 3.创建普通账号获取accessToken
    • 4.accessToken延伸利用
  • 四、漏洞原理
  • 五、新版本漏洞真的修复了吗?
  • 六、accessToken滥用是原罪
  • 七、解决方案
    • 1.升级到安全版本
    • 2.升级控制台密码策略
    • 3.内网交互
    • 4.关闭公网回调端口
    • 5.ip相互加白
    • 6.accessToken增强
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档