目录
0x01 漏洞复现目标
记录可利用版本或版本范围、如何识别或者判断某个数据包使用了java shiro组件、漏洞原理、验证poc 、exp、利用过程、需要的工具等。
0x02 漏洞可利用版本
Apache Shiro <= 1.2.4(CVE漏洞利用版本建议去官网查看
CVE -Home)
0x03 漏洞修复
1.确定自己使用的shiro版本要高于1.2.4;
2.在代码中全局搜索 "setCipherKey(Base64.decode(" 关键字,或者"setCipherKey"方法,Base64.decode()中的字符串就是shiro的密钥,要确保该密钥的安全性,千万不要使用公开的密钥。
0x04 漏洞原理
1.Apache Shiro默认使用了CookieRememberMeManager,其处理Cookie的流程:得到rememberMe的Cookie值→Base64解码→AES解密→反序列化。然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。
2.关键因素:AES的加密密钥在Shiro的1.2.4之前版本中使用的是硬编码:kPH+bIxk5D2deZiIxcaaaA==
,只要找到密钥后就可以通过构造恶意的序列化对象进行编码,加密,然后作为Cookie加密发送,服务端接收后会解密并触发反序列化漏洞。在1.2.4之后,ASE秘钥就不为默认了,需要获取到Key才可以进行渗透。
0x05 漏洞特征
shiro反序列化的特征:在返回包的 Set-Cookie 中存在 rememberMe=deleteMe 字段
0x06 反序列化漏洞常见的魔术方法
魔术方法(Magic Method)就是指所有以__(两个下划线)开头的类的方法。在某些条件下自动执行会导致反序列化漏洞。Java反序列化漏洞通常涉及到以下魔术方法::
readObject():Java的序列化机制在反序列化对象时会自动调用这个方法,用于读取对象字节流并重新构造对象。攻击者可以通过恶意构造的序列化数据来执行任意代码。
readResolve():这个方法在反序列化过程中也会被自动调用,用于返回一个代表被反序列化对象的替代对象。攻击者可以通过在这个方法中返回恶意对象来执行任意代码。
writeObject():这个方法与readObject()相对应,用于将对象转换为字节流进行序列化。攻击者可以在这个方法中插入恶意代码并进行操作。
readExternal():这个方法与readObject()类似,用于反序列化对象,但是它是在实现Externalizable接口时调用的。攻击者可以通过恶意构造的序列化数据来执行任意代码。
需要注意的是,这些魔术方法通常是在恶意构造的序列化数据中被调用的,因此在处理序列化数据时需要进行充分的输入验证和安全措施,以防止攻击者利用这些方法执行恶意代码。
0x07 漏洞复现工具利用
工具(shiro反序列化漏洞综合利用工具)网址:https://github.com/j1anFen/shiro_attack
0x08 漏洞复现过程
1.首先启动靶场环境,靶场环境启动成功后访问访问http://ip:8080/
2.检测是否存在漏洞,爆破秘钥
3.爆破利用链及回显
4.命令执行
5.注入内存马
6.使用哥斯拉利用内存马
0x09 如何发现shiro反序列化漏洞
1.漏洞特征:Shiro反序列化漏洞存在特征,在返回包的Set-Cookie中存在rememberMe=deleteMe 字段。
2.漏洞特征验证
设置代理,随便输入账号密码,使用burp抓取请求包,在返回包中set_cookie中存在rememberMe=deleteMe特征
如果直接发送数据包,返回包不存在特征:Set-Cookie: rememberMe=deleteMe;
可以在请求包中的cookie中添加:rememberMe=deleteMe;
然后查看返回包中是否存在特征:Set-Cookie: rememberMe=deleteMe;
0x10 判断网站是否使用shiro
-
找到网站登录的地方,随便输入账号密码抓包(一定要输入点击登录),看返回包是否有remembeMe字段
-
如果以上有返回remembeMe字段还可以尝试在请求包中的cookie中加入 rememberMe=1 ,来查看返回包是否有rememberMe=deleteMe字段。如果cookie字段有值则先清空
如我们直接访问登录的页面不进行登录,此时返回的数据包是没有remember字段的
这时,我们手动加上一个cookie:rememberMe=1,注意cookie要放在Upgrade的上面,则返回了remember字段。说明使用了shiro框架