diff --git a/CAPE/Injection.c b/CAPE/Injection.c index 248b0836..f6631528 100644 --- a/CAPE/Injection.c +++ b/CAPE/Injection.c @@ -31,7 +31,7 @@ along with this program.If not, see . #include "Shlwapi.h" #pragma comment(lib, "shlwapi.lib") -#pragma warning(push ) +#pragma warning(push) #pragma warning(disable : 4996) extern _NtMapViewOfSection pNtMapViewOfSection; @@ -46,6 +46,37 @@ extern char *our_process_name; extern void hook_disable(); extern void hook_enable(); +BOOL is_system_process(DWORD ProcessId) +{ + char processName[MAX_PATH] = {0}; + HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, ProcessId); + if (hProcess) { + char processPath[MAX_PATH]; + if (GetProcessImageFileName(hProcess, processPath, MAX_PATH)) { + char *fileName = strrchr(processPath, '\\'); + if (fileName) { + strncpy(processName, fileName + 1, MAX_PATH - 1); + } + } + CloseHandle(hProcess); + } + + // Process name filtering - exclude system processes + const char *systemProcesses[] = { + "services.exe", "svchost.exe", "WmiPrvSE.exe", "wininit.exe", + "winlogon.exe", "lsass.exe", "csrss.exe", "smss.exe", + "explorer.exe", "dwm.exe", "conhost.exe", "audiodg.exe" + }; + + for (int i = 0; i < sizeof(systemProcesses) / sizeof(systemProcesses[0]); i++) { + if (!_stricmp(processName, systemProcesses[i])) { + return TRUE; + } + } + + return FALSE; +} + //************************************************************************************** PINJECTIONINFO GetInjectionInfo(DWORD ProcessId) //************************************************************************************** @@ -53,6 +84,7 @@ PINJECTIONINFO GetInjectionInfo(DWORD ProcessId) DWORD CurrentProcessId; PINJECTIONINFO CurrentInjectionInfo = InjectionInfoList; + while (CurrentInjectionInfo) { CurrentProcessId = CurrentInjectionInfo->ProcessId; @@ -677,7 +709,7 @@ void CreateProcessHandler(LPWSTR lpApplicationName, LPWSTR lpCommandLine, LPPROC DebugOutput("CreateProcessHandler: Injection info set for new process %d, ImageBase: 0x%p", CurrentInjectionInfo->ProcessId, CurrentInjectionInfo->ImageBase); } -PCHAR OpenProcessHandler(HANDLE ProcessHandle, DWORD Pid) +PCHAR OpenProcessHandler(HANDLE ProcessHandle, DWORD Pid, ACCESS_MASK DesiredAccess) { struct InjectionInfo *CurrentInjectionInfo; char DevicePath[MAX_PATH]; @@ -685,6 +717,7 @@ PCHAR OpenProcessHandler(HANDLE ProcessHandle, DWORD Pid) if (Pid == GetCurrentProcessId()) return NULL; + CurrentInjectionInfo = GetInjectionInfo(Pid); @@ -1126,7 +1159,7 @@ void ProcessMessage(DWORD ProcessId, DWORD ThreadId) DebugOutput("ProcessMessage: Skipping monitoring process %d", ProcessId); return; } - + if (g_config.single_process) { DebugOutput("ProcessMessage: Skipping monitoring process %d as single-process mode set.", ProcessId); @@ -1194,7 +1227,7 @@ void ProcessMessage(DWORD ProcessId, DWORD ThreadId) swprintf_s(CommandLine, MAX_PATH, L"%s inject %u %u %s", Loader, ProcessId, ThreadId, our_dll_path_w); } #endif - } + } hook_disable(); if (CreateProcessW(NULL, CommandLine, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &StartupInfoEx.StartupInfo, &ProcInfo)) { diff --git a/CAPE/Injection.h b/CAPE/Injection.h index 54d4f650..03055511 100644 --- a/CAPE/Injection.h +++ b/CAPE/Injection.h @@ -66,9 +66,10 @@ PINJECTIONINFO GetInjectionInfoFromHandle(HANDLE ProcessHandle); PINJECTIONINFO CreateInjectionInfo(DWORD ProcessId); BOOL DropInjectionInfo(HANDLE ProcessHandle); void CreateProcessHandler(LPWSTR lpApplicationName, LPWSTR lpCommandLine, LPPROCESS_INFORMATION lpProcessInformation); -PCHAR OpenProcessHandler(HANDLE ProcessHandle, DWORD Pid); +PCHAR OpenProcessHandler(HANDLE ProcessHandle, DWORD Pid, ACCESS_MASK DesiredAccess); void ResumeProcessHandler(HANDLE ProcessHandle, DWORD Pid); void MapSectionViewHandler(HANDLE ProcessHandle, HANDLE SectionHandle, PVOID BaseAddress, SIZE_T ViewSize); void UnmapSectionViewHandler(PVOID BaseAddress); void WriteMemoryHandler(HANDLE ProcessHandle, LPVOID BaseAddress, LPCVOID Buffer, SIZE_T NumberOfBytesWritten); void TerminateHandler(); +BOOL is_system_process(DWORD ProcessId); diff --git a/config.c b/config.c index e0715656..63294ef6 100644 --- a/config.c +++ b/config.c @@ -1249,11 +1249,16 @@ void parse_config_line(char* line) else if (g_config.unpacker == 2) DebugOutput("Active unpacking of payloads enabled\n"); } - else if (!stricmp(key, "injection")) { //When set to 1 this will enable CAPE’s capture of injected payloads between processes + else if (!stricmp(key, "injection")) { //When set to 1 this will enable CAPE�s capture of injected payloads between processes g_config.injection = value[0] == '1'; if (g_config.injection) DebugOutput("Capture of injected payloads enabled.\n"); } + else if (!stricmp(key, "filter-system-injection")) { //When set to 1 this will enable filtering of system injection based on process names and access patterns + g_config.filter_system_injection = value[0] == '1'; + if (g_config.filter_system_injection) + DebugOutput("System injection filtering enabled.\n"); + } else if (!stricmp(key, "dump-config-region")) { g_config.dump_config_region = value[0] == '1'; if (g_config.dump_config_region) @@ -1405,6 +1410,10 @@ void read_config(void) g_config.dump_limit = DUMP_LIMIT; g_config.dropped_limit = 0; g_config.injection = 1; + + g_config.filter_system_injection = 1; + g_config.filter_system_safe_process_pid = 0; + g_config.unpacker = 1; g_config.api_cap = 5000; g_config.api_rate_cap = 1; @@ -1675,4 +1684,4 @@ void read_config(void) } return; -} +} \ No newline at end of file diff --git a/config.h b/config.h index c10ceae3..9e11d85a 100644 --- a/config.h +++ b/config.h @@ -168,6 +168,9 @@ struct _g_config { int unpacker; int injection; + int filter_system_injection; + int filter_system_safe_process_pid; + // should we dump each process on exit/analysis timeout? int procdump; int procmemdump; diff --git a/hook_process.c b/hook_process.c index 6b342b5d..45d45b7f 100644 --- a/hook_process.c +++ b/hook_process.c @@ -518,14 +518,29 @@ HOOKDEF(NTSTATUS, WINAPI, NtOpenProcess, } ret = Old_NtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId); + + + if (g_config.filter_system_injection) { + ACCESS_MASK legitimate_flags = PROCESS_QUERY_INFORMATION | + PROCESS_QUERY_LIMITED_INFORMATION | + PROCESS_VM_READ | PROCESS_DUP_HANDLE | + SYNCHRONIZE; + + if ((DesiredAccess & ~legitimate_flags) == 0 && is_system_process(pid)) { + g_config.filter_system_safe_process_pid = pid; + } + } + if (NT_SUCCESS(ret) && g_config.injection) - ProcessName = OpenProcessHandler(*ProcessHandle, pid); + ProcessName = OpenProcessHandler(*ProcessHandle, pid, DesiredAccess); if (ProcessName) LOQ_ntstatus("process", "Phis", "ProcessHandle", ProcessHandle, "DesiredAccess", DesiredAccess, "ProcessIdentifier", pid, "ProcessName", ProcessName); + else LOQ_ntstatus("process", "Phi", "ProcessHandle", ProcessHandle, "DesiredAccess", DesiredAccess, "ProcessIdentifier", pid); + return ret; } diff --git a/hook_window.c b/hook_window.c index 8bf7b296..db07884d 100644 --- a/hook_window.c +++ b/hook_window.c @@ -23,8 +23,10 @@ along with this program. If not, see . #include "pipe.h" #include "log.h" + #define StringAtomSize 0x100 +extern void DebugOutput(_In_ LPCTSTR lpOutputString, ...); extern void ProcessMessage(DWORD ProcessId, DWORD ThreadId); extern void DumpSectionViewsForPid(DWORD Pid); @@ -189,6 +191,7 @@ HOOKDEF(BOOL, WINAPI, PostMessageW, return ret; } + HOOKDEF(BOOL, WINAPI, PostThreadMessageA, _In_ DWORD idThread, _In_ UINT Msg, @@ -198,17 +201,22 @@ HOOKDEF(BOOL, WINAPI, PostThreadMessageA, BOOL ret = Old_PostThreadMessageA(idThread, Msg, wParam, lParam); DWORD pid = GetThreadProcessId(idThread); + + LOQ_bool("windows", "iii", "ProcessId", pid, "ThreadId", idThread, "Message", Msg); if (pid && pid != GetCurrentProcessId()) { DumpSectionViewsForPid(pid); - ProcessMessage(pid, 0); + // ProcessMessage(pid, 0); } - - LOQ_bool("windows", "iii", "ProcessId", pid, "ThreadId", idThread, "Message", Msg); + if (g_config.filter_system_injection && pid == g_config.filter_system_safe_process_pid) { + return FALSE; + } + ProcessMessage(pid, 0); return ret; } + HOOKDEF(BOOL, WINAPI, PostThreadMessageW, _In_ DWORD idThread, _In_ UINT Msg, @@ -218,13 +226,17 @@ HOOKDEF(BOOL, WINAPI, PostThreadMessageW, BOOL ret = Old_PostThreadMessageW(idThread, Msg, wParam, lParam); DWORD pid = GetThreadProcessId(idThread); + LOQ_bool("windows", "iii", "ProcessId", pid, "ThreadId", idThread, "Message", Msg); + if (pid && pid != GetCurrentProcessId()) { DumpSectionViewsForPid(pid); - ProcessMessage(pid, 0); + // ProcessMessage(pid, 0); } - - LOQ_bool("windows", "iii", "ProcessId", pid, "ThreadId", idThread, "Message", Msg); + if (g_config.filter_system_injection && pid == g_config.filter_system_safe_process_pid) { + return FALSE; + } + ProcessMessage(pid, 0); return ret; } @@ -274,8 +286,12 @@ HOOKDEF(BOOL, WINAPI, SendNotifyMessageA, our_GetWindowThreadProcessId(hWnd, &pid); if (pid != GetCurrentProcessId()) { DumpSectionViewsForPid(pid); - ProcessMessage(pid, 0); + //ProcessMessage(pid, 0); + } + if (g_config.filter_system_injection && pid == g_config.filter_system_safe_process_pid) { + return FALSE; } + ProcessMessage(pid, 0); } set_lasterrors(&lasterror); @@ -301,8 +317,12 @@ HOOKDEF(BOOL, WINAPI, SendNotifyMessageW, our_GetWindowThreadProcessId(hWnd, &pid); if (pid != GetCurrentProcessId()) { DumpSectionViewsForPid(pid); - ProcessMessage(pid, 0); + // ProcessMessage(pid, 0); + } + if (g_config.filter_system_injection && pid == g_config.filter_system_safe_process_pid) { + return FALSE; } + ProcessMessage(pid, 0); } set_lasterrors(&lasterror); @@ -524,4 +544,4 @@ HOOKDEF(int, WINAPI, MessageBoxTimeoutW, else LOQ_zero("windows", "uui", "Text", lpszText, "Caption", lpszCaption, "Timeout", dwTimeout); return ret; -} +} \ No newline at end of file