unknown 2 жил өмнө
parent
commit
a0c668e71f

+ 23 - 0
KIT/FindFile/README.md

@@ -0,0 +1,23 @@
+# FindFile
+Search for matching files based on a word, extention or keyword in the file content. Wildcards are supported.
+
+>Keyword matching only works for text based files like .csv, .txt or .ps1 etc. So no MS Office files like .xlsx and .docs :(. 
+
+## Arguments
+* `<path to directory>`: specify a path to the directory from which to start searching (recursive searching supported).
+* `<search pattern>`: specify a single word or extention to search for (support wildcards).
+* `<keyword>`: leave empty OR specify a keyword to search for in text based files (support wildcards).
+
+## Usage
+* `findfile <path to directory> <search pattern> <(optional) keyword>`
+
+## Examples
+* `findfile C:\Users\RTO\Documents *.xlsx`
+* `findfile C:\Users\RTO *login*.* username`
+* `findfile C:\Users\RTO *.txt *pass*`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 69 - 0
KIT/FindFile/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 0
KIT/FindFile/bofcompile.bat

@@ -0,0 +1,5 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc findfile.c
+move /y findfile.obj findfile.o
+

+ 299 - 0
KIT/FindFile/findfile.c

@@ -0,0 +1,299 @@
+#include <windows.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include "findfile.h"
+#include "beacon.h"
+
+
+//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
+HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
+	HRESULT hr = S_FALSE;
+	va_list argList;
+	DWORD dwWritten = 0;
+
+	if (g_lpStream <= (LPSTREAM)1) {
+		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
+		if (FAILED(hr)) {
+			return hr;
+		}
+	}
+
+	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
+		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
+		if (g_lpwPrintBuffer == NULL) {
+			hr = E_FAIL;
+			goto CleanUp;
+		}
+	}
+
+	va_start(argList, lpwFormat);
+	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
+		hr = E_FAIL;
+		goto CleanUp;
+	}
+
+	if (g_lpStream != NULL) {
+		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
+			goto CleanUp;
+		}
+	}
+
+	hr = S_OK;
+
+CleanUp:
+
+	if (g_lpwPrintBuffer != NULL) {
+		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); // Clear print buffer.
+	}
+
+	va_end(argList);
+	return hr;
+}
+
+//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
+VOID BeaconOutputStreamW() {
+	STATSTG ssStreamData = { 0 };
+	SIZE_T cbSize = 0;
+	ULONG cbRead = 0;
+	LARGE_INTEGER pos;
+	LPWSTR lpwOutput = NULL;
+
+	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
+		return;
+	}
+
+	cbSize = ssStreamData.cbSize.LowPart;
+	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
+	if (lpwOutput != NULL) {
+		pos.QuadPart = 0;
+		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
+			goto CleanUp;
+		}
+
+		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
+			goto CleanUp;
+		}
+
+		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
+	}
+
+CleanUp:
+	if (g_lpStream != NULL) {
+		g_lpStream->lpVtbl->Release(g_lpStream);
+		g_lpStream = NULL;
+	}
+
+	if (g_lpwPrintBuffer != NULL) {
+		MSVCRT$free(g_lpwPrintBuffer);
+		g_lpwPrintBuffer = NULL;
+	}
+
+	if (lpwOutput != NULL) {
+		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
+	}
+
+	return;
+}
+
+
+
+
+bool keywordMatches(const char* content, const char* keyword) {
+    size_t keywordLen = MSVCRT$strlen(keyword);
+    
+    // If keyword is "*example*"
+    if (keyword[0] == '*' && keyword[keywordLen - 1] == '*') {
+        char tempKeyword[MAX_PATH]; 
+        MSVCRT$strncpy(tempKeyword, keyword + 1, keywordLen - 2);
+        tempKeyword[keywordLen - 2] = '\0';
+        if (MSVCRT$strstr(content, tempKeyword)) {
+            return true;
+        }
+    }
+    // If keyword is "example*"
+    else if (keyword[keywordLen - 1] == '*') {
+        char tempKeyword[MAX_PATH];
+        MSVCRT$strncpy(tempKeyword, keyword, keywordLen - 1);
+        tempKeyword[keywordLen - 1] = '\0';
+        if (MSVCRT$strncmp(content, tempKeyword, keywordLen - 1) == 0) {
+            return true;
+        }
+    }
+    // If keyword is "*example"
+    else if (keyword[0] == '*') {
+        if (MSVCRT$strlen(content) >= keywordLen - 1 && 
+            MSVCRT$strcmp(content + MSVCRT$strlen(content) - (keywordLen - 1), keyword + 1) == 0) {
+            return true;
+        }
+    }
+    // If keyword is "example"
+    else if (MSVCRT$strstr(content, keyword)) {
+        return true;
+    }
+
+    return false;
+}
+
+
+
+bool SearchFileForKeyword(const char* filePath, const char* keyword) {
+    FILE *file = MSVCRT$fopen(filePath, "rb");  
+    if (!file) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to open file: %s\n", filePath);
+        return false;
+    }
+
+    MSVCRT$fseek(file, 0, SEEK_END);
+    long fileSize = MSVCRT$ftell(file);
+    MSVCRT$fseek(file, 0, SEEK_SET);
+
+    char* fileContents = (char*)MSVCRT$malloc(fileSize + 1); 
+    if(!fileContents) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to allocate memory for file: %s\n", filePath);
+        MSVCRT$fclose(file);
+        return false;
+    }
+    
+    MSVCRT$fread(fileContents, 1, fileSize, file);
+    fileContents[fileSize] = '\0';  
+    MSVCRT$fclose(file);
+
+    // Convert file contents to lowercase
+    for (long i = 0; i < fileSize; i++) {
+        fileContents[i] = MSVCRT$tolower(fileContents[i]);
+    }
+
+    // Convert keyword to lowercase
+    char* lowerKeyword = MSVCRT$_strdup(keyword);
+    if (!lowerKeyword) {
+        MSVCRT$free(fileContents);
+        return false;
+    }
+    for (int i = 0; lowerKeyword[i]; i++) {
+        lowerKeyword[i] = MSVCRT$tolower(lowerKeyword[i]);
+    }
+	
+	//match line with keyword and return pattern if true
+    wchar_t wideFullPath[MAX_PATH];
+    wchar_t wideKeyword[MAX_PATH]; 
+    wchar_t wideLine[MAX_PATH];  
+	
+    KERNEL32$MultiByteToWideChar(CP_ACP, 0, filePath, -1, wideFullPath, MAX_PATH);
+    KERNEL32$MultiByteToWideChar(CP_ACP, 0, keyword, -1, wideKeyword, MAX_PATH);
+	
+    char* line = MSVCRT$strtok(fileContents, "\n");
+    bool found = false;
+    bool firstPrint = true;
+    while (line) {
+        if (keywordMatches(line, lowerKeyword)) {
+            found = true;
+            KERNEL32$MultiByteToWideChar(CP_ACP, 0, line, -1, wideLine, MAX_PATH);
+            
+            if (firstPrint) {
+                BeaconPrintToStreamW(L"\n[+] Keyword '%ls' found in file: %ls\n", wideKeyword, wideFullPath);
+                firstPrint = false;
+            }
+            BeaconPrintToStreamW(L"\t- Matched on pattern: %ls\n", wideLine);
+            // break; //stop after first match
+        }
+        line = MSVCRT$strtok(NULL, "\n");
+    }
+
+    MSVCRT$free(fileContents);
+    MSVCRT$free(lowerKeyword);
+	
+    return found;
+}
+
+
+void SearchFilesRecursive(const char* lpFolder, const char* lpSearchPattern, const char* keyword) {
+    WIN32_FIND_DATAA findFileData;
+    HANDLE hFind = INVALID_HANDLE_VALUE;
+    char szDir[MAX_PATH];
+    DWORD dwError;
+
+    // Build search path for files in the current directory
+    MSVCRT$strcpy(szDir, lpFolder);
+    MSVCRT$strcat(szDir, "\\");
+    MSVCRT$strcat(szDir, lpSearchPattern);
+	
+	// Search for files
+    hFind = KERNEL32$FindFirstFileA(szDir, &findFileData);
+    if (hFind != INVALID_HANDLE_VALUE) {
+        do {
+			if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+				char fullPath[MAX_PATH];
+				MSVCRT$sprintf(fullPath, "%s\\%s", lpFolder, findFileData.cFileName);
+				
+				wchar_t wideFullPath[MAX_PATH];
+				KERNEL32$MultiByteToWideChar(CP_ACP, 0, fullPath, -1, wideFullPath, MAX_PATH);
+				
+				if (*keyword) { 
+				    SearchFileForKeyword(fullPath, keyword); 
+				} else if (!*keyword) {
+					BeaconPrintToStreamW(L"[+] File found: %ls\n", wideFullPath);
+				}
+			}
+		} while (KERNEL32$FindNextFileA(hFind, &findFileData) != 0);
+		
+		dwError = KERNEL32$GetLastError();
+		if (dwError != ERROR_NO_MORE_FILES) {
+			BeaconPrintf(CALLBACK_ERROR, "Error searching for next file: %d\n", dwError);
+		}
+		KERNEL32$FindClose(hFind);
+	}
+	
+	//search for subdirectories and recurse into them
+    MSVCRT$strcpy(szDir, lpFolder);
+    MSVCRT$strcat(szDir, "\\*");
+
+    hFind = KERNEL32$FindFirstFileA(szDir, &findFileData);
+    if (hFind != INVALID_HANDLE_VALUE) {
+        do {
+            if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
+                MSVCRT$strcmp(findFileData.cFileName, ".") != 0 && 
+                MSVCRT$strcmp(findFileData.cFileName, "..") != 0) {
+				
+				// Build path for the subdirectory
+                char subDir[MAX_PATH];
+                MSVCRT$strcpy(subDir, lpFolder);
+                MSVCRT$strcat(subDir, "\\");
+                MSVCRT$strcat(subDir, findFileData.cFileName);
+
+                SearchFilesRecursive(subDir, lpSearchPattern, keyword);
+            }
+        } while (KERNEL32$FindNextFileA(hFind, &findFileData) != 0);
+		
+        dwError = KERNEL32$GetLastError();
+        if (dwError != ERROR_NO_MORE_FILES) {
+            BeaconPrintf(CALLBACK_ERROR, "Error searching for next file: %d\n", dwError);
+        }
+		KERNEL32$FindClose(hFind);
+    }
+}
+
+
+int go(char *args, int len) {
+	datap parser;
+    CHAR *lpDirectory = "";
+    CHAR *lpSearchPattern = "";
+    CHAR *keyword = ""; // If not empty, SearchFileForKeyword is called to verify if the keyword is in the text file
+
+	BeaconDataParse(&parser, args, len);
+	lpDirectory = BeaconDataExtract(&parser, NULL);
+	lpSearchPattern = BeaconDataExtract(&parser, NULL);
+	keyword = BeaconDataExtract(&parser, NULL);
+	
+	BeaconPrintToStreamW(L"==========FILE SEARCH RESULTS==========\n");
+	
+    SearchFilesRecursive(lpDirectory, lpSearchPattern, keyword);
+	
+	BeaconOutputStreamW();
+	BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished searching!\n");
+
+    return 0;
+}
+
+
+		
+		

+ 39 - 0
KIT/FindFile/findfile.cna

@@ -0,0 +1,39 @@
+# author REDMED-X
+
+beacon_command_register(
+    "findfile", "Search for matching files based on a word, extention or keyword.",
+    "INFO:\nSearch for matching files based on a word, extention or keyword in the file content. Wildcards are supported . Keyword matching only works for text based files.\n\n" .
+	"ARGUMENTS:\n[<path to directory>]: specify a path to the directory from which to start searching (recursive searching supported).\n[<search pattern>]: specify a single word or extention to search for (support wildcards).\n[<keyword>]: leave empty OR specify a keyword to search for in text based files (support wildcards).\n\n" .
+	"USAGE:\nfindfile <path to directory> <search pattern> <(optional) keyword> \n\n" .
+	"EXAMPLES:\nfindfile C:\\Users\\RTO\\Documents *.xlsx\nfindfile C:\\Users\\RTO *login*.* username\nfindfile C:\\Users\\RTO *.txt *pass*\n\n");
+
+
+alias findfile {
+    $bid = $1;
+	$lpDirectory = $2;
+    $lpSearchPattern = $3;
+    $keyword = $4;
+
+    if ($lpDirectory eq "") {
+        berror($bid, "Please specify a path to a directory.\n");
+        return;
+    }
+
+    if ($lpSearchPattern eq "") {
+        berror($bid, "Please specify a pattern/word to search for.\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("findfile.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "zzz", $lpDirectory, $lpSearchPattern, $keyword);
+
+    blog($bid, "Tasked to search for matching files..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 44 - 0
KIT/FindFile/findfile.h

@@ -0,0 +1,44 @@
+#include <windows.h>  
+
+//BeaconPrintToStreamW + BeaconOutputStreamW
+#define MAX_STRING 8192
+INT g_iGarbage = 1;
+LPSTREAM g_lpStream = (LPSTREAM)1;
+LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
+WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+
+//SearchFileForKeyword + keywordMatches
+WINBASEAPI int WINAPI MSVCRT$strcmp(const char* str1, const char* str2);
+WINBASEAPI FILE* WINAPI MSVCRT$fopen(const char* filename, const char* mode);
+WINBASEAPI int __cdecl MSVCRT$fseek(FILE *_File, long _Offset, int _Origin);
+WINBASEAPI long __cdecl MSVCRT$ftell(FILE *_File);
+WINBASEAPI size_t __cdecl MSVCRT$fread(void * _DstBuf, size_t _ElementSize, size_t _Count, FILE * _File);
+WINBASEAPI int __cdecl MSVCRT$fclose(FILE *_File);
+WINBASEAPI char* WINAPI MSVCRT$strstr(const char* haystack, const char* needle);
+WINBASEAPI void *__cdecl MSVCRT$malloc(size_t _Size);
+//WINBASEAPI void __cdecl MSVCRT$free(void *_Memory);
+WINBASEAPI char* WINAPI MSVCRT$_strdup(const char* str);
+WINBASEAPI int WINAPI MSVCRT$tolower(int c);
+WINBASEAPI size_t WINAPI MSVCRT$strlen(const char* str);
+WINBASEAPI int WINAPI MSVCRT$strncmp(const char* str1, const char* str2, size_t n);
+WINBASEAPI char* WINAPI MSVCRT$strncpy(char* dest, const char* src, size_t n);
+DECLSPEC_IMPORT char* WINAPI MSVCRT$strtok(char* str, const char* delimiters);
+
+//SearchFilesRecursive
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetLastError(void);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$FindClose(HANDLE hFindFile);
+//DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+WINBASEAPI char* WINAPI MSVCRT$strcpy(char* dest, const char* src);
+WINBASEAPI char* WINAPI MSVCRT$strcat(char* dest, const char* src);
+WINBASEAPI int WINAPI MSVCRT$sprintf(char* buffer, const char* format, ...);

BIN
KIT/FindFile/findfile.o


+ 2 - 1
README.md

@@ -19,10 +19,11 @@ The following tools are currently in the operators' kit:
 |**[EnumShares](KIT/EnumShares)**|List remote shares and there access level using a predefined list with hostnames.|
 |**[EnumTaskScheduler](KIT/EnumTaskScheduler)**|Enumerate and list all the scheduled tasks in the root folder.|
 |**[FindDotnet](KIT/FindDotnet)**|Find processes that most likely have .NET loaded.|
+|**[FindFile](KIT/FindFile)**|Search for matching files based on a word, extention or keyword in the file content.|
 |**[FindHandle](KIT/FindHandle)**|Find "process" and "thread" handle types between processes.|
 |**[FindLib](KIT/FindLib)**|Find loaded module(s) in remote process(es).|
 |**[FindRWX](KIT/FindRWX)**|Find RWX memory regions in a target process.|
-|**[FindSysmon](KIT/FindSysmon)**|Verify if Sysmon is running through enumerating Minifilter drivers and checking the registry.|
+|**[FindSysmon](KIT/FindSysmon)**|Verify if Sysmon is running by checking the registry and listing Minifilter drivers.|
 |**[FindWebClient](KIT/FindWebClient)**|Find hosts with the WebClient service running based on a list with predefined hostnames.|
 |**[ForceLockScreen](KIT/ForceLockScreen)**|Force the lock screen of the current user session.|
 |**[HideFile](KIT/HideFile)**|Hide file or directory by setting it's attributes to systemfile + hidden.|