今天我们发布了一个新的工具来帮助红队成员避免被EDR发现。壳代码是一小段代码,通常用作漏洞利用的有效负载,通常可以通过其"签名"或唯一模式检测到。Shellcode Mutator可在不影响其功能的情况下改变利用漏洞攻击源代码,更改其特征码并使其更难被可靠地检测为恶意代码。
网站名称:https://github.com/netitude/ShellcodeMutator
用汇编语言编写壳代码的一个主要好处是,你可以完全控制壳代码的结构。
例如,源文件中函数的内容和顺序可以(显然)更改,代码可以编译为新版本的壳代码。这些改变不一定是功能性的,但是,我们可以使用自动化工具来改变壳代码源代码,以便每次我们编译它时,功能保持不变,但内容发生了变化。
这意味着生成的壳代码将具有不同的大小、文件哈希、字节顺序等,这将使其更难在静态和内存中可靠地检测。
这种能力与壳代码加密等是正交的,因为在某个点上,加密和编码的壳代码需要被解密、解码和解扰,以便它可以实际上被执行,并且在这个点上,它可以被检测到。
让我们使用一个具体的例子,如果有点做作。
我们可以从Didier Stevens那里获得一些MessageBox壳代码的nasm源代码,按照他的指令编译并注入它,我们成功地得到了一个消息框--到目前为止一切顺利。
如果我们要提取这个shell代码作为一个blue teamer,并希望编写检测来捕获它,我们可以记录哈希,检查内容和反汇编,然后编写一个yara规则,以便能够在内存或磁盘上捕获它。
如下所示,我们可以使用binary refinery快速查看一下二元。
我们还注意到sha256哈希值是a8fb8c2b46ab00c0c5bc6aa8d9d6d5263a8c4d83ad465a9c50313da17c85fcb3
。
Rizin可以用来检查壳代码的反汇编。
如果我们要为此编写一个非常快速的yara规则,我们可能会选择关注执行一些设置的初始字节。替换偏移(例如[原始码+0x113]
),并将字节向上取到第二个调用0x0000001b
我们可以编写一个快速的yara规则来匹配内存和磁盘中的shell代码,但不匹配其他代码。C:\windows\system32
(测试假阳性)。
该规则匹配磁盘和内存中的壳代码,并且不会对中的任何内容触发误报C:\windows\system32
。
所以我们有一个可靠的yara规则,并添加到我们的威胁狩猎
这就是Shellcode Mutator项目的用武之地。这个简单的python脚本将解析nasm源代码,并以随机间隔插入指令集,这些指令集“什么也不做”,但随后将以增加大小为代价改变shell代码的字节顺序和文件散列。
这个脚本很容易使用,它有一个源代码“模板”、一个输出文件、一个变形百分比和一个设置x86
与x64
模式的标志。
这个脚本有一些基本的逻辑来检查源代码行,但本质上有一些可以扩展的指令集,一个用于x86
,一个用于x64
。这些指令集中的每一项在所有指令执行完毕后,都应使所有寄存器与标志保持与执行前相同的状态,以确保壳代码可以继续运行而不会出错。
与其他一些逻辑一起,脚本将以随机间隔(由变形百分比决定)将这些指令集放置在汇编指令
变量:
如果我们对MessageBox壳代码运行该脚本,将变形百分比设置为15%,则得到的源代码文件为57行,而不是53行。编译该壳代码并执行yara搜索,结果显示没有捕获到该代码,只有原始壳代码匹配。
通过检查二进制文件的反汇编,可以发现它在我们匹配的字节中插入了一条nop(0x90
)指令(除了在其他地方)。这当然也改变了文件哈希。
当然,这其中有运气的因素。我们需要确保我们更改了足够多的字节,使得任何yara规则不再匹配,而实际上不知道这些yara规则是什么(或任何其他检测)。增加变形百分比将增加修改的次数,并以增加壳代码大小为代价,增加绕过任何规则的可能性。
当然,最大的问题是,我们的壳代码是否还能运行
okk!
网站名称:https://github.com/netitude/ShellcodeMutator