shiro反序列化漏洞复现
vulhub靶场复现
漏洞原理
Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会生成经过加密并编码的cookie。在服务端对rememberMe的cookie值,先base64解码然后AES解密再反序列化,就导致了反序列化RCE漏洞。 那么,Payload产生的过程: 命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值 在整个漏洞利用过程中,比较重要的是AES加密的密钥,如果没有修改默认的密钥那么就很容易就知道密钥了,Payload构造起来也是十分的简单。
这是一个典型的 Shiro RememberMe 反序列化漏洞的触发路径。用大白话解释就是:
场景比喻
想象你进了一家高级会所,前台给你一张加密的会员卡(RememberMe Cookie),下次来不用输密码,直接刷卡进。但这家会所的会员卡加密方式有问题——用的是一把通用钥匙(默认密钥),导致坏人能伪造任意会员卡。
流程拆解
- 登录成功:
你输入账号密码正确,前台(Shiro)说:“记住这个用户,下次直接刷会员卡进!”
→ 触发onSuccessfulLogin
方法。 - 制作会员卡:
前台把你的信息(用户名、权限)打包成快递(序列化),用会所统一包装盒(加密)封好,再贴个快递单(Base64编码)。
→ 调用rememberIdentity
→rememberSerializedIdentity
。 - 快递配送:
前台把包装好的快递(加密后的数据)塞进你的浏览器,变成一张会员卡(Cookie)。
→ 设置Cookie值rememberMe=加密后的Base64字符串
。 - 漏洞在哪:
- 通用钥匙:所有会员卡都用同一把钥匙加密(Shiro默认硬编码密钥)。
- 包装盒可破解:序列化数据用的是可预测的加密方式(AES-CBC)。
→ 坏人拿到你的会员卡,拆开包装盒,换上自己的毒包裹(恶意代码),再用原样封好,系统会正常解密执行。
1.首先正常登录,然后生成带有rememberme的返回cookie值。 2.生成cookie,shiro会提供rememberme功能,可以通过cookie记录登录用户,从而记录登录用户的身份认证信息,即下次无需登录即可访问。处理rememberme的cookie的类为org.apache.shiro.web.mgt.CookieRememberMeManager 3.之后进入serialize,对登录认证信息进行序列化 4.然后加密,调用aes算法。 5.加密结束,然后在在org/apache/shiro/web/mgt/CookieRememberMeManager.java的rememberSerializedIdentity方法中进行base64编码,并通过response返回 6.解析cookie 7.先解密在反序列化 8.AES是对称加密,加解密密钥都是相同的,并且shiro都是将密钥硬编码 9.调用crypt方法利用密文,key,iv进行解密,解密完成后进入反序列化,看上面的public AbstractRememberMeManager这里用的是默认反序列化类,然后触发生成反序列化 |
生成带有Rememberme的返回cookie->处理rememberme的cookie的类为org.apache.shiro.web.mgt.CookieRememberMeManager->序列化登录信息->交给aes进行加密->加密后org/apache/shiro/web/mgt/CookieRememberMeManager.java的rememberSerializedIdentity进行base64编码->解析cookie->先解密在反序列化
判断AES密钥
密钥不正确或类型转换异常时,目标Response包含Set-Cookie:rememberMe=deleteMe字段, |
工具:https://github.com/feihong-cs/ShiroExploit-Deprecated/releases
shrio-550使用的是默认密钥kPH+blxk5D2deZilxcaaaA==
工具非常给力可以获得密钥
这就不去复现了
[Shiro-认证绕过漏洞(CVE-2020-1957)]
核心点就是
场景设定:
- 门卫(Shiro):负责检查每个客人能不能进VIP室,规则是”所有想进
/vip
房间的人必须出示会员卡”。 - 管家(Spring):负责带客人去实际房间,但它有个怪癖——看到分号
;
就会自动截断后面的内容。
- 门卫(Shiro):负责检查每个客人能不能进VIP室,规则是”所有想进
坏人如何混进VIP室:
坏人不去正门/vip
,而是故意走歪路:- 构造假路径:
/vip;/../秘密通道
- 门卫视角:检查路径是
/vip
(因为Shiro看到分号;
就停下),发现规则是允许所有人访问/vip
(未配置需要登录),直接放行。 - 管家视角:处理路径时,看到分号
;
就截断成/vip
,实际却把客人带到/秘密通道
(VIP室后门)。
→ 门卫以为你去的是公开区域,管家却把你带进了VIP室,全程没查会员卡!
- 构造假路径:
这个文章写的也很好https://www.cnblogs.com/dhan/p/18423713
这个文章主流payload是
/xxx/..;/admin/ |
首先shiro处理的
将分号后面的内容直接处理了得到xxx/..,显示不是要去/admin可以直接bypass掉了shiro认证
spring认证
跟进removeSemicolonContentInternal(requestUri)方法,他的作用就是:移除uri中/与/之间的;分号以及;分号后面的内容
根据这句话可以得知最后的uri应该是:
/xxx/../admin/ == /admin/