EDRSandBlast is a tool written in C that weaponize a vulnerable signed driver to bypass EDR detections and LSASS protections

EDRSandBlast

EDRSandBlast is a tool written in C that weaponize a vulnerable signed driver to bypass EDR detections (Kernel callbacks and ETW TI provider) and LSASS protections. Multiple userland unhooking techniques are also implemented to evade userland monitoring.

As of release, combination of userland (--usermode) and Kernel-land (--kernelmode) techniques were used to dump LSASS memory under EDR scrutiny, without being blocked nor generating "OS Credential Dumping"-related events in the product (cloud) console. The tests were performed on 3 distinct EDR products and were successful in each case.

Description

EDR bypass through Kernel callbacks removal

EDR products use Kernel callbacks on Windows to be notified by the kernel of system activity, such as process and thread creation and loading of images (exe / DLL).

The Kernel callbacks are defined from user-land using a number of documented APIs (nt!PsSetCreateProcessNotifyRoutine, nt!PsSetCreateThreadNotifyRoutine, etc.). The user-land APIs add driver-supplied callback routines to undocumented arrays of routines in Kernel-space:

  • PspCreateProcessNotifyRoutine for process creation
  • PspCreateThreadNotifyRoutine for thread creation
  • PspLoadImageNotifyRoutine for image loading

EDRSandBlast enumerates the routines defined in those arrays and remove any callback routine linked to a predefined list of EDR drivers (more than 1000 thousands drivers of security products from the allocated filter altitudes). The enumeration and removal are made possible through the exploitation of an arbitrary Kernel memory read / write vulnerability of the Micro-Star MSI Afterburner driver (CVE-2019-16098). The enumeration and removal code is largely inspired from br-sn's CheekyBlinder project.

The offsets of the aforementioned arrays are hardcoded in the NtoskrnlOffsets.csv file for more than 350 versions of the Windows Kernel ntoskrnl.exe. The choice of going with hardcoded offsets instead of pattern searches is justified by the fact that the undocumented APIs responsible for Kernel callbacks addition / removal are subject to change and that any attempt to write Kernel memory at the wrong address may (and often will) result in a Bug Check (Blue Screen of Death). For more information on how the offsets were gathered, refer to Offsets section.

EDR bypass through deactivation of the ETW Microsoft-Windows-Threat-Intelligence provider

The ETW Microsoft-Windows-Threat-Intelligence provider log data about the usages of some Windows API commonly used maliciously. This include the nt!MiReadWriteVirtualMemory API, called by nt!NtReadVirtualMemory (which is used to dump LSASS memory) and monitored by the nt!EtwTiLogReadWriteVm function.

EDR products can consume the logs produced by the ETW TI provider through services or processes running as, respectively, SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT or PS_PROTECTED_ANTIMALWARE_LIGHT, and associated with an Early Launch Anti Malware (ELAM) driver.

As published by slaeryan in a CNO Development Labs blog post, the ETW TI provider can be disabled altogether by patching, in kernel memory, its ProviderEnableInfo attribute to 0x0. Refer to the great aforementioned blog post for more information on the technique.

Similarly to the Kernel callbacks removal, the necessary ntoskrnl.exe offsets (nt!EtwThreatIntProvRegHandleOffset, _ETW_REG_ENTRY's GuidEntry, and _ETW_GUID_ENTRY's ProviderEnableInfo) are hardcoded in the NtoskrnlOffsets.csv file a number of the Windows Kernel versions.

EDR bypass through userland hooking bypass

How userland hooking works

In order to easily monitor actions that are performed by processes, EDR products often deploy a mechanism called userland hooking. First, EDR products register a kernel callback (usually image loading or process creation callbacks, see above) that allows them to be notified upon each process start.

When a process is loaded by Windows, and before it actually starts, the EDR is able to inject some custom DLL into the process address space, which contains its monitoing logic. While loading, this DLL injects "hooks" at the start of every function that is to be monitored by the EDR. At runtime, when the monitored functions are called by the process under surveillance, these hooks redirect the control flow to some supervision code present in the EDR's DLL, which allows it to inspect arguments and return values of these calls.

Most of the time, monitored functions are system calls (such as NtReadVirtualMemory, NtOpenProcess, etc.), whose implementations reside in ntdll.dll. Intercepting calls to Nt* functions allows products to be as close as possible to the userland / kernel-land boundary (while remaining in userland), but functions from some higher-level DLLs may also be monitored as well.

