识别base64编码内容中的内容并替换整行

识别base64编码内容中的内容并替换整行

我有一个脚本可以在 shell 上输出一些信息,如下所示:

field1: value1
field2: value2
...
fieldn: valuen

这样的字段/值可以是:

    CmdLine: C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe -EncodedCommand <base64_encodedcommand>

我一直在寻找一种方法来处理这个问题,因为编码的命令可能非常大(例如,2 个大或更多的终端屏幕)。我抽出时间去做的一件事是:

command_that_generates_strings | awk '{for (i=1;i<=NF;i++) if (tolower($i) ~/^-encodedcommand/) {i++; "echo "$i" | base64 -d | iconv -f UTF-16LE -t UTF8 | grep -i <specific_identifier_here> | sed -E \"s#.+#<better_identifier_here#g\"" | getline x; print x} else {print $i}}'

为了可读性:

command_that_generates_strings | awk '{
    for (i=1;i<=NF;i++) 
    if (tolower($i) ~/^-encodedcommand/) {
      i++; "echo "$i" | 
      base64 -d | 
      iconv -f UTF-16LE -t UTF8 | 
      grep -i <specific_identifier_here> | 
      sed -E \"s#.+#<better_identifier_here#g\"" | 
      getline x; print x
    } else {print $i}}'

(是的,iconv其中的原因是,雪上加霜的是,base64 内容是 grep 不喜欢的 utf16le 格式。我在 bash 和 zsh 中都“半成功”地运行了这个)

但这并不完全按预期工作...而不是替换为CmdLine: yaddayadda<better_identifier_here>它只是替换编码的命令,并将其他所有内容分开,并且不知何故它似乎正在对输出进行排序,如下所示:

A-string
B-string
C-string
CmdLine:
C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe
D-string
EncodedCommand
...
N-string
<better_identifier_here>
...
Y-string
Z-string
0-string
1-string
...

(上面的“EncodedCommand”是实际的字符串,而不是来自该命令行的 base64 编码命令)

也许有另一种更好的方法来完成我正在寻找的事情?预期的结果只是:

field1: value1
field2: value2
...
<better_identifier_here>
...
fieldn: valuen

-- 让我们尝试在这里包含一个更有用的示例:

输入:

    field1: value1
    field2: value2
    ...
    CmdLine: C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe -EncodedCommand PABpAG4AcwBlAHIAdAAgAHAAbwB3AGUAcgBzAGgAZQBsAGwACgBtAHUAbAB0AGkAbABpAG4AZQAKAHMAYwByAGkAcAB0AAoAaABlAHIAZQAgAC0AIABpAHQAJwBsAGwAIABiAGUAIABlAG4AYwBvAGQAZQBkACAAYQBzACAAdQB0AGYAMQA2AGwAZQAKAGEAbgBkACAAdABoAGUAbgAgAGUAbgBjAG8AZABlAGQAIABpAG4AIABiAGEAcwBlADYANAA+AA==
    ...
    fieldn: valuen

由此,我希望能够识别该字符串"be encoded"是该编码命令的一部分,并将整个“CmdLine”行替换为“找到编码的有效负载”。

示例输出如下:

    field1: value1
    field2: value2
    ...
    Encoded payload found.
    ...
    fieldn: valuen

答案1

假设您想要:

  • 查找任意出现-encodedcommand(不区分大小写)后跟空格的Base64 编码数据
  • 将其解码为假定为多行 UTF16-LE 编码字符串的内容
  • 解码 UTF16-LE 以获取实际文本
  • 将解码文本中与模式(不区分大小写)匹配的任何行替换为新行
  • 将结果编码回 UTF16-LE
  • 并返回base64

然后你可以这样做:

your-cmd | perl -MMIME::Base64 -MEncode -pe '
  s{\s-encodedcommand\s+\K\S+}{
    encode_base64(
      encode(
        "UTF16LE",
        decode(
          "UTF16LE",
          decode_base64($&)
        ) =~ s/^.*bad content.*$/new better content/mgir
      ), ""
    )
  }gie'

