一、前言
我们在实战渗透过程中,尤其是国内,遇到很多Java语言编写的站点居多,同时这里会存在很多Java漏洞场景。
例如在Shiro 550中,以Java反序列化点为漏洞入口起点,使用 CommonsBeanutils 反序列化链,并通过 TemplatesImpl 类去加载任意字节码,这里我们通过字节码可以实现各种操作,例如通过 Sleep 判断漏洞是否存在、通过 Dnslog 判断dns是否出网、通过回显用来辅助判断环境、甚至是注入 Godzilla内存马。
再例如前段时间爆出的帆软的链,也是一个Java反序列化入口点,通过 DruidXADataSource 类去转为 JDBC URL Attack 利用,最常见的JDBC Attack 就是H2 jdbc去执行 js,不过在帆软环境内使用的是 hsqldb 的JDBC 利用,可转为二次反序列化绕黑名单实现RCE。
漏洞场景中不止常规的 Java 反序列化点,还有JNDI注入。众所周知,JNDI的利用可以简单分为三种方式:字节码加载、反序列化、Reference(ObjectFactory)利用。前两个不用多说,第三个利用方式中最常见的是通过 Tomcat EL 表达式实现加载字节码RCE。
从以上例子我们发现,有很多点都是重复的,比如反序列化链、字节码等。
二、想法
我们可以将上面的各种利用拆分并简单抽象为一个个可复用的小组件。例如将 CommonsBeanutils 链的前半段、TemplatesImpl 对象、Sleep 字节码、回显字节码、注马字节码作为一个个 Gadget,供我们选择组装并生成,这个过程就是在组装一条利用链⛓️一样。
很明显,这样做的好处是方便拓展,如果将来发现了一条新的链,假如这个链同样可以通过 TemplateImpl 去加载字节码,这样就不用写重复的TemplatesImpl相关逻辑,把新链的一部分抽离出来集成进来就可以了。
其实这样的拆分也不是什么新鲜想法,在一些公开的工具已经应用了起来,例如ysomap 和 PPPYSO。
笔者以往使用ysomap较多,以它为例,ysomap将链拆分成为了两部分:Payload 和 Bullet,很大程度上拓展了链子的使用灵活性,例如CC链、CB链等链可加载同一个 TemplatesImpl (Bullet)、也可以加载同样的 Transformer 相关链。
不过在一些实战场景,经常需要使用反序列化去加载各种字节码,ysomap 显然考虑到了这样需求,提供了自定义加载字节码选项,不过配合命令行在实际使用起来稍显繁琐。
基于以上种种,我们需要一个更加统一的工具,去提供各种 Java Payload,以便适用于各种场景,实现 Payload 「一次编写,到处应用」。
三、框架设计
有两个概念:Payload和Gadget:
Payload 作为一种对 Gadget 链最终结果的封装,例如有JavaNativePayload(Java序列化)、HessianPayload,都是对 Gadget 链进行序列化操作
Gadget 就是一个个的 Java Object 对象,就像ysomap中的 bullet 那样
例如将 CommonsBeanutils 整个链中涉及到调用getter的前半部分拿出来,再把后半段的TemplatesImpl作为被getter调用的链也单独拿出来,最后加载的字节码也单独拿出来,拆成三部分,为什么把 TemplatesImpl 也拆出来?因为 TemplatesImpl 链仅是 getter 链的一个子集,还有二次反序列化,JDBC等利用链。
我们还需要规定 Gadget 之间的衔接规则,如果不这么限制的话,后面 Gadget 数量多了起来,要想凑个能用的链简直是大海捞针。
笔者的想法给 Gadget 进行贴标签,每个 Gadget 有三种标签:当前标签(Tags)、下个标签(NextTags)、排除标签(Excludes)。链子之间使用标签进行衔接,Payload 为起点,Gadget END 标签为终点,整个组装就像一个单向链表数据结构,CB链的组装如下图所示:
使用标签的好处是方便拓展,例如想要新增一个字节码利用,只要贴上字节码的标签,就可以快速到融入框架中,在调用字节码的时候就会将它显示出来。
对应到 web-chains 的前端,这里用到了级联选择器,选择到最终的 Node 节点就代表组装为一个完整的链:
另外可以给 Payload、Gadget 设置各种参数,比如可以在Java原生反序列化中同时提供各种混淆:
比如在字节码中,提供各种字节码格式支持,有些选项会通过链的上下文自动设置:TemplatesImpl 链中字节码需要继承 AbstractTranslet 类的,当选择了 TemplatesImpl 链就会自动处理字节码。
四、代价
这个工具提供了较高的自由度,那么代价是什么呢?我们回顾以往的反序列化链,经常由于链子中某一环的特殊性,会导致某个 Gadget 无法使用,这样生成的链无法正常执行。例如在 Hessian 反序列化中,因为不走 readObject 函数,导致无法还原TemplatesImpl 中的 _tfactory 字段,也就无法正常使用 TemplatesImpl Gadget。同样是通过 getter 方法触发 UnixPrintService 链实现命令注入,但是由于 UnixPrintService 类是没有实现 Serializable 接口的,所以只适用于 Hessian 等反序列化,无法用于 Java 原生反序列化中。
还有很多其他差异导致组合出来的链无法正常执行的情况。
为了减少使用时的心智负担,同时不想失去工具的灵活性,这里有一种简单方法来提示这种情况:上面提到的Gadget 排除标签 (Excludes) 派上了用场,如果链中任意一个Gadget存在这个标签就代表有一些问题,会给 Gadget 进行标记,到时候根据实际情况自行判断即可:
这里不会完全禁止生成,因为还是有可能出现一些例外情况,比如 Hessian 二次反序列化中,是可以正常使用 TemplatesImpl 链子的,所以不能一杆子打死。
五、常用 Payload 生成
简单举几个例子,例如 FindClass 探测类,从柯师傅的 https://github.com/kezibei/Urldns 搜集了一些常用类:
Jeg 回显:内置并调用 https://github.com/pen4uin/java-echo-generator 生成回显字节码
还有一些 ShiroPayload、HessianPayload、AMF Payload、宝蓝德Payload 等等生成,这里不举例了,关注公众号可以获取URL自行体验。
六、JNDI的利用
有了生成模块作为基座,兼容其他利用就很简单了,只需要小小的「对接」即可:把生成出来的 Payload 装填到其他工具中,例如 JNDIExploit:
基本上把浅蓝文章和https://github.com/X1r0z/JNDIMap 里的姿势都搬了过来,这个 JNDIMap 是我看到最全的JNDI利用工具,推荐一波。
得益于Web平台的操作逻辑,可以不通过传参来进行控制 Payload 生成。写代码时突发奇想,甚至可以不需要任何参数传入,代码中只要有这样的逻辑,没有匹配上 token 就返回默认最新生成的 Payload:
JndiData data = jndiDataMap.get(key);
// 如果没有搜索到,使用默认的 data,即最新放置的jndiPayload
if (data == null) {
data = jndiDataMap.get(DEFAULT_KEY);
}
这样就可以实现很强的兼容性,只要目标能发起ldap请求就能实现利用,例如只需要请求 ldap://vps_ip:12345/x 即可。
提一嘴,这里的Reference对象还可以被c3p0的
某个链复用。
七、Fake Mysql
基于许少的fake mysql小改一下:
https://github.com/4ra1n/mysql-fake-server
其实和上面的JNDI逻辑差不多,也很好集成。
八、RMI 相关利用
https://github.com/qtc-de/remote-method-guesser 是一个优秀的RMI漏洞利用工具,也是简单魔改一下,将里面的 ysoserial 替换为 cli-chains(命令行版),提供更多的 Paylaoad 支持(站在巨人的肩膀上
使用 CC 链攻击 Registry 端:
使用 JRMPClient 链配合 JRMPListener:
当然1,为了方便命令行中参数的使用,减少心智负担,web chains 选中参数后会通过前端自动生成一些参数,点击进行复制
当然2,为了避免了特殊符号导致的奇奇怪怪的解析问题,这里的参数值会自动判断并进行Base64编码,完全避免了特殊字符导致的解析问题,缺点就是参数会有亿点点长。
九、Tcp Server
Tcp Server 简单来说就是启一个 Tcp 端口,无论请求什么,都会响应指定字节流。
例如 Derby Slave 反序列化利用:
十、Http Server
将生成的字节流/字符串 Payload 挂载到 HttpServer 上,适用于挂载字节码、spring bean.xml 等场景。
例如 PostgreSQL JDBC等利用:
十一、总结
本文介绍了 Java Payload 生成框架的设计思路,并且对接到 JNDI、Fake Mysql、JRMP 等Exploit模块中,最终实现 Payload 一次编写,到处应用。
目前公开 Payload 生成模块供大家使用,欢迎反馈建议和想法
关注公众号后回复: web-chains 即可获取 URL 链接
大哥们只要别 DOS 就行,如果能日下来可以跟我深入交流一下 祝大哥们国庆快乐
反序列化链参考:
https://github.com/mbechler/marshalsec
https://github.com/frohoff/ysoserial
原文始发于微信公众号(探索笔迹):Java Payload 生成框架的设计与实现