edrsandblast's People
Forkers
topotam minkione maubertin riskydissonance htts3at eniac888 adversaryemulator who1smrrobot bharadwajyas sharyloop fuckup1337 techthupport analyticsearch gavz freeide grayswandin slyd0g cybersecops cyrillefranchet rileyzink yougar0 bl4d3666 scriptidiot mebuis goowen veath1 yangfan6888 solacol peta909 asdlei99 inosec2 superuser5 zeronounours viper-sec gdraperi johnlatwc majid-derkaoui askyeye mmmmcoffee sensi-1337 827dream fengjixuchui johnjohnsp1 t43wiu6 xalicex invokethreatguy a10ncoder bravery9 icinder xistens wisdark jilvan1234 tomyang9 toomding killvxk prageeth1985 codingman v4nyl gladiatx0r slooppe uakbr kennyzeng bopin2020 kangd1w2 gitwk86 heyzm suraj51k th30c0der arryboom korallin alehacksp justinforbes jembsd kopfjager007 webyeti jermainlaforce usama7628674 daffodi1 lucabongiorni zha0 crackercat anti-ghosts sp00ks-git 0xajstrike benheise dn3ro filipesam blahblah5555 nocomp useful-gw beerandgin killaragorn lee-sh827 0xrobert wumn290 sh3ll0ck3r gysf666 clayne lunarobliq seeeyouuedrsandblast's Issues
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.
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).
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 😃 )
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.
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
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
This should not happen, aborting...
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.
Implement userland ETW-Ti impairing
In --usermode
mode, we should implement this https://www.riskinsight-wavestone.com/en/2023/10/a-universal-edr-bypass-built-in-windows-10/ for both auditing the state of these flags for a target process (or all processes) and also for disabling it for the target process of the dump operation
Error Starting Service on Windows 10 Pro 21H2 19044.1586
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??
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.
Cannot bypass Kaspersky
Cannot bypass Kaspersky when dump lsass
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!
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.
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.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.