Skip to content

Commit 98cd9d2

Browse files
committed
Initial commit
1 parent 400a636 commit 98cd9d2

File tree

4 files changed

+651
-1
lines changed

4 files changed

+651
-1
lines changed

EDRenum-BOF.c

+252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
#include <windows.h>
2+
#include <tlhelp32.h>
3+
#include <psapi.h>
4+
#include "beacon.h"
5+
6+
#define MAX_EDR_STRINGS 200
7+
#define MAX_EDR_STRING_LENGTH 50
8+
#define MAX_PATH_LENGTH MAX_PATH
9+
10+
//KERNEL32
11+
WINBASEAPI HANDLE WINAPI KERNEL32$CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID);
12+
WINBASEAPI WINBOOL WINAPI KERNEL32$Process32First(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
13+
WINBASEAPI WINBOOL WINAPI KERNEL32$Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
14+
WINBASEAPI WINBOOL WINAPI KERNEL32$CloseHandle(HANDLE hObject);
15+
WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, WINBOOL bInheritHandle, DWORD dwProcessId);
16+
WINBASEAPI DWORD WINAPI KERNEL32$QueryFullProcessImageNameA(HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize);
17+
WINBASEAPI HANDLE WINAPI KERNEL32$FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData);
18+
WINBASEAPI BOOL WINAPI KERNEL32$FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData);
19+
WINBASEAPI BOOL WINAPI KERNEL32$FindClose(HANDLE hFindFile);
20+
//ADVAPI
21+
WINBASEAPI SC_HANDLE WINAPI ADVAPI32$OpenSCManagerA(LPCSTR lpMachineName, LPCSTR lpDatabaseName, DWORD dwDesiredAccess);
22+
WINBASEAPI SC_HANDLE WINAPI ADVAPI32$OpenServiceA(SC_HANDLE hSCManager, LPCSTR lpServiceName, DWORD dwDesiredAccess);
23+
WINBASEAPI BOOL WINAPI ADVAPI32$QueryServiceConfigA(SC_HANDLE hService, LPQUERY_SERVICE_CONFIGA lpServiceConfig, DWORD cbBufSize, LPDWORD pcbBytesNeeded);
24+
WINBASEAPI BOOL WINAPI ADVAPI32$CloseServiceHandle(SC_HANDLE hSCObject);
25+
WINBASEAPI BOOL WINAPI ADVAPI32$EnumServicesStatusExA(SC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned, LPDWORD lpResumeHandle, LPCSTR pszGroupName);
26+
//PSAPI
27+
WINBASEAPI DWORD WINAPI PSAPI$GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
28+
//MSVCRT
29+
WINBASEAPI void *__cdecl MSVCRT$memcpy(void * __restrict__ _Dst,const void * __restrict__ _Src,size_t _MaxCount);
30+
WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
31+
WINBASEAPI int __cdecl MSVCRT$strcmp(const char *_Str1,const char *_Str2);
32+
WINBASEAPI size_t __cdecl MSVCRT$strlen(const char *_Str);
33+
WINBASEAPI int __cdecl MSVCRT$_stricmp(const char *string1,const char *string2);
34+
WINBASEAPI char * __cdecl MSVCRT$strstr(const char *haystack, const char *needle);
35+
WINBASEAPI char * __cdecl MSVCRT$strcpy(char * __restrict__ _Dest, const char * __restrict__ _Source);
36+
WINBASEAPI int __cdecl MSVCRT$sprintf(char *__stream, const char *__format, ...);
37+
WINBASEAPI void* WINAPI MSVCRT$malloc(SIZE_T);
38+
DECLSPEC_IMPORT void WINAPI MSVCRT$free(void*);
39+
40+
char edrList[MAX_EDR_STRINGS][MAX_EDR_STRING_LENGTH] = {
41+
"activeconsole", "ADA-PreCheck", "ahnlab", "amsi.dll", "anti malware", "anti-malware",
42+
"antimalware", "anti virus", "anti-virus", "antivirus", "appsense", "attivo networks",
43+
"attivonetworks", "authtap", "avast", "avecto", "bitdefender", "blackberry", "canary",
44+
"carbonblack", "carbon black", "cb.exe", "check point", "ciscoamp", "cisco amp",
45+
"countercept", "countertack", "cramtray", "crssvc", "crowdstrike", "csagent", "csfalcon",
46+
"csshell", "cybereason", "cyclorama", "cylance", "cynet", "cyoptics", "cyupdate", "cyvera",
47+
"cyserver", "cytray", "darktrace", "deep instinct", "defendpoint", "defender", "eectrl",
48+
"elastic", "endgame", "f-secure", "forcepoint", "fortinet", "fireeye", "groundling",
49+
"GRRservic", "harfanglab", "inspector", "ivanti", "juniper networks", "kaspersky", "lacuna",
50+
"logrhythm", "malware", "malwarebytes", "mandiant", "mcafee", "morphisec", "msascuil",
51+
"msmpeng", "mssense", "nissrv", "omni", "omniagent", "osquery", "Palo Alto Networks", "pgeposervice",
52+
"pgsystemtray", "privilegeguard", "procwall", "protectorservic", "qianxin", "qradar",
53+
"qualys", "rapid7", "redcloak", "red canary", "SanerNow", "sangfor", "secureworks",
54+
"securityhealthservice", "semlaunchsv", "sentinel", "sentinelone", "sepliveupdat",
55+
"sisidsservice", "sisipsservice", "sisipsutil", "smc.exe", "smcgui", "snac64", "somma",
56+
"sophos", "splunk", "srtsp", "symantec", "symcorpu", "symefasi", "sysinternal", "sysmon",
57+
"tanium", "tda.exe", "tdawork", "tehtris", "threat", "trellix", "tpython", "trend micro",
58+
"uptycs", "vectra", "watchguard", "wincollect", "windowssensor", "wireshark", "withsecure",
59+
"xagt.exe", "xagtnotif.exe"
60+
};
61+
62+
char bof_tolower(char c) {
63+
if (c >= 'A' && c <= 'Z') {
64+
return c + 32;
65+
}
66+
return c;
67+
}
68+
69+
void toLower(char* str) {
70+
for (int i = 0; str[i]; i++) {
71+
str[i] = bof_tolower(str[i]);
72+
}
73+
}
74+
75+
void safe_strncpy(char* dest, const char* src, size_t n) {
76+
size_t src_len = MSVCRT$strlen(src);
77+
size_t copy_len = (src_len < n) ? src_len : n - 1;
78+
MSVCRT$memcpy(dest, src, copy_len);
79+
dest[copy_len] = '\0';
80+
}
81+
82+
int isEDRString(const char* str) {
83+
char lowerStr[MAX_PATH];
84+
safe_strncpy(lowerStr, str, MAX_PATH);
85+
toLower(lowerStr);
86+
87+
for (int i = 0; i < MAX_EDR_STRINGS && edrList[i][0] != '\0'; i++) {
88+
char lowerEDR[MAX_EDR_STRING_LENGTH];
89+
safe_strncpy(lowerEDR, edrList[i], MAX_EDR_STRING_LENGTH);
90+
toLower(lowerEDR);
91+
92+
if (MSVCRT$strstr(lowerStr, lowerEDR) != NULL) {
93+
return 1;
94+
}
95+
}
96+
return 0;
97+
}
98+
99+
void checkProcesses(formatp *obj) {
100+
BeaconFormatPrintf(obj, "\n===== Processes =====\n");
101+
102+
HANDLE hSnapshot = KERNEL32$CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
103+
if (hSnapshot == INVALID_HANDLE_VALUE) {
104+
BeaconFormatPrintf(obj, "[-] Failed to create process snapshot\n");
105+
return;
106+
}
107+
108+
PROCESSENTRY32 pe32;
109+
pe32.dwSize = sizeof(PROCESSENTRY32);
110+
111+
if (!KERNEL32$Process32First(hSnapshot, &pe32)) {
112+
BeaconFormatPrintf(obj, "[-] Failed to get first process\n");
113+
KERNEL32$CloseHandle(hSnapshot);
114+
return;
115+
}
116+
117+
int foundSuspicious = 0;
118+
do {
119+
char path[MAX_PATH_LENGTH] = {0};
120+
121+
HANDLE hProcess = KERNEL32$OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
122+
if (hProcess) {
123+
if (PSAPI$GetModuleFileNameExA(hProcess, NULL, path, MAX_PATH_LENGTH) == 0) {
124+
DWORD pathSize = MAX_PATH_LENGTH;
125+
if (!KERNEL32$QueryFullProcessImageNameA(hProcess, 0, path, &pathSize)) {
126+
MSVCRT$strcpy(path, "Path unavailable");
127+
}
128+
}
129+
KERNEL32$CloseHandle(hProcess);
130+
} else {
131+
MSVCRT$strcpy(path, "Access denied");
132+
}
133+
134+
if (isEDRString(pe32.szExeFile) || isEDRString(path)) {
135+
BeaconFormatPrintf(obj, "[!] Suspicious process found:\n");
136+
BeaconFormatPrintf(obj, "\tName: %s\n", pe32.szExeFile);
137+
BeaconFormatPrintf(obj, "\tPath: %s\n", path);
138+
BeaconFormatPrintf(obj, "\tPID: %lu\n\n", pe32.th32ProcessID);
139+
foundSuspicious = 1;
140+
}
141+
142+
} while (KERNEL32$Process32Next(hSnapshot, &pe32));
143+
144+
KERNEL32$CloseHandle(hSnapshot);
145+
146+
if (!foundSuspicious) {
147+
BeaconFormatPrintf(obj, "[+] No suspicious processes found\n\n");
148+
}
149+
}
150+
151+
void checkDirectories(formatp *obj) {
152+
BeaconFormatPrintf(obj, "\n===== Directories =====\n");
153+
const char* directories[] = {
154+
"C:\\Program Files",
155+
"C:\\Program Files (x86)",
156+
"C:\\ProgramData"
157+
};
158+
int foundSuspicious = 0;
159+
for (int i = 0; i < 3; i++) {
160+
WIN32_FIND_DATAA findFileData;
161+
char searchPath[MAX_PATH];
162+
MSVCRT$sprintf(searchPath, "%s\\*", directories[i]);
163+
HANDLE hFind = KERNEL32$FindFirstFileA(searchPath, &findFileData);
164+
if (hFind != INVALID_HANDLE_VALUE) {
165+
do {
166+
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
167+
if (MSVCRT$strcmp(findFileData.cFileName, ".") != 0 && MSVCRT$strcmp(findFileData.cFileName, "..") != 0) {
168+
if (isEDRString(findFileData.cFileName)) {
169+
BeaconFormatPrintf(obj, "[!] Suspicious directory found: %s\\%s\n", directories[i], findFileData.cFileName);
170+
foundSuspicious = 1;
171+
}
172+
}
173+
}
174+
} while (KERNEL32$FindNextFileA(hFind, &findFileData) != 0);
175+
KERNEL32$FindClose(hFind);
176+
}
177+
}
178+
if (!foundSuspicious) {
179+
BeaconFormatPrintf(obj, "[+] No suspicious directories found\n\n");
180+
}
181+
}
182+
183+
void checkServices(formatp *obj) {
184+
BeaconFormatPrintf(obj, "\n===== Services =====\n");
185+
SC_HANDLE hSCManager = ADVAPI32$OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
186+
if (hSCManager == NULL) {
187+
BeaconFormatPrintf(obj, "[-] Failed to open Service Control Manager\n");
188+
return;
189+
}
190+
DWORD bytesNeeded = 0;
191+
DWORD servicesReturned = 0;
192+
DWORD resumeHandle = 0;
193+
ADVAPI32$EnumServicesStatusExA(hSCManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &bytesNeeded, &servicesReturned, &resumeHandle, NULL);
194+
ENUM_SERVICE_STATUS_PROCESSA* services = (ENUM_SERVICE_STATUS_PROCESSA*)MSVCRT$malloc(bytesNeeded);
195+
if (services == NULL) {
196+
BeaconFormatPrintf(obj, "[-] Failed to allocate memory for services\n");
197+
ADVAPI32$CloseServiceHandle(hSCManager);
198+
return;
199+
}
200+
if (!ADVAPI32$EnumServicesStatusExA(hSCManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE)services, bytesNeeded, &bytesNeeded, &servicesReturned, &resumeHandle, NULL)) {
201+
BeaconFormatPrintf(obj, "[-] Failed to enumerate services\n");
202+
MSVCRT$free(services);
203+
ADVAPI32$CloseServiceHandle(hSCManager);
204+
return;
205+
}
206+
int foundSuspicious = 0;
207+
for (DWORD i = 0; i < servicesReturned; i++) {
208+
SC_HANDLE hService = ADVAPI32$OpenServiceA(hSCManager, services[i].lpServiceName, SERVICE_QUERY_CONFIG);
209+
if (hService) {
210+
DWORD bytesNeeded = 0;
211+
ADVAPI32$QueryServiceConfigA(hService, NULL, 0, &bytesNeeded);
212+
QUERY_SERVICE_CONFIGA* pServiceConfig = (QUERY_SERVICE_CONFIGA*)MSVCRT$malloc(bytesNeeded);
213+
if (pServiceConfig != NULL) {
214+
if (ADVAPI32$QueryServiceConfigA(hService, pServiceConfig, bytesNeeded, &bytesNeeded)) {
215+
char serviceInfo[MAX_PATH * 3];
216+
MSVCRT$sprintf(serviceInfo, "%s - %s - %s",
217+
services[i].lpServiceName,
218+
services[i].lpDisplayName,
219+
pServiceConfig->lpBinaryPathName);
220+
if (isEDRString(serviceInfo)) {
221+
BeaconFormatPrintf(obj, "[!] Suspicious service found:\n");
222+
BeaconFormatPrintf(obj, "\tName: %s\n", services[i].lpServiceName);
223+
BeaconFormatPrintf(obj, "\tDisplay Name: %s\n", services[i].lpDisplayName);
224+
BeaconFormatPrintf(obj, "\tBinary Path: %s\n\n", pServiceConfig->lpBinaryPathName);
225+
foundSuspicious = 1;
226+
}
227+
}
228+
MSVCRT$free(pServiceConfig);
229+
}
230+
ADVAPI32$CloseServiceHandle(hService);
231+
}
232+
}
233+
MSVCRT$free(services);
234+
ADVAPI32$CloseServiceHandle(hSCManager);
235+
if (!foundSuspicious) {
236+
BeaconFormatPrintf(obj, "[+] No suspicious services found\n\n");
237+
}
238+
}
239+
240+
void go(char* args, int len) {
241+
formatp obj;
242+
BeaconFormatAlloc(&obj, 8192);
243+
244+
checkProcesses(&obj);
245+
checkDirectories(&obj);
246+
checkServices(&obj);
247+
248+
int size = 0;
249+
char* output = BeaconFormatToString(&obj, &size);
250+
BeaconOutput(CALLBACK_OUTPUT, output, size);
251+
BeaconFormatFree(&obj);
252+
}

EDRenum-BOF.cna

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
alias EDRenum {
2+
3+
$handle = openf(script_resource("EDRenum-BOF.o"));
4+
$bof = readb($handle, -1);
5+
closef($handle);
6+
7+
$args = bof_pack($1 , "i", $pid);
8+
9+
beacon_inline_execute($1, $bof, "go");
10+
}
11+
12+
beacon_command_register("EDRenum", "EDR and AV enumeration", "Synopsis: Identify EDR processes, directories, and services");

README.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,16 @@
1-
# EDRenum-BOF
1+
# EDRenum-BOF
2+
3+
Identify common EDR processes, directories, and services. Simple BOF of [Invoke-EDRChecker](https://github.com/PwnDexter/Invoke-EDRChecker).
4+
5+
## Compile
6+
7+
BOF
8+
```
9+
x86_64-w64-mingw32-gcc -c EDRenum-BOF.c -o EDRenum-BOF.o
10+
```
11+
12+
## CS
13+
14+
- load .cna
15+
16+
![EDRenum-BOF](https://github.com/user-attachments/assets/43411187-322e-4969-bd3e-1cb443084ba8)

0 commit comments

Comments
 (0)