Bellow are examples of the same function, before and after beeing hooked by the EDR product:

NtProtectVirtualMemory   proc near
	mov r10, rcx
	mov eax, 50h
	test byte ptr ds:7FFE0308h, 1
	jnz short loc_18009D1E5
	syscall
	retn
loc_18009D1E5:
	int 2Eh
	retn
NtProtectVirtualMemory   endp			
NtProtectVirtualMemory proc near
	jmp     sub_7FFC74490298     ; --> "hook", jump to EDR analysis function
	int 3                        ; overwritten instructions
	int 3                        ; overwritten instructions
	int 3                        ; overwritten instructions
	test byte_7FFE0308, 1        ; <-- execution resumes here after analysis
	jnz short loc_7FFCB44AD1E5
	syscall
	retn
loc_7FFCB44AD1E5:
	int 2Eh
	retn
NtProtectVirtualMemory   endp			

Hooks detection

Userland hooks have the "weakness" to be located in userland memory, which means they are directly observable and modifiable by the process under scrutiny. To automatically detect hooks in the process address space, the main idea is to compare the differences between the original DLL on disk and the library residing in memory, that has been potentially altered by an EDR. To perform this comparison, the following steps are followed by EDRSandblast:

  • The list of all loaded DLLs is enumerated thanks to the InLoadOrderModuleList located int the PEB (to avoid calling any API that could be monitored and suspicious)
  • For each loaded DLL, its content on disk is read and its headers parsed. The corresponding library, residing in memory, is also parsed to identify sections, exports, etc.
  • Relocations of the DLL are parsed and applied, by taking the base address of the corresponding loaded library into account. This allows the content of both the in-memory library and DLL originating from disk to have the exact same content (on sections where relocations are applied), and thus making the comparison reliable.
  • Exported functions are enumerated and the first bytes of the "in-memory" and "on-disk" versions are compared. Any difference indicates an alteration that has been made after the DLL was loaded, and thus is very probably an EDR hook.

Note: The process can be generalized to find differences anywhere in non-writable sections and not only at the start of exported functions, for example if EDR products start to apply hooks in the middle of function :) Thus not used by the tool, this has been implemented in findDiffsInNonWritableSections.

In order to bypass the monitoring performed by these hooks, multiples techniques are possible, and each has benefits and drawbacks.

Hook bypass using ... unhooking

The most intuitive method to bypass the hook-based monitoring is to remove the hooks. Since the hooks are present in memory that is reachable by the process itself, to remove a hook, the process can simply:

  • Change the permissions on the page where the hook is located (RX -> RWX or RW)
  • Write the original bytes that are known thanks to the on-disk DLL content
  • Change back the permissions to RX

This approach is fairly simple, and can be used to remove every detected hook all at once. Performed by an offensive tool at its begining, this allows the rest of the code to be completely unaware of the hooking mechnanism and perform normally without being monitored.

However, it has two main drawbacks. The EDR is probably monitoring the use of NtProtectVirtualMemory, so using it to change the permissions of the page where the hooks have been installed is (at least conceptually) a bad idea. Also, if a thread is executed by the EDR and periodically check the integrity of the hooks, this could also trigger some detection.

For implementation details, check the unhook() function's code path when unhook_method is UNHOOK_WITH_NTPROTECTVIRTUALMEMORY.

Important note: for simplicity, this technique is implemented in EDRSandblast as the base technique used to showcase the other bypass techniques; each of them demonstrates how to obtain an unmonitored version of NtProtectVirtualMemory, but performs the same operation afterward (unhooking a specific hook).

Hook bypass using a custom trampoline

To bypass a specific hook, it is possible to simply "jump over" and execute the rest of the function as is. First, the original bytes of the monitored function, that have been overwritten by the EDR to install the hook, must be recovered from the DLL file. In our previous code example, this would be the bytes corresponding to the following instructions:

mov r10, rcx
mov eax, 50h

Identifying these bytes is a simple task since we are able to perform a clean diff of both the memory and disk versions of the library, as previously described. Then, we assemble a jump instruction that is built to redirect the control flow to the code following immediately the hook, at address NtProtectVirtualMemory + sizeof(overwritten_instructions)

jmp NtProtectVirtualMemory+8

Finally, we concatenate these opcodes, store them in (newly) executable memory and keep a pointer to them. This object is called a "trampoline" and can then be used as a function pointer, strictly equivalent to the original NtProtectVirtualMemory function.

