在日常工作中,遇见奇葩环境之shiro 反序列化漏洞
#1 背景描述
1.不出网!
2.没有传统的web目录,不能echo到某系统下
3.header头限制大小
4.liqun的利用链小,能简单执行命令,但是不能写内存马,其他工具利用链不能判断,
5.不能echo上马,不能像传统环境,此为spring框架,没有传统的jsp目录
#正文开始
有正确的shirokey,获取方式,是某某泄漏找到的。用liqun已确认存在反序列化漏洞。

但是用shiroattack不能找到利用链 😅

抓包分析,分析原因,将流量代理到Burp,发现检查利用链的时候,发现是400错误:

可以发现是HTTP头中rememberMe的数据太大,后端根本就没有处理到rememberMe里面的反序列化数据。
发现了问题,就得解决问题

#解决思路
1、 优化减少rememberMe头中SpringEcho模版的代码
2、 通过反序列化修改后端的header buff size (网上方案,感觉稍微复杂,而且网上分析都是基于tomcat的,与实际场景存在差异)
从代码和抓包看,其实ShiroAttack2自身已经对Header头限制进行了绕过,包括内存马注入这些都是有分离处理。

大部分tomcat环境配置环境对header头限制大概为8k。但是遇到这个目标环境对header头限制的更小,大概只有2-4k左右,payload超过就会报错。
所以导致shiro attack2无法成功反序列话rememberMe中携带数据
好了,开始解决,思路
项目:
修改https://github.com/SummerSec/ShiroAttack2
所以我们要的处理思路,就是缩短ShiroAttack2中 rememberMe加密后header头部分
看工具怎么解决
1、 解决命令执行问题,发现ShiroAttack2 SpringEcho的类本身就比较短:
直接看代码,在: com.summersec.attack.deser.echo.SpringEcho.java中
原来代码:

思路就是缩短长度!!!!!!

我们可以通过缩短变量名称,去除不必要语句,来缩短Header头的长度,利群工具的SpringEcho肯定比这个代码量少一些:
由于已经知道os为linux系统,所以我直接把原来的
String[] cmd = System.getProperty(\"os.name\").toLowerCase().contains(\"windows\")
逻辑去掉了,然后重命名了一些变量名


然后运行程序

成功找到key!!

运行命令成功,但是还达不到我们的目录,目标上马
注入内存马,也是因为请求Header头被限制,无法注入:
然后我们看shiro attack2项目关于内存马注入的部分:
类:com.summersec.attack.deser.plugins. InjectMemTool

别人的思路:
发现核心其实是,InjectMemTool类和getFV方法,然而这个作者已经写的很精简了,我们在怎么精简,也很难达到预期的长度。
想了半天,没缩减成功,选择了一个迂回的思路,其实分两步走,
1、先把内存马的paylaod部分放到服务器上(/data/mvc.txt)
2、然后重写InjectMemTool类,不通过请求解析来内存马body部分,直接从服务器上读取解析,打入内存马
这样就可以减少大量代码了:
重写后的核心,先用BufferedReader先把内存马数据读取,然后通过defineClass反射加载调用,在newInstacnce()创建对象后,自动完成添加内存马的逻辑。
因为不确定shiroAttack2 中内存马读取有没有进行特殊处理,改动比较大,所以我们可以选择JMG 工具来生成内存马:
https://github.com/pen4uin/java-memshell-generator-release
然后程序我们进行更改

将结果输出上传/data/mvc.txt,由于目标不出网,所以通过echo命令写入,还是长度限制,我们要把payload分割一下,多次执行:

最后通过shiroAttack2 将修改后的InjectMemTool打出去即可,执行注入:

最终当然是成功了!!!