例子。与your-cmd是:

echo 'CmdLine: ... -EncodedCommand MQANAAoAMgANAAoAMwANAAoANAANAAoA'

MQANAAoAMgANAAoAMwANAAoANAANAAoA其中 的输出的UTF16-LE 编码的base64编码seq -f $'%g\r' 4

替换为s/^3\r$/new\r/mgir,用 1 替换该3行(带有 MSDOS 行分隔符),new给出:

CmdLine: ... -EncodedCommand MQANAAoAMgANAAoAbgBlAHcADQAKADQADQAKAA==

在哪里:

echo MQANAAoAMgANAAoAbgBlAHcADQAKADQADQAKAA== |
  base64 -d |
  hexdump -C

给出:

00000000  31 00 0d 00 0a 00 32 00  0d 00 0a 00 6e 00 65 00  |1.....2.....n.e.|
00000010  77 00 0d 00 0a 00 34 00  0d 00 0a 00              |w.....4.....|
0000001c

您可以在哪里识别 Microsoft 版本

1
2
new
4

如果按照您明确的要求,您只想检测编码文本中的字符串,如果存在,则用解码的内容替换整行(大概以UTF-8¹编码)

your-cmd | perl -MMIME::Base64 -MEncode -pe '
  if (/^\s*cmdline:.*\s-encodedcommand\s+(\S+)/i) {
    $text = decode("UTF16LE", decode_base64($1));
    if ($text =~ /encoded as/) {
      $_ = encode("UTF-8", "$text\n");
      # or "$text\r\n" if meant to be DOS-style or:
      # $_ = "Encoded payload found\n";
    }
  }'

(假设每行只有一个-encodedcommand;如果有更多,则仅考虑最后一个。替换.*.*?以考虑第一个)。

在你的样本上,这给出了:

    field1: value1
    field2: value2
    ...
<insert powershell
multiline
script
here - it'll be encoded as utf16le
and then encoded in base64>
    ...
    fieldn: valuen

1 默认情况下,perl 会将输入视为采用 ISO8859-1(又名 latin1)编码。由于您要处理的部分仅是 ASCII,因此不会有任何区别,并且至少对于 latin1,您不会遇到解码问题。如果它是 UTF-8,您可以添加该-C选项perl并跳过该encode("UTF-8"...)部分。

请注意,虽然字节顺序标记不属于 UTF-8,但有时会在 Microsoft 文件中找到它们。如果是这种情况并且CmdLine位于第一行,则/^\s*cmdline.../i正则表达式将不匹配,因为开头会有 U+FEFF BOM 字符。然后您可以传递-C并更改正则表达式以/^\x{feff}?\s*cmdline.../i允许在行开头使用可选的 U+FEFF 字符。

答案2

到目前为止,唯一有效的解决方案似乎是接受编码命令是 UTF16LE,并在生成内容的脚本\u0000中手动包含搜索中的空字节...jq

对于上面给出的示例,考虑到大写和小写-EncodedCommand或的可能性-encodedcommand,就像(在 内jq):

restofjq | 
 if(if((split(" ")[1] | ascii_downcase)=="-encodedcommand") 
    then (
        split(" ")[2] | 
        @base64d | 
        test("\u0000b\u0000e\u0000 \u0000e\u0000n\u0000c\u0000o\u0000d\u0000e\u0000d\u0000")
    ) else empty end
  ) then "Encoded payload found!" else empty end

(添加换行符以方便阅读)

split(" ")将使 powershell 命令行为split(" ")[0],而实际编码的命令-EncodedCommandsplit(" ")[1]split(" ")[2]

因为内容采用 UTF16LE 格式,所以如果我尝试@base64d | test("be encoded")这样做就会失败,因为 UTF16LE 中存在空值。这样,如果be encoded在编码命令中找到内容,则该字段将输出为Encoded payload found!

相关内容