一些很重要的灵光一现与概念性的东西集合
Drunkbaby Lv6

是也不是

关于 Java 反序列化的

关于 readObject

我们传进去的东西其实是已经被序列化的东西,比如在 Web 上面抓包,抓取的包是 json,这就是已经序列化了的代表。

当我们执行反序列化操作的时候会自动进行 readObject() 方法,所以我们反序列化的入口类要求是必须能够序列化,且里面重写了 readObject() 方法。

CC 链到底是干嘛的

CC 链实际上是利用链的一部分,但是 CC 链这里没有什么好的入口类,所以打不了,是要与一些其他的,比如 shiro 呀,fastjson 呀,结合起来打的。

一般链子的执行是如何实现的

  • 我自己在看 CC6 的复习的时候想到的这一点,到底是怎么实现的呢。

看了一段简单的代码,dubug 了很久之后终于很明白了。

先说反射,要讲反序列化漏洞,要从反射说起。

反射这里,我们看最简单的一段代码。

1
2
3
4
5
6
7
8
9
10
11
12
package src.ReflectDemo;  

import java.lang.reflect.Method;

public class ReflectionTest04 {
public static void main(String[] args) throws Exception{
Class c1 = Class.forName("src.ReflectDemo.Person");
Object m = c1.newInstance();
Method method = c1.getMethod("reflect");
method.invoke(m);
}
}

这样的,当我 debug 的时候:

c1 就是我们获取的类,m 就是实例化 c1,也就是 c1.Class

然后再获取 c1 中的方法,用 invoke 执行即可

那么在 CC6 链当中呢

这里没有实例化,我觉得有点奇怪,但是这里获取 method 方法,然后 invoke 执行是一样的!所以 CC6 之前那里!!!第二个参数总是为空!因为用不到!

这和构造函数有关!原来如此!因为它的构造函数是 public,所以可以直接 new!终于想明白了!但是不知道为啥不用实例化,后来知道获取私有类是不需要 newInstance() 的,而且这样会报错。

关于反射

真的是常看常新,要多写 EXP,不然容易忘记

要先实例化;反射可以获取到所有东西,绕过 private 的方式

1
2
3
Class clazz = Class.forName("xxx");
Object o = method.invoke(clazz);
method.invoke(o);

关于 Fastjson

首先是原理,很重要

设置 @type 的值,然后在反序列化的时候会自动去调用 [构造函数、getter、setter] 方法

如果这些被调用的方法满足这些条件,而且有对应的漏洞点,就可以命令执行

然后也是要结合链子的思维吧,确实牛逼。

  • 还有一个小点,要注意的。

其实我们在反序列化的时候是不能把 @type 的值设置为抽象类的,一定是要去调用它的实现类的,也就是子类;这样一来,在反序列化的时候其实我们写的 @type 是一个子类,但是会自动去调用它的父类。参照例子可以是 Fastjson 1.2.62

checkAutoType() 函数就是使用黑白名单的方式对反序列化的类型继续过滤,acceptList 为白名单(默认为空,可手动添加),denyList 为黑名单(默认不为空)。

默认情况下,autoTypeSupport 为 False,即先进行黑名单过滤,遍历 denyList,如果引入的库以 denyList 中某个 deny 开头,就会抛出异常,中断运行。

true: 先白名单过滤,匹配成功即可加载该类,否则再黑名单过滤
false: 先黑名单过滤,再白名单过滤,若白名单匹配上则直接加载该类,否则报错

 评论