看到了微步的漏洞预警信息,于是想从零开始记录一下 nday 漏洞的复现过程。虽然这次涉及代码审计很少,但也算一个路径,就记录一下吧。
首先看预警信息
首先提取关键词:accessToken 默认、在 application.properties 中配置、绕过认证调用 executor
接下来我们去 xxl-job 的官方仓库找这个文件
该文件有多个但内容一致,这里选择 xxl-job-admin 下的为例。我们能看到 application.properties 中 accessToken 确实有个配置项,其值就为 default_token。因为 properties 是个纯静态文件,所以不存在什么语法变量,确定就是这几个字符 “default_token”
好,现在我们确定了 accessToken 的值,这将是我们构造 payload 的关键。接下来我们要弄清楚通过这个值可以绕过什么。也就是预警信息中所说的 executor
查看项目目录,发现了一个相似的文件夹
点开看里面
又有两个,而且里面出现了 frameless 和 springboot,推测是两个版本或者编译方式。
这里不敢继续深入,不了解话可能会变成无底洞让我钻进牛角尖。那么回到最开始,看一看官方文档,看看从里面能发现什么信息便于我们了解软件架构。
通过文档我们可以知道 xxl-job 其实是分为两部分是类似于 docker 的那种 c/s 结构,或者说类似于中台 /agent 架构。调度中心(默认端口 8080)就是 xxl-job-admin,而执行器(默认端口 9999)则就是所谓的 executor。执行器接收调度中心发出的命令,在所在机器上执行后并返回结果。而接收上级指令一定有一个身份验证来保证不被滥用,这个验证就是 accessToken。
那么现在我们大致就理清漏洞的利用思路了,很简单就是构造一个调度中心的指令请求给执行器,当 accessToken 为默认时我们就可以冒用身份把执行器作为我们的木马去使用。那这个请求的格式是什么样的呢?最开始我从代码层面可是跟踪,但往深处太复杂就换个方向从互联网入手。搜索关键词:xxl-job executor rce,这时找到了一个很久以前的漏洞
点进去看,时同一个组建相同的问题。我们现在这个是默认值,这个洞则是空值。看下时间,最早 2022 年就有人复现分析了。那么他的 payload 我们能不能用呢?
很显然里面并没有提到 accessToken 这个字段,估计是因为空值的话根本不用传参。但是我们得到了另一个信息,组建之间通过 RESTful API 传送数据,那么这个字段格式在文档中就也一定有。回到文档去看
好了,可以直接根据文档去构造请求包了。(glueType 字段还有别的类型自行摸索,可能会对 bypass 有利)
文章中的指纹我们也可以直接拿来用
即: shodan request, HttpMethod not support.
也就是 body 内容为 invalid request, HttpMethod not support.
其他国产引擎语法请自行构造
接下来找个目标试试
成功执行命令并通过 dnslog 带出
如果默认值改了,则是这样
总的来说就是这样。但有些时候你会发现服务器的执行器打不了。这是因为 c/s 架构,agent 不一定就非得在 admin 的那个机器上。这虽然降低了利用成功率,但某种意义上对内网横向起到了一定作用。
最后一个小彩蛋:
2022 年执行器未授权漏洞之后官方做了补救措施,默认开始 token。但他们却使用了一个固定的值进行硬编码。也就是这个修复开启了执行器绕过。正所谓,修了吗?如修
不知道为什么这么简单的一个漏洞竟然过了一年才爆出来
最后的话:虽然这次没有从代码审计的角度深入解析,但指出了另一条路,要善用网络搜索和已知漏洞,这往往也是一个捷径