1.前言
在挖某家SRC的时候,通过域名历史解析找到一个IP,然后通过各种问题组合接管云控制台,最后告知打歪了,今天分享一波。有点标题党了,这个流程实际上也不是很难(
2.从druid入手
拿到了一个历史解析IP,扫一波全端口,可以看到还是有几个WEB资产,其中一个WEB资产爆druid未鉴权,一个则是index.zip泄露。还有一个GitLab,先测了一遍GitLab常见漏洞,未果。后续实测index.zip里面全是前端源码,没啥意义。那就只能看看druid了。
一般druid也就看看URI和Session两个地方,Session是空的,本来想研究一波URI接口有没有啥未鉴权问题,这里由于前期扫了一波目录,所以记载了很多乱七八糟的uri,对后续测试还造成了一点点干扰。
在对里面的接口uri进行测试的时候,我先是发现里面一些未鉴权接口使用fastjson来处理json传参
经典的删个花括号爆fastjson错误。那么具体是哪个版本呢?尝试调用一些经典的payload进行探测,会发现禁止autoType的异常,那么就猜测是1.2.68以上,缩小一下payload探测范围,使用下面的payload进行报错探测
{@type":"java.lang.AutoCloseable"
果然是1.2.68,不高不低,一个最经典的利用方法就是打JDBC
成功收到外联,能跑通,那接下来好办了,可以把allowUrlInLocalInfile属性和allowLoadLocalInfile属性打开,从而进行可回显SSRF或者文件读取,当然直接打链子也是可以的,可以使用下面这个Mysql蜜罐辅助:
https://github.com/fnmsd/MySQL_Fake_Server
先读个passwd证明一下吧
由于是云资产,本来想触发SSRF读一下ram拿临时凭据的,结果压根没配置ram,那算了,读个hostname
然后由于7001端口开放了个gitlab,所以打算读一下gitlab root的默认密码,一个小知识,GitLab安装的时候会给root用户设置一个默认密码,其密码信息一般保存在这个文件里:
/etc/gitlab/initial_root_password
但是最后也没成功登上去,那还能怎么办呢?这里还是打打JDBC反序列化吧。
3.失败的反序列化,但最终拿下控制台
既然常规手法走不通,先打个URLDNS试试看吧
URLDNS链子能打通,接下来是gadget探测的问题,仙贝们fastjson gadget探测已经有过很多探索,也已经有了比较成熟的工具,例如
https://github.com/a1phaboy/FastjsonScan
等等,不过用这个工具没探测出gadget。
然后就想到,既然URLDNS链能用,其实可以改造URLDNS链去进行gadget探测,详情可以参考这篇文章:
https://mp.weixin.qq.com/s/KncxkSIZ7HVXZ0iNAX8xPA
也已经有实现好的工具了:
https://github.com/kezibei/Urldns
(Jyso好像也支持URLDNS探测gadget)
然后又遇到一个很尴尬的问题,上面这个罐子默认只对ysoserial做了适配,要适配其它工具的话还得改改这罐子的代码,作为一个脚本小子真是汗流浃背了。
然后根据目标的java环境试了几个可能的链子,没用,就很邪门,索性就放弃了。其实这里是猪脑过载了,后面拿下控制台之后才反应过来我是用fastjson问题进行利用的,而fastjson的toString()是可以和原生反序列化的BadAttributeValueExpException串起来的,虽然这里是较高版本的Fastjson,要面临一个resolveClass绕过的问题,不过理论上应该是能利用上的,参考
https://paper.seebug.org/2067/
总之,链子打不通,应该咋办呢,思来想去还是觉得能把源码脱下来就好了,因为发现有些接口能拿到和储存桶有关的信息,一些文件上传接口也和云有关,源码里应该是有AK/SK的硬编码的。
我通过读取目标机器上的/proc/self/environ,读取当前进程的环境信息,可以确认当前java进程的运行路径在/root/xxxxx/xxxxx_jar_new
之后还要确认jar包名称,这里思路就很多了,看history,寻找一些.sh文件(一般开发者喜欢写个.sh文件来运行或关闭jar)等等。不过这些我都没搞,很简单,druid作为一个监控状态的组件,其实把classpath信息已经给出来了
这样就拿到了jar包名字,在实战中如果师傅们遇到java站点的文件读取、下载问题,并且用常规读取路径难以确定jar包名称的话,可以尝试从druid里再搜集一些信息(前提是有)。也可以试试我之前提到的小tricks,也即文件下载、读取与目录遍历伴生出现的问题。
总之,最后可以用mysql蜜罐下载
/root/xxxxx/xxxxx_jar_new/xxxxx.jar
由于这玩意太大,直接504了。不过这个蜜罐确实强大,作者说测试了50MB的数据没问题,我想现在打包成jar的javaweb应用动辄100MB以上,真能顺利下载下来吗,结果最后也是成功下载下来了,差不多150MB,很强悍
进来之后也是先看看漏洞成因,某个控制器由于涉及鉴权,恰好是拦截器的漏网之鱼,而这个控制器里的某个方法又恰好接受JSONObject类型的RequestBody,又恰好使用了fastjson 1.2.68这个卡在中间的版本处理json,所以被我们拿下了。
再看看配置文件能不能找到我们梦寐以求的AK/SK呢?
有AK/SK,那么权限几何呢?脚本小子掏出CF试试一把梭。
直接也是最高权限,直接接管控制台
4.结语
奇思妙想很多,不过最后还是简单粗暴的拖源码拿AK/SK结束战斗。主要是对fastjson 1.2.68打JDBC相关问题的利用吧。此外GitLab初始密码位置、druid中的某些信息这类细枝末节的信息,虽然在本次攻击流程中不一定发挥了作用,但是说不定哪天就能用得上了,还是可以积累一下的。
原文始发于微信公众号(HW专项行动小组):从druid一路杀到云控制台