The main benefit of this technique as for every techniques bellow, is that the hook is never erased, so any integrity check performed on the hooks by the EDR should pass. However, it requires to allocate writable then executable memory, which is typical of a shellcode allocation, thus attracting the EDR's scrutiny.

For implementation details, check the unhook() function's code path when unhook_method is UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE. Please remind the technique is only showcased in our implementation and is, in the end, used to remove hooks from memory, as every technique bellow.

Hook bypass using the own EDR's trampoline

The EDR product, in order for its hook to work, must save somewhere in memory the opcodes that it has removed. Worst (or "better", from the attacker point of view), to effectively use the original instructions the EDR has probably allocated itself a trampoline somewhere to execute the original function after having intercepted the call.

This trampoline can be searched for and used as a replacement for the hooked function, without the need to allocate executable memory, or call any API except VirtualQuery, which is most likely not monitored being an innocuous function.

To find the trampoline in memory, we browse the whole address space using VirtualQuery looking for commited and executable memory. For each such region of memory, we scan it to look for a jump instruction that targets the address following the overwritten instructions (NtProtectVirtualMemory+8 in our previous example). The trampoline can then be used to call the hooked function without triggering the hook.

This technique works surprisingly well as it recovers nearly all trampolines on tested EDR. For implementation details, check the unhook() function's code path when unhook_method is UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE.

Hook bypass using duplicate DLL

Another simple method to get access to an unmonitored version of NtProtectVirtualMemory function is to load a duplicate version of the ntdll.dll library into the process address space. Since two identical DLLs can be loaded in the same process, provided they have different names, we can simply copy the legitimate ntdll.dll file into another location, load it using LoadLibrary (or reimplement the loading process), and access the function using GetProcAddress for example.

This technique is very simple to understand and implement, and have a decent chance of success, since most of EDR products does not re-install hooks on newly loaded DLLs once the process is running. However, the major drawback is that copying Microsoft signed binaries under a different name is often considered as suspicious by EDR products as itself.

This technique is nevertheless implemented in EDRSandblast. For implementation details, check the unhook() function's code path when unhook_method is UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY.

Hook bypass using direct syscalls

In order to use system calls related functions, one program can reimplement syscalls (in assembly) in order to call the corresponding OS features without actually touching the code in ntdll.dll, which might be monitored by the EDR. This completely bypasses any userland hooking done on syscall functions in ntdll.dll.

This nevertheless has some drawbacks. First, this implies being able to know the list of syscall numbers of functions the program needs, which changes for each version of Windows. Also, functions that are not technically syscalls (e.g. LoadLibraryX/LdrLoadDLL) could be monitored as well, and cannot simply be reimplemented using a syscall.

This technique is implemented in EDRSandblast. As previously stated, it is only used to execute NtProtectVirtualMemory safely, and remove all detected hooks. However, in order not to rely on hardcoded offsets, a small heuristic is implemented to search for mov eax, imm32 instruction at the start of the NtProtectVirtualMemory function and recover the syscall number from it if found (else relying on hardcoded offset for known Windows versions).

For implementation details, check the unhook() function's code path when unhook_method is UNHOOK_WITH_DIRECT_SYSCALL.

RunAsPPL bypass

The Local Security Authority (LSA) Protection mechanism, firstly introduced in Windows 8.1 and Windows Server 2012 R2, leverage the Protected Process Light (PPL) technology to restrict access to the LSASS process. The PPL protection regulates and restricts operations, such as memory injection or memory dumping of protected processes, even from process holding the SeDebugPrivilege privilege.

The protection level of a process is defined in its EPROCESS structure, used by the Windows kernel to represent processes in memory. The EPROCESS structure includes a _PS_PROTECTION field, defining the protection level of a process through its Type (_PS_PROTECTED_TYPE) and Signer (_PS_PROTECTED_SIGNER) attributes.

If no EDR drivers callbacks are detected, the current process is self protected as PsProtectedSignerWinTcb-Light. This level of protection is sufficient to dump the LSASS process memory, with RunAsPPL enabled, as the PsProtectedSignerWinTcb signer "dominates" PsProtectedSignerLsa-Light (and both process are of PsProtectedTypeProtectedLight type).

