JDK7u21

·
Java代码审计 no tag August 12, 2021

JDK7u21

在前面的CommonsCollections这些利用链中,必须依靠第三方jar包 才能反序列化。

JDK7u21的核心是sun.reflect.annotation.AnnotationInvocationHandler

我们查看equalsImpl方法

image-20210812091159977

发现这里有一个反射调用memberMethod.invoke(),而memberMethod来自于this.type.getDeclaredMethods()。

也就是说,equalsImpl这个方法是将this.type类中的所有方法遍历执行了。那么假设this.type是Templates类。那么就会执行其中的newTransformer() 或 getOutputProperties() 方法,进而触发任意代码执行。

如何调用equalsImpl

image-20210812110356835

我们看到在invoke方法中调用了equalsImpl。

在之前我们说过。在使用 java.reflect.Proxy 动态绑定一个接口时,如果调用该接口中任意一个方法,会执行到 InvocationHandler#invoke 。执行invoke时,被传入的第一个参数是这个proxy对象,第二个参数是 被执行的方法名,第三个参数是执行时的参数列表。

而 AnnotationInvocationHandler 就是一个 InvocationHandler 接口的实现,我们看看它的invoke 方法:

if (var4.equals("equals") && var5.length == 1 && var5[0] == Object.class)

根据这句来看,方法名等于equals且只有一个Object类型参数时,会调用equalImpl方法

找到equals方法调用链

会经常调用equals的场景就是集合set。set中出储存的对象不允许重复。所以在添加对象的时候会涉及到比较操作

我们查看Hashset的readObject方法。

image-20210812110448790

可见,这里使用了HashMap,将对象保存在HashMap的key处来做去重。最后调用了put

image-20210812110459296

这个变量i就是所谓的哈希。只有两个不通对象的i相等时候。才会执行到key.equals(k)

接下来我们就要让proxy对象的哈希值,等于TemplateImpl对象的哈希值

梳理思路

  • 首先生成恶意TemplateImpl对象
  • 实例化AnnotationInvocationHandler对象,它的type属性是一个TemplateImpl类,它的memberValues属性是一个Map,Map只有一个key和value,key是字符串 f5a5a608 , value是前面生成的恶意TemplateImpl对象
  • 对这个 AnnotationInvocationHandler 对象做一层代理,生成proxy对象
  • 实例化一个HashSet,这个hashset有两个元素 TempateIpml对象,proxy对象。
  • 将HashSet对象序列化

流程跟踪

首先打断点调试,进入Hashset的readObject方法。

image-20210812112636165

然后进入hashMap的put函数,计算第一个hash

image-20210812114718544

设置第一个hash

image-20210812112840439

然后再次进入put

经过计算,第二个hash和第一个相同,调用了equals函数。由于动态代理特性进入invoke方法

image-20210812113117581

所以会调用TemplatesImpl中的所有方法。

image-20210812113539301

然后就是之前分析过的执行字节码的老一套了

image-20210812113725712

  • ciscn国赛决赛 ezj4va复现
  • fat-jar调试踩坑
取消回复

说点什么?

© 2023 Yang_99的小窝. Using Typecho & Moricolor.