让你的php网站拥有shiro
前言
很久很久以前freebuf发过一篇通过shiro反序列化拿下php网站的文章后,我大受震撼,震撼到今天。
我今天花了一下午摸鱼做这个实验。实验非常简单,也就是我们如何让php网站收到shiro探测的请求后让工具或脚本认为这是一个有shiro框架的网站?如何收到密钥爆破检测请求的时候,通过请求的字段值来与后端密钥做匹配,更加逼真的还原密钥爆破的场景,从而让脚本小子继续误入歧途?
Shiro框架指纹
shiro常见的指纹是通过请求包设置cookie中一个值为RememberMe=xxx,返回到有相应的Set-Cookie: rememberMe=deleteMe。这是最常见的指纹了,我们的目的是防御,而不是攻击,所以设置一个最常见的即可。
这里我拿j1anfen师傅的shiro测试工具来测试。通过原理,我们可以自己给网站base文件或者中间件写这样的代码(这里以及下文都是以php网站为例)
php用$_COOKIE函数取值会使+号变成空格,这里通过headers遍历重新取值可以解决这个问题。于是我们用j1anfen师傅的工具探测一下
发现已经可以让大多数工具认为我的网站是shiro框架了,但这还太简陋了。
Shiro框架密钥爆破原理
我们能不能更逼真点呢?
比如说我php网站后台指定一个密钥,你爆破密钥的时候必须和我php后台配置的密钥一致,再设置相应的回显?
https://mp.weixin.qq.com/s/do88_4Td1CSeKLmFqhGCuQ
现在非常多的工具都是构造一个继承 PrincipalCollection 的序列化对象,key正确情况下不返回 deleteMe ,key错误情况下返回 deleteMe 的方式来判断key是否正确。
那么,当我们取值取到一个由密钥kPH+bIxk5D2deZiIxcaaaA==加密而来探测的rememberme,我们后端配置的密钥也是kPH+bIxk5D2deZiIxcaaaA==,我们应该怎么做呢?
首先,老版本的shiro是aes-cbc加密,padding是Pkcs7。上面key探测的方法用到了反序列化,那么解密出来的数据一定会存在反序列化的特征
aced0005
所以我们可以给后台写一下php对于aes-cbc pkcs7的解密,一开始我对aes的加密不是很熟悉。因为cbc模式下是有偏移量的,但我们并没有偏移量,让我困惑了很久为什么一个密钥就可以进行反序列化。
还是万能的小何和我说的
所以思路就很明确了:
php网站收到请求中的rememberme字段值
后台存在一个我们假定的key,并使用aes-cbc解密,如果密钥匹配正确,那么解密出来的hex字符串的32-40位的字符串应该是aced0005。
如果解密出来的数据是aced0005,那么我们就不设置deleteme的头部字段。
其他情况下如果存在rememberme的请求cookie,就设置。
解密脚本如下
上面的pkcs7unpadding用不用结果都会有特征,去掉也行。
最终效果如下
成果
由于本人技术水平有限,一下午只能研究这么多了。后续伪造利用链,伪造回显可以继续深入研究,该继续挖漏洞了。
更新,已经初步实现这样的效果:
光是aes解密那个部分就想了很久,一开始用的是nginx来直接配置shiro相关特征,发现我并不太行,我太菜了。
如果还有其他的伪造,其实可以用伪静态设置后缀为jsp,亦或者修改phpsession,改成jsessionid。
如有错误,请指正轻喷。
^^