EDRSandBlast implements the self protection as follow:

  • open an handle to the current process
  • leak all system handles using NtQuerySystemInformation to find the opened handle on the current process (which correspond to the current process' EPROCESS structure in kernel memory).
  • use the arbitrary read / write vulnerability of the Micro-Star MSI Afterburner driver to overwrite the _PS_PROTECTION field of the current process in kernel memory. The offsets of the _PS_PROTECTION field relative to the EPROCESS structure (defined by the ntoskrnl version in use) are hardcoded in the NtoskrnlOffsets.csv file.

Credential Guard bypass

Microsoft Credential Guard is a virtualization-based isolation technology, introduced in Microsoft's Windows 10 (Enterprise edition) which prevents direct access to the credentials stored in the LSASS process.

When Credentials Guard is activated, an LSAIso (LSA Isolated) process is created in Virtual Secure Mode, a feature that leverages the virtualization extensions of the CPU to provide added security of data in memory. Access to the LSAIso process are restricted even for an access with the NT AUTHORITY\SYSTEM security context. When processing a hash, the LSA process perform a RPC call to the LSAIso process, and waits for the LSAIso result to continue. Thus, the LSASS process won't contain any secrets and in place will store LSA Isolated Data.

As stated in original research conducted by N4kedTurtle: "Wdigest can be enabled on a system with Credential Guard by patching the values of g_fParameter_useLogonCredential and g_IsCredGuardEnabled in memory". The activation of Wdigest will result in cleartext credentials being stored in LSASS memory for any new interactive logons (with out requiring a reboot of the system). Refer to the original research blog post for more details on this technique.

EDRSandBlast simply make the original PoC a little more opsec friendly and provide support for a number of wdigest.dll versions (through hardcoded offsets for g_fParameter_useLogonCredential and g_IsCredGuardEnabled).

ntoskrnl and wdigest offsets

The required ntoskrnl.exe and wdigest.dll offsets (mentioned above) are extracted using r2pipe, as implemented in the ExtractOffsets.py Python script. In order to support more Windows versions, the ntoskrnl.exe and wdigest.dll referenced by Winbindex can be automatically downloaded (and their offsets extracted). This allow to extract offsets from that files which appear in Windows update packages (to date 350+ ntoskrnl.exe and 30+ wdigest.dll versions).

Usage

The vulnerable RTCore64.sys driver can be retrieved at:

http://download-eu2.guru3d.com/afterburner/%5BGuru3D.com%5D-MSIAfterburnerSetup462Beta2.zip

Quick usage

Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] 
   
     [--usermode [--unhook-method 
    
     ]] [--kernelmode] [--dont-unload-driver] [--dont-restore-callbacks] [--driver 
     
      ] [--service 
      
       ] [--nt-offsets 
       
        ] [--wdigest-offsets 
        
         ] [--add-dll 
         
          ]* [-o | --dump-output 
          
           ] 
          
         
        
       
      
     
    
   

Options

-h | --help             Show this help message and exit.
-v | --verbose          Enable a more verbose output.

Actions mode:

        audit           Display the user-land hooks and / or Kernel callbacks with out taking actions.
        dump            Dump the LSASS process, by default as 'lsass' in the current directory or at the
                        specified file using -o | --output 
   
    .
        cmd             Open a cmd.exe prompt.
        credguard       Patch the LSASS process' memory to enable Wdigest cleartext passwords caching even if
                        Credential Guard is enabled on the host. No kernel-lank actions required.

--usermode              Perform user-land operations (DLL unhooking).
--kernelmode            Perform kernel-land operations (Kernel callbacks removal and ETW TI disabling).

--unhook-method 
    
     
   Choose the userland un-hooking technique, from the following:

        1 (Default)     Uses the (probably monitored) NtProtectVirtualMemory function in ntdll to remove all
                        present userland hooks.
        2               Constructs a 'unhooked' (i.e. unmonitored) version of NtProtectVirtualMemory, by
                        allocating an executable trampoline jumping over the hook, and remove all present
                        userland hooks.
        3               Searches for an existing trampoline allocated by the EDR itself, to get an 'unhooked'
                        (i.e. unmonitored) version of NtProtectVirtualMemory, and remove all present userland
                        hooks.
        4               Loads an additional version of ntdll library into memory, and use the (hopefully
                        unmonitored) version of NtProtectVirtualMemory present in this library to remove all
                        present userland hooks.
        5               Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory,
                        and uses it to remove all detected hooks

Other options:

--dont-unload-driver                    Keep the Micro-Star MSI Afterburner vulnerable driver installed on the host
                                        Default to automatically unsinstall the driver.
