jdk7u21链分析

jdk7u21链的分析

前言

分析jdk7u21链。

实验环境

Osx 14.6,jdk7u21,ysoserial最新版。

实验步骤

  1. 直接使用ysoerial生成 jdk7u21的链的oayload,然后将断点下在Runtimeexec

    1
    2
    3
    4
    5
    6
    7
    8
    9
    try {
    FileInputStream fis=new FileInputStream("payload");
    ObjectInputStream obs=new ObjectInputStream(fis);
    Object o=obs.readObject();
    } catch (IOException e) {
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
  2. 调用链如下

    image-20210207100352829

  3. ysoserial最终生成的对象是啥样

    image-20210207100657420

    第一个对象是TemplatesImpl对象,第二个对象实现了动态代理,接口用的是AnnotationInvocationHandler,代理了Templates基类的实现对象。

  4. 链分析

    • LinkedHashSet
      • TemplatesImpl
      • Proxy(Templates)
        • Handler:AnnotationInvocationHandler
          • AnnotationInvocationHandler.invoke
            • AnnotationInvocationHandler.equalsImpl
              • Method.invoke
                • TemplatesImpl.newTransformer
                  • create evil class object

    现在来实际跟一下。

    HashSetreadObject会依次反序列化成员对象并且加入集合,在加入集合中调用put方法。

    image-20210207112051323

    put方法中有两个方法需要注意,一个是hash方法,最终会调用hashcode方法,另外一个是equals方法。hashcode方法是一个常见的Gadget,但是这里主要用到了equals方法作为跳板。由于第一轮集合为空所以不触发循环。

    image-20210207112309679

    在第二轮的时候会进入循环,触发代理对象的equals方法。因为是动态代理的缘故,所以会触发Handler中的invoke方法,并最终进入equalsImpl方法。

    image-20210207112905445

    equalsImpl方法中,需要构造type来满足比较对象类型相同,然后需要伪造memberValues,来获取Method对象,需要注意的是这里可以使用的Method需要是无参的,这也是最终利用链选择TemplatesImpl利用的理由。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    private Boolean equalsImpl(Object var1) {
    if (var1 == this) {
    return true;
    } else if (!this.type.isInstance(var1)) {
    return false;
    } else {
    Method[] var2 = this.getMemberMethods();
    int var3 = var2.length;

    for(int var4 = 0; var4 < var3; ++var4) {
    Method var5 = var2[var4];
    String var6 = var5.getName();
    Object var7 = this.memberValues.get(var6);
    Object var8 = null;
    AnnotationInvocationHandler var9 = this.asOneOfUs(var1);
    if (var9 != null) {
    var8 = var9.memberValues.get(var6);
    } else {
    try {
    var8 = var5.invoke(var1);
    } catch (InvocationTargetException var11) {
    return false;
    } catch (IllegalAccessException var12) {
    throw new AssertionError(var12);
    }
    }

    if (!memberValueEquals(var7, var8)) {
    return false;
    }
    }

    return true;
    }
    }

    image-20210207114058708

    跟入TemplatesImpl的利用链,这里触发getTransletInstance方法。

    image-20210207114308471

    需要置空_name_class来加载字节码。

    image-20210207114411559

    image-20210207114536495

    创建一个AbstractTranslet实例,evilcode一般都写在这个类中的构造器里,创建即执行。

    image-20210207114613771

    弹计算器

    image-20210207114857231

总结与思考

该链用到了相当程度的java知识,所以分析起来需要一些耐心,动态代理的部分可以自己写个demo来理解概念,其他部分跟完payload就基本上明白了。

参考

  1. https://www.cnblogs.com/qifengshi/p/6566752.html
  2. https://github.com/frohoff/ysoserial