Common Collections 利用链-1(CC1)漏洞分析

slug
series-status
status
summary
date
series
type
password
icon
tags
category

最终漏洞点

  • 首先给大家看一下cc1的最后的利用点,也就是InvokerTransformer类,首先看一下它的transformer方法:
notion image
  • 可以看到,这里它使用了之前我们讲过的反射的机制调用了一个类的一个方法,而具体调用的什么类的什么方法则是通过iMethodName, iParamTypes, iArgs三个参数决定的,而这三个参数则是在构造方法里设定的:
notion image
  • 可以看到,所以这个反射方法是完全可控的,最终也导致了命令执行的产生。
  • 示例利用代码:
  • 执行结果:
notion image

漏洞回溯

TransformedMap

  • 在上一部分我们找到了最终的可以任意控制的漏洞利用点,但是由于我们还没找到readObject方法,因此还没办法最终利用这个部分,因此我们还需要向前寻找,看看有没有哪个函数调用了transform方法,最好这个函数还可以支持传入任意的对象,这样我们传入这个InvokerTransformer对象,然后就会调用它的transform方法了。
  • 而我们通过idea的find usage功能最终可以找到TransformedMap类的checkSetValue方法调用了transform:
notion image
  • 而这里这个valueTransformer对象我们可以溯源到其构造方法:
notion image
  • 不过我们发现它的构造方法是protected的,因此我们还需要继续往上寻找,可以发现decorate方法调用了这个构造方法:
notion image
  • 因此我们可以通过尝试调用这个decorate方法去设定checkSetValue的valueTransformer。
  • 而此时我们还不知道checkSetValue方法是如何能调用到的,以及其value值是否可以控制,也就是说我们能不能传入一个Runtime对象去执行我们的方法。

AbstractInputCheckedMapDecorator.MapEntry

  • 最终可以找到在AbstractInputCheckedMapDecorator类的MapEntry中调用了这个方法:
notion image
  • 配合我们常用的遍历map的写法,不难发现这里其实只要遍历我们之前的TrasformedMap就可以最终执行setValue方法。
这里遍历map的四种常用方法可以参见这个链接:https://blog.csdn.net/gm371200587/article/details/82108372?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~Rate-1-82108372-blog-80156626.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~Rate-1-82108372-blog-80156626.pc_relevant_vip_default&utm_relevant_index=1
  • 这里简单列举四种遍历方案:
  • 因此,这里我们的漏洞利用代码可以优化为:
  • 执行结果为:
notion image
  • 当然,这里由于Map的特性,我们传入的HashMap里有几个值他就会调用几次setValue方法也就会调用几次checkSetValue方法也就会调用几次transform方法也就会执行几次我们的命令,因此如果我们传入两个值:
  • 就会得到两条记录:
notion image
  • 那么接下来就应该去寻找哪里有没有遍历数组的操作调用了setvalue方法,当然最好还是readobject方法。

AnnotationInvocationHandler

  • 经过一番寻找,最终会发现在AnnotationInvocationHandler类里有一个对setvalue的调用,也是一个遍历数组的功能,恰巧这里也还是一个readobject方法:
notion image
  • 那么就要看一下这里的调用的setvalue方法的参数能否控制
  • 观察该类的构造方法,可以发现这里的memberValues是构造方法传入的一个map:
notion image
  • 因此这里我们可以尝试利用一下这个类实现这个漏洞,而这个类由于没有指定类型,因此是一个默认属性的类,只能在同一个包底下才能访问到它,因此我们要利用的话只能通过反射去获取这个对象,具体示例代码如下:
  • 但是会发现现在这个时候并没有正确执行我们想要执行的命令:curl <http://httplog.ip/Xg5/AnnotationInvocationHandler>
notion image
  • 这是因为这里的几个问题:
      1. AnnotationInvocationHandler的readobject方法的对象我们是无法控制的
        1. notion image
      1. 而且这里还会有两个if需要通过
      1. 即使我们满足了这两条,我们要传入的Runtime对象也是没办法序列化的
我们逐步去解决这个问题
  • 针对Runtime无法序列化,我们可以通过反射去获取这个对象,毕竟Class类肯定是可以序列化的,这部分的代码如下:
  • 运行效果:
notion image
  • 而我们还要将其转换为InvokerTransformer的写法以便后续使用:
  • 效果:
notion image
  • 不过这样写其实还是有一些麻烦的,恰好也有这么一个类可以帮我们实现这种递归的transform调用,就是ChainedTransformer,转换后的代码如下:
  • 效果:
notion image
至此解决了Runtime的序列化问题,接下来补充代码:
  • 但是其实会发现这里运行代码是没办法正确执行的,问题就是在我们前文提到的if条件那里:
notion image
  • 由于我们传入的Override成员方法的参数其实是空的,因此无法通过第一个if:
notion image
  • 因此我们可以Override改为一个有成员方法的注解类,例如Target:
notion image
  • 同时将部分代码改为如下,其中要注意把HashMap的key值也改为成员方法名,因为在readObject方法里还会判断是否有这个key对应的成员方法:
  • 至此则可以正常通过两个if条件了(第二个if其实只是判断是否支持强转,而我们这里是不支持的,因此可以直接通过)
  • 在这里我们还要面对最后一个问题,就是在通过if以后,调用的setValue的参数其实是已经写死的,是一个AnnotationTypeMismatchExceptionProxy对象:
notion image
  • 而在这个条件下,我们的ChainedTransformer的入口参数就不是我们想要的Runtime.Class而是这个AnnotationTypeMismatchExceptionProxy对象
notion image
  • 为了解决这个问题,我们找到了另一个类ConstantTransformer:
notion image
  • 可以看到这个类的transform方法不论输入什么内容,都会返回一样的内容(在构造方法里写的对象),因此如果将其放在ChainedTramsformer的第一个去调用的话,则可以通过将我们想要的Runtime.class放在构造方法的参数里然后就可以替换掉写死的对象继续后边的利用链了
  • 总结起来,最终代码如下:
  • 运行效果如下:
notion image
至此,CC1利用链的漏洞分析完成,希望大家也可以重视这条利用链的学习,是Java反序列化各种利用链中很重要的基础。
参考视频:https://www.bilibili.com/video/BV1no4y1U7E1/?spm_id_from=333.880.my_history.page.click&vd_source=8546f8163043e33e9fdf8c5e94be2d24
Loading...

尚未开始
更新中
近期核心
已完结
已弃更

© River 2021-2025