Shiro中间件介绍
官网介绍
Apache Shiro™是一个强大且易用的Java安全框架,能够用于身份验证、授权、加密和会话管理。Shiro拥有易于理解的API,您可以快速、轻松地获得任何应用程序——从最小的移动应用程序到最大的网络和企业应用程序。
现在网站常将Shiro中间件用于用户权限鉴定,如果Shiro中间件出现漏洞,网站也因此会受到影响。
CVE-2016-4437分析
描述:该CVE漏洞是Shiro中间件的反序列化漏洞,通过该漏洞可以让攻击者远程执行命令。
影响版本:Apache Shiro <= 1.2.4
环境搭建
IDEA + XAMPP
git clone https://github.com/apache/shiro.git
cd shiro
git checkout shiro-root-1.2.4
1. 在shiromgtAbstractRememberMeManager.class的onSuccessfulLogin方法打断点,启动debug模式并在浏览器内登录,勾选remember选项。开启burp suite抓包。
按f7进入该方法的this.rememberIdentity语句中,该方法是获取请求中的用户名然后验证rememberMe字段。
进入this.rememberIdentity方法,
this.convertPrincipalsToBytes语句是将获取到的用户身份通过某种算法转换为字节码赋值给bytes变量,进入该方法,该方法先把身份序列化,然后进入加密方法encrypt内加密。
进入encrypt查看代码。
该代码获取序列化后的数据,通过this.getCipherService获取加密方法,从调试界面知道加密算法为AES加密,模式为CBC,填充方式为:PKCS5.
进入ByteSource byteSource
=cipherService.encrypt(serialized,this.getEncryptionCipherKey());语句中,该语句获取序列化后的数据和通过this.getEncryptionCipherKey()方法获取的加密密钥然后通过算法加密,从this.getEncryptionCipherKey()可以得到硬编码的密钥。
回到rememberIdentity方法中,进入this.
rememberSerializedIdentity(subject, bytes)语句内,分析代码逻辑。
可以知道,该代码将序列化后的数据进行base64转换后设置到cookie中,即浏览器内的rememberMe cookie字段。
流程梳理
登录成功后,后端获取用户名 => 序列化用户名 => AES加密密钥已知 => base64转换 => 设置到cookie内。
2. 解密过程分析
在org.apache.shiro.mgt.DefaultSecurityManager#getRememberedIdentity打断点,开启调试模式,跟踪该方法。
跟进getRememberedPrincipals函数进入byte[] bytes = this.getRememberedSerializedIdentity(subjectContext)语句,该代码是获取cookie值进行base64解码后返回。
回到getRememberedPrincipals,进入principals = this.convertBytesToPrincipals(bytes, subjectContext)分析代码逻辑,进入解密方法内
decrypt方法进行AES解密,同时由调试信息可以知道,解密方法为AES,模式为CBC,填充方式为PKCS5,同时解密密钥也可以由getDecryptionCipherKey()方法获得即
获取cookie => base64解码 => AES解密密钥已知。
3. 利用方式
由于加密解密密钥已知,且在这个过程中存在序列化和反序列化,所以可以控制客户端的序列化数据,在服务端进行反序列化的时候,重写readObject方法,执行恶意代码。
浏览器在正常给服务器发送请求携带的cookie还有前面的JSESSIONID,长度为32,在利用该漏洞的时候,生成的cookie的rememberme字段除了构造的序列化值之外还需要填充16个比特iv,根据shiro的rememberme生成原理,构造脚本,先利用ysoserial-master-30099844c6-1.jar生成测试
脚本地址:https://paste.ubuntu.com/p/T5DNQXYm7H/
poc脚本原理:先利用ysoserial生成序列化恶意payload,然后将payload用AES算法加密,加密密钥为之前获取的,模式为CBC,填充为随机16byte的数据,然后将填充和加密后的payload进行base64编码,发送request请求,携带rememberMe的cookie字段,服务器接受数据报之后进行base64解码=>AES解密=>反序列化,从而完成攻击,服务器会对指定DNS服务器发起dns请求。
原文始发于微信公众号(闲聊趣说):shiro框架的CVE-2016-4437分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论