--dont-restore-callbacks                Do not restore the EDR drivers' Kernel Callbacks that were removed.
                                        Default to restore the callbacks.

--driver 
     
                       Path to the Micro-Star MSI Afterburner vulnerable driver file.
                                        Default to 'RTCore64.sys' in the current directory.
--service 
      
                       Name of the vulnerable service to intall / start.

--nt-offsets 
       
         Path to the CSV file containing the required ntoskrnl.exe's offsets. Default to 'NtoskrnlOffsets.csv' in the current directory. --wdigest-offsets 
        
          Path to the CSV file containing the required wdigest.dll's offsets (only for the 'credguard' mode). Default to 'WdigestOffsets.csv' in the current directory. --add-dll 
         
           Loads arbitrary libraries into the process' address space, before starting anything. This can be useful to audit userland hooking for DLL that are not loaded by default by this program. Use this option multiple times to load multiple DLLs all at once. Example of interesting DLLs to look at: user32.dll, ole32.dll, crypt32.dll, samcli.dll, winhttp.dll, urlmon.dll, secur32.dll, shell32.dll... -o | --output 
          
            Output path to the dump file that will be generated by the 'dump' mode. Default to 'lsass' in the current directory. 
          
         
        
       
      
     
    
   

Build

EDRSandBlast (x64 only) was built on Visual Studio 2019 (Windows SDK Version: 10.0.19041.0 and Plateform Toolset: Visual Studio 2019 (v142)).

ExtractOffsets.py usage

Note that ExtractOffsets.py has only be tested on Windows.

# Installation of Python dependencies
pip.exe install -m .\requirements.txt

# Script usage
ExtractOffsets.py [-h] -i INPUT [-o OUTPUT] [-d] mode

positional arguments:
  mode                  ntoskrnl or wdigest. Mode to download and extract offsets for either ntoskrnl or wdigest

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        Single file or directory containing ntoskrnl.exe / wdigest.dll to extract offsets from.
                        If in dowload mode, the PE downloaded from MS symbols servers will be placed in this folder.
  -o OUTPUT, --output OUTPUT
                        CSV file to write offsets to. If the specified file already exists, only new ntoskrnl versions will be
                        downloaded / analyzed.
                        Defaults to NtoskrnlOffsets.csv / WdigestOffsets.csv in the current folder.
  -d, --dowload         Flag to download the PE from Microsoft servers using list of versions from winbindex.m417z.com.

Detection

From the defender (EDR vendor, Microsoft, SOC analysts looking at EDR's telemetry, ...) point of view, multiple indicators can be used to detect or prevent this kind of techniques.

Driver whitelisting

Since every action performed by the tool in kernel-mode memory relies on a vulnerable driver to read/write arbitrary content, driver loading events should be heaviliy scrutinized by EDR product (or SOC analysts), and raise an alert at any uncommon driver loading, or even block known vulnerable drivers. This latter approach is even recommended by Microsoft themselves: any HVCI (Hypervisor-protected code integrity) enabled Windows device embeds a drivers blocklist, and this will be progressively become a default behaviour on Windows (it already is on Windows 11).

Kernel-memory integrity checks

Since an attacker could still use an unknown vulnerable driver to perform the same actions in memory, the EDR driver could periodically check that its kernel callbacks are still registered, directly by inspecting kernel memory (like this tool does), or simply by triggering events (process creation, thread creation, image loading, etc.) and checking the callback functions are indeed called by the executive kernel.

As a side note, this type of data structure could be protected via the recent Kernel Data Protection (KDP) mechanism, which relies on Virtual Based Security, in order to make the kernel callbacks array non-writable without calling the right APIs.

The same logic could apply to sensitive ETW variables such as the ProviderEnableInfo, abused by this tool to disable the ETW Threat Intelligence events generation.

User-mode detection

The first indicator that a process is actively trying to evade user-land hooking is the file accesses to each DLL corresponding to loaded modules; in a normal execution, a userland process rarely needs to read DLL files outside of a LoadLibrary call, especially ntdll.dll.

In order to protect API hooking from being bypassed, EDR products could periodically check that hooks are not altered in memory, inside each monitored process.

Finally, to detect hooking bypass (abusing a trampoline, using direct syscalls, etc.) that does not imply the hooks removal, EDR products could potentially rely on kernel callbacks associated to the abused syscalls (ex. PsCreateProcessNotifyRoutine for NtCreateProcess syscall, ObRegisterCallbacks for NtOpenProcess syscall, etc.), and perform user-mode call-stack analysis in order to determine is the syscall was triggered from a normal path (kernel32.dll -> ntdll.dll -> syscall) or an abnormal one (ex. program.exe -> direct syscall).

Acknowledgements

Authors

Thomas DIOT (Qazeer) Maxime MEIGNAN (themaks)

Licence

CC BY 4.0 licence - https://creativecommons.org/licenses/by/4.0/

Owner
Wavestone - Cybersecurity & Digital Trust
Projects from the auditors and consultants from Wavestone's Cybersecurity & Digital Trust practice
Wavestone - Cybersecurity & Digital Trust
Comments
  • ExtractOffsets.py fails on linux

    ExtractOffsets.py fails on linux

    The ExtractOffsets.py script fails to extract offsets on Linux. No crash happens but every time the offsets are all 0x0. It seems radare2 is crashing on pdb files on multiple version tested, explaining the current behavior, though I am not really sure where the problem is.

  • Support for ObRegisterCallbacks

    Support for ObRegisterCallbacks

    It would be interesting to add support for bypass ObRegisterCallbacks LSASS protection. Also could be interesting to add other weaponized drivers.

    Do you accept collaboration??

  • Fix potential buffer overrun in credguard disable

    Fix potential buffer overrun in credguard disable

    The call to GetModuleFileNameEx passes in sizeof(szModulename) for the size parameter. The documentation for that API says the size parameter is a character count, not a byte count ("The size of the lpFilename buffer, in characters."). Since the code currently passes in a byte count, this opens up the possibility for a stack buffer overrun on UNICODE compilations of this tool where the szModulename buffer will be MAX_PATH characters (2 * MAX_PATH bytes), but the size parameter wil indicate it is 2*MAX_PATH characters which GetModuleFileNameEx will interpret as a character count and potentially write up to 2*2*MAX_PATH bytes into the buffer. Fix by passing in a character count. You could also use a macro like ARRAYSIZE(szModulename).

        TCHAR szModulename[MAX_PATH];
        for (DWORD i = 0; i < (lpcbNeeded / sizeof(HMODULE)); i++) {
            if (hModulesArray[i] && !GetModuleFileNameEx(hLsass, hModulesArray[i], szModulename, sizeof(szModulename))) {
    ...        }
    

    [1] Docs for GetModuleFileNameEx are here (https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmodulefilenameexa)

  • Add g_CiOptions offset extract

    Add g_CiOptions offset extract "feature"

    Hi,

    I added g_CiOptions offset extract "feature" to the script. Will be useful for disabling DSE.

    Here is an example :
    ExtractOffsets.py ci -i C:\Windows\System32\ci.dll

  • Error Starting Service on Windows 10 Pro 21H2 19044.1586

    Error Starting Service on Windows 10 Pro 21H2 19044.1586

    Has this driver loading been patched in the Windows 10 version I have mentioned above? The tool fails every time when loading the driver. I ran this on a system with no EDR/AV at all and the driver loading still fails as an Administrator.

    image

  • Windows Defender flagging

    Windows Defender flagging

    Hello,

    Fab tool :-) I was surprised that Windows Defender is now flagging my compiled binary. I looked at strings that could flag it but without success. The signature was "VirTool:Win64/Edirwip.A"

    Strangely if you disable in Code Generation / Security Check to Disable Security Check (/GS-) it's no longer flagged

    Not really an issue, but I thought it could be shared if somebody searches for it. Regards

  • Make extraction of offsets compatible with Linux

    Make extraction of offsets compatible with Linux

    Currently ExtractOffsets.py relies on win32api which is a Windows-only library.

    I removed this dependency to use Radare2 instead (as already started in comments) and I normalized the use of subprocess.run to be compatible with Linux and Windows.

    Finally, i tested the script with Radare2 5.0.0 and it works well: I updated the minimal version to prevent the warning.

  • Offsets could be incorrect (because of Windows version / file version mismatch)

    Offsets could be incorrect (because of Windows version / file version mismatch)

    Hello,

    The file (ex : ntoskrnl.exe) version is used for offset calculations, but some mismatch can happen giving wrong results. In the following example the ntoskrnl.exe version is 19041.2364 but the current running version is 19045.2364. versionMismatch

    For example the following functions are affected (because it uses GetFileVersion from FileVersion.c:13) : LoadWdigestOffsetsFromFile LoadNtoskrnlOffsetsFromFile

    It's a big deal if using kernel RW operation with wrong offsets, it will probably lead to a BSOD.

    Maybe the current Windows version should be double-checked / confirmed using Windows API (ex: GetVersionEx or RtlGetNtVersionNumbers).

  • Add feature : loading unsigned driver

    Add feature : loading unsigned driver

    Hello, This PR allows to add the unsigned driver loading feature. It is done by patching g_CiOptions in order to disable DSE, load unsigned driver, restore g_CiOptions. The Ci offset is extracted with the same method you use for ntoskrnl. I added the support of gdrv.sys driver because I'm used to use it.

  • Fix multiple issues in offsets extractor

    Fix multiple issues in offsets extractor

    This PR fix multiple issues in the extractor:

    • A crash in the version check of radare2 depending on the release taken
    • The progress not showing correctly when downloading and processing files. I had to remove some verbose information to avoid the progress being rewritten
    • Introducing locks when downloading files to prevent any race when printing
    • Now finding version information in the nested json file to prevent some crashes and potentially retrieving more ntoskrnl.exe files
  • Feature Request: MinGW compatibility

    Feature Request: MinGW compatibility

    Trying to build under mingw (on linux), i'm having to downcase some headers and seeing macro definitions fail a la:

    Includes/DriverOps.h:12:66: error: expected ‘)’ before ‘__FUNCTION__’
       12 | #define PRINT_ERROR_AUTO(func) (_tprintf(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError()))
          |                                                                  ^~~~~~~~~~~~
    Utils/DriverOps.c:74:21: note: in expansion of macro ‘PRINT_ERROR_AUTO’
       74 |                     PRINT_ERROR_AUTO(TEXT("CreateService"));
          |                     ^~~~~~~~~~~~~~~~
    In file included from Utils/DriverOps.c:12:
    Includes/DriverOps.h:12:41: note: to match this ‘(’
       12 | #define PRINT_ERROR_AUTO(func) (_tprintf(TEXT("[!] ERROR ") TEXT(__FUNCTION__) TEXT(" ; ") func TEXT(" (0x%08x)\n"), GetLastError()))
          |                                         ^
    Utils/DriverOps.c:74:21: note: in expansion of macro ‘PRINT_ERROR_AUTO’
       74 |                     PRINT_ERROR_AUTO(TEXT("CreateService"));
          |                     ^~~~~~~~~~~~~~~~
    In file included from /usr/x86_64-w64-mingw32/include/minwindef.h:163,
                     from /usr/x86_64-w64-mingw32/include/windef.h:9,
                     from /usr/x86_64-w64-mingw32/include/windows.h:69,
                     from Utils/DriverOps.c:7:
    

    still trying to nail down all the include paths, but guessing that anything i come up w/ is going to be rather hacky compared to actual author implementation. Would be a very nice feature to have if you have the cycles to implement. Thanks for the awesome code - highly informative.

Sysmon event simulation utility which can be used to simulate the attacks to generate the Sysmon Event logs for testing the EDR detections and correlation rules by Blue teams.

SysmonSimulator SysmonSimulator is an Open source Windows event simulation utility created in C language, that can be used to simulate most of the att

Dec 25, 2022
Signed - a 3D modeling and construction language based on Lua and SDFs. Signed will be available for macOS and iOS and is heavily optimized for Metal.
Signed - a 3D modeling and construction language based on Lua and SDFs. Signed will be available for macOS and iOS and is heavily optimized for Metal.

Signed - A 3D modeling language Abstract Signed is a Lua based 3D modeling language, it provides a unique way to create high quality 3D content for yo

Nov 21, 2022
Hygieia, a vulnerable driver traces scanner written in C++ as an x64 Windows kernel driver.

Hygieia The Greek goddess of health, her name is the source for the word "hygiene". Hygieia is a windows driver that works similarly to how pagewalkr

Dec 4, 2022
SinMapper - usermode driver mapper that forcefully loads any signed kernel driver
SinMapper - usermode driver mapper that forcefully loads any signed kernel driver

usermode driver mapper that forcefully loads any signed kernel driver (legit cert) with a big enough section (example: .data, .rdata) to map your driver over. the main focus of this project is to prevent modern anti-cheats (BattlEye, EAC) from finding your driver and having the power to hook anything due to being inside of legit memory (signed legit driver).

Dec 29, 2022
vdk is a set of utilities used to help with exploitation of a vulnerable driver.

vdk - vulnerable driver kit vdk is a set of utilities used to help with exploitation of a vulnerable driver. There are 2 main features of this library

Nov 23, 2022
ScriptHook Bypass For Fivem / bypass hardware ID For nvdia only
ScriptHook Bypass For Fivem / bypass hardware ID For nvdia only

Fivem-Bypass ScriptHook Bypass For Fivem / bypass hardware ID For nvdia only Not Working? Run as admin and disable your antivirus. How to use 1. Put y

Dec 25, 2022
Some source code to demonstrate avoiding certain direct syscall detections by locating and JMPing to a legitimate syscall instruction within NTDLL.

hiding-your-syscalls What is this? This repository contains all of the source code from my blog post about avoiding direct syscall detections, which y

Dec 1, 2022
A Simple LSASS Credential Injection Tool

CredInject Hello Dear Reader! Welcome to the CredInject repo -- This project is based on HoneyCred and uses the same method to inject credentials into

Jun 8, 2022
GPU 3D signed distance field generator, written with DirectX 11 compute shader
GPU 3D signed distance field generator, written with DirectX 11 compute shader

GPU SDF Generator GPU 3D signed distance field generator, written with DirectX 11 compute shader Building git clone --recursive https://github.com/Air

Dec 13, 2022
Shellcode loader written in rust. Strives to evade modern EDR solutions.

Pestilence What is pestilence? Pestilence is a shellcode loader written in rust. It strives to evade modern EDR solutions. How does it work? It loads

Dec 5, 2022
OffensivePH - use old Process Hacker driver to bypass several user-mode access controls

offensiveph OffensivePH is a post-exploitation tool that utilizes an old Process Hacker driver to bypass several user-mode access controls. Usage Comp

Dec 29, 2022
x64 Windows kernel code execution via user-mode, arbitrary syscall, vulnerable IOCTLs demonstration
x64 Windows kernel code execution via user-mode, arbitrary syscall, vulnerable IOCTLs demonstration

anycall x64 Windows kernel code execution via user-mode, arbitrary syscall, vulnerable IOCTLs demonstration Read: https://www.godeye.club/2021/05/14/0

Dec 30, 2022
C++ POC to write addintional credentials into LSASS process

LSASS_Injection_CreateProcessWithLogonW C++ POC to write addintional credentials into LSASS process Usage: LSASS_Injection_CreateProcessWithLogonW USE

Feb 9, 2022
A Beacon Object File that creates a minidump of the LSASS process.
A Beacon Object File that creates a minidump of the LSASS process.

NanoDump A Beacon Object File that creates a minidump of the LSASS process. Features It uses syscalls (with SysWhispers2) for most operations You can

Jan 5, 2023
PIC lsass dumper using cloned handles
PIC lsass dumper using cloned handles

HandleKatz This tool was implemented as part of our Brucon2021 conference talk and demonstrates the usage of cloned handles to Lsass in order to creat

Dec 28, 2022
Skrull is a malware DRM, that prevents Automatic Sample Submission by AV/EDR and Signature Scanning from Kernel.
Skrull is a malware DRM, that prevents Automatic Sample Submission by AV/EDR and Signature Scanning from Kernel.

Skrull is a malware DRM, that prevents Automatic Sample Submission by AV/EDR and Signature Scanning from Kernel. It generates launchers that can run malware on the victim using the Process Ghosting technique. Also, launchers are totally anti-copy and naturally broken when got submitted.

Dec 10, 2022
Project to check which Nt/Zw functions your local EDR is hooking

Probatorum EDR Userland Hook Checker Probatorum will check which Nt/Zw functions your local EDR is hooking. Most credit for this code goes to SolomonS

Nov 15, 2022
Proof of concept Beacon Object File (BOF) that attempts to detect userland hooks in place by AV/EDR

Detect-Hooks Detect-Hooks is a proof of concept Beacon Object File (BOF) that attempts to detect userland API hooks in place by AV/EDR. The BOF will r

Dec 25, 2022
RefleXXion is a utility designed to aid in bypassing user-mode hooks utilised by AV/EPP/EDR etc
RefleXXion is a utility designed to aid in bypassing user-mode hooks utilised by AV/EPP/EDR etc

Introduction RefleXXion is a utility designed to aid in bypassing user-mode hooks utilised by AV/EPP/EDR etc. In order to bypass the user-mode hooks,

Dec 26, 2022