GithubHelp home page GithubHelp logo

edrsandblast's People

Contributors

johnlatwc avatar laxa avatar maxbeckmann avatar nikaiw avatar nuts7 avatar qazeer avatar themaks avatar v1k1ngfr avatar xalicex avatar zeronounours avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

edrsandblast's Issues

UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE assumes patch starts at function start

In the function getSafeVirtualProtectUsingTrampoline, the method UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE creates the trampoline from function start to (function start + patchsize). This does not work, if the patch does not start at the beginning of the function. In my opinion, instead of using patchSize, "sizeFromFunctionStart" should be used. E.g. like this:

size_t sizeFromFunctionStart = (size_t)patchAddr - (size_t)mem_NtProtectVirtualMemory + patchSize;
PBYTE trampoline = VirtualAlloc(NULL, sizeFromFunctionStart + JUMP_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (NULL == trampoline) {
	debugf("\tError : VirtualAlloc: 0x%x\n\n", GetLastError());
	exit(1);
}
DWORD oldProtect;
memcpy(trampoline, disk_NtProtectVirtualMemory, sizeFromFunctionStart);
#if _WIN64
* ((WORD*)(trampoline + sizeFromFunctionStart)) = 0x25FF; //RIP relative jmp
*((DWORD*)(trampoline + sizeFromFunctionStart + 2)) = 0x0; // [RIP + 0]
*((QWORD*)(trampoline + sizeFromFunctionStart + 2 + 4)) = (QWORD)(((BYTE*)mem_NtProtectVirtualMemory) + sizeFromFunctionStart);
#else
* (trampoline + sizeFromFunctionStart) = 0xE9; //far JMP
*((DWORD*)(trampoline + sizeFromFunctionStart + 1)) = (DWORD)(((DWORD)mem_NtProtectVirtualMemory) + sizeFromFunctionStart - (((DWORD)trampoline) + sizeFromFunctionStart + JUMP_SIZE));
#endif
VirtualProtect(trampoline, sizeFromFunctionStart + JUMP_SIZE, PAGE_EXECUTE_READ, &oldProtect);

Did I missunderstand something? If not I will gladlay create a pull request.

Thanks!

Wait for minidump exfiltration before re-enabling the EDR's capabilities

Currently, the Minifilter unhooking allow file operations to be carried on without being worried by the EDR. This means that after process dumping, the minidump file write on disk will not trigger EDR's analysis.
However, after the file is written, the default behavior of EDRSanblast is to revert all changes that impaired the EDR before existing; thus, when trying to access the minidump file afterward (for extraction on an unmonitored machine, or for deletion), EDR's code might be triggered and the file analyzed, potentially triggering an alert.

It could be very useful to implement a CLI option (--wait-for-dump-exfiltration ?) that changes the behavior of EDRSandblast so that after writing minidump file, the execution of EDRSandblast is paused until the file has "disappeared" (copied and removed by another method), then the execution resumes and EDR's hooks are restored.

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??

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.

Project needs to be recompiled if used with a different vulnerable driver

A usability problem

Currently, while using EDRSandblast, if a specific driver is blocked at loading by the EDR or Microsoft's blacklist, the whole project needs to be recompiled by changing a switch in KernelMemoryPrimitives.h


While this guarantees that only the exploit code of one driver will be embedded in the binary at a time, it makes the process of changing driver a bit tedious, especially if it's just for testing things or for a non "opsec-critical" pentest.

Proposed solution

Another mode should be added (e.g. #define VULN_DRIVER ALL) in order to compile all R/W primitives, and make WriteMemory, ReadMemory and CloseDriverHandle function pointers dynamically point at the appropriate functions, depending on the provided vulnerable driver.
A robust way to identify a vulnerable driver is to compute its authenticode or get it from its certificate. A code base is already existing to extract the signer from its certificate (see https://github.com/wavestone-cdt/EDRSandblast/blob/4d2789b21b4ef48b1757bcb63dce5cdbf1a121f9/EDRSandblast/Utils/SignatureOps.c ) so it should be easy to create a GetFileAuthenticode function from the same structure.

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.

TODO: check if 24H2 edition of Windows breaks things in EDRSandblast and fix them if needed

https://windows-internals.com/kaslr-leaks-restriction/ : many userland APIs now restrict processes to access kernel addresses, in order not to break KASLR and make kernel exploits more complex. This does not affect processes with SeDebugPrivilege though so it is not a long term problem for EDRSandblast (Microsoft's goal is to harden the user->admin boundary; not the usermode-admin->kernelmode one).

This should break some of EDRSandblast code if we do not enable SeDebugPrivilege before calling APIs that are used to leak kernel pointer (such as kernel module addresses, kernel objects' handles, etc.)

TODO: review the code and ensure the privilege is set before these operations.
(I am noting this here as a reminder to myself since it could break EDRSandblast in the near future; but if someone wants to contribute, be my guest 😃 )

Can you share the core files ?

Can you share all the core files involved in NtoskrnlOffsets.csv, if I want to find some offsets, I don’t have to search hard,thanks

EDRSandblast_API does not restore MiniFilter Callbacks

In EDRSandblast_API -> Krnlmode_RestoreAllMonitoring, EnableEDRProcessAndThreadObjectsCallbacks is called twice instead of RestoreEDRMinifilterCallbacks.
I tested the change and RestoreEDRMinifilterCallbacks seems to work great.

Will make the pull request.

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).

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

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.