KeyZero: A Custom PowerShell RAT

The Blackpoint SOC recently investigated an incident that revealed a custom PowerShell Remote Access Trojan (RAT) we named KeyZero, a reference to the static authentication token certokey0 used during session setup. KeyZero opens an outbound TLS-wrapped TCP connection to a hardcoded operator endpoint on port 3389 and intentionally disables certificate validation so the controller can use a self-signed certificate. After the TLS session and the simple token handshake complete, the RAT builds a compact host fingerprint, sends that one line system profile to the operator, and then drops into a persistent interactive command loop for operator-driven actions.

The payload is intentionally lightweight and leverages native Windows APIs and common system components to execute operator instructions. It conditionally spawns cmd.exe or powershell.exe to run arbitrary commands, captures stdout and stderr, and frames results back to the controller over the established channel. KeyZero enforces single-instance execution using a Global\ mutex derived from the MD5 of DOMAIN\username and performs a set of environment checks including total RAM, CPU and BIOS strings, GPU info, IP configuration, and elevation state. The script aborts on sandboxed or virtualized hosts and only reports to the operator when the environment looks genuine. These design choices, combined with a mostly fileless initial footprint, helped the RAT evade traditional signature-based antivirus and reduce noisy disk indicators.

We observed the operator using KeyZero as a hands-on keyboard orchestration and staging tool. After performing local reconnaissance and confirming host value, the operator leveraged the RAT’s command channel to push follow-on tooling. That staging workflow decoded base64 gzip blobs, wrote randomized temporary PS1 files into %TEMP%, executed them hidden via a VBScript shim or child process, and then removed them. The operator also staged several additional conventional C2 beacons into %TEMP%, executed them from there, and ultimately staged a payload to create SYSTEM-level RegDump scheduled tasks on remote hosts to collect high value registry secrets.

KeyZero exemplifies a broader shift toward compact, minimalistic tooling that prioritizes stealth and operator flexibility. Instead of large, signature-prone binaries, this approach composes small, platform-native pieces that perform reconnaissance, provide interactive control, and selectively stage additional capability on demand. That model keeps early activity quiet and flexible, enabling human operators to blend into normal system and network behavior and escalate only on targets of interest.

Key Findings

  • Initial access came from a downloaded zip archive that delivered an obfuscated batch file which decoded and executed a temporary PowerShell payload.
  • This expanded and deployed a custom PowerShell Remote Access Trojan (RAT) we named KeyZero, which fingerprints hosts and enforces single-instance behavior.
  • KeyZero fingerprints the host thoroughly to evade sandbox / VM analysis, checking RAM, CPU/BIOS strings, GPU info, and IP configuration.
  • After passing checks the implant opens an outbound TLS channel over port 3389, authenticates with a static token, and enables follow-on command execution.
  • The operator used that interactive channel to stage follow-on tooling by inflating base64+gzip blobs to randomized temporary PS1 files, executing them hidden, and deployed additional C2 beacon executables staged in the temp directory.
  • The operator staged a payload which created SYSTEM level RegDump tasks on several remote hosts and attempted to dump registry hives to C:\Users\Public.
  • Both the KeyZero RAT and the staged C2 beacons fully evaded traditional AV and EDR solutions until the follow-on operator-driven execution.

Observed Killchain

Green Eggs and SAM

The deployment of KeyZero began with a file named 168492165.zip located in the user’s Downloads folder, which served as the initial access vector. The archive contained a small, obfuscated batch file (Figure 1) that acted as the first stage of execution. Its sole purpose was to carry an embedded payload and ensure that the next stage could be decoded and launched silently, leaving only minimal artifacts behind.

Figure 1: Malicious batch file decoding and launching the KeyZero PowerShell implant.

The embedded blob inside the batch expanded into the second stage PowerShell script (Figure 2). The script was delivered in a gzipped Base64 format, decoded into memory, decompressed, written to a randomized .ps1 under %TEMP%, and then executed hidden via WScript.Shell. After a short delay the bootstrap attempted to delete the temporary file, leaving the PowerShell process as the only persistent artifact in memory. This design allowed the operator to package a much larger script inside a compact archive, while keeping its presence on disk minimal.

Figure 2: Decoded payload decompressing to a temp file for hidden execution.

Stage three is the PowerShell payload we call KeyZero, the decompressed PS1 produced by the stage two inflation. The script starts with inline comments (notably # v2) and defines lightly obfuscated C2 constants at the top. The server and port are constructed via small arithmetic and [char] expressions to hide obvious strings, and the port resolves to 3389 for communication. The agent also builds a static handshake token from character codes that resolves to certokey0, which is where the KeyZero name is derived from.

Figure 3: Obfuscated C2 constants and handshake token certokey0.

KeyZero runs comprehensive environment checks before making any outbound connection and builds a compact host fingerprint from RAM, CPU and BIOS strings, GPU and IP information, and elevation status. If the checks indicate a sandbox or virtual machine the agent aborts; if they pass, a one-line fingerprint is sent to the operator after the agent authenticates, giving the operator the quick, actionable view needed to decide whether to stage follow-on tooling.

The agent injects a small C# type that uses P/Invoke to call the Windows API GlobalMemoryStatusEx, exposing total physical RAM back into PowerShell (Figure 4). That value is then consumed by the script, converted into gigabytes, and compared against a cutoff, with execution aborting if the system reports less than 4 GB of memory, a straightforward way to evade most automated analysis environments (Figure 5).

Figure 4: Inline C# definition and P/Invoke declaration for GlobalMemoryStatusEx.

Figure 5: RAM check logic calling Get-RAMBytes and aborting if memory is below 4 GB.

KeyZero reads the processor name from the registry and compares it against known test or virtualized CPU signatures. The agent pulls ProcessorNameString and tests it with simple pattern matching to identify lab or VM CPUs; if a match is found the agent treats the host as low value and stops execution (Figure 6). This check is a quick way to detect non-production environments without triggering heavier telemetry.

Figure 6: CPU string inspection from the registry to detect virtualized or test CPUs.

Additional queries for BIOS information from the registry to detect virtualization are also made. It collects both the SystemManufacturer and SystemProductName values, concatenates them, and evaluates the string for terms like VMware, Hyper-V, VirtualBox, or other common hypervisor artifacts (Figure 7). If any of these markers are present the agent aborts, preventing further execution inside virtual analysis environments.

Figure 7: BIOS registry query used to detect virtualization markers.

In addition to CPU and BIOS inspection, KeyZero queries the GPU and network configuration to refine its host profiling. It walks PCI registry entries to extract video device names, expecting to find legitimate hardware rather than generic or missing identifiers that often appear in emulated environments. At the same time, it resolves the host’s DNS name and filters out invalid or APIPA (169.*) addresses, ensuring only routable IPs are included in the fingerprint. Together these checks provide another layer of sandbox evasion before any C2 communication begins.

Figure 8: GPU and IP resolution logic used to filter out emulated or non-routable hosts.

The agent also checks whether it is running with administrative privileges using an Is-Elevated helper, then folds the result into the fingerprint string it builds. This check queries the current Windows identity and role membership, returning Yes or No depending on whether the process has administrative rights. The final fingerprint is a compact one-liner containing the domain, host, user, IPs, CPU, RAM in gigabytes, GPU information, virtualization status, the Elevated:Yes/No flag, and a timestamp. When transmitted to the controller, this gives operators a quick snapshot of host value and privilege level (Figure 9).

Figure 9: Elevation check and host fingerprint composition.

The connection and authentication are handled inside the outer retry loop. The agent creates a TCP socket, upgrades the stream to TLS using an SslStream with a certificate callback that always returns true, and calls AuthenticateAsClient before any plaintext exchange. The client then writes AUTH certokey0 and reads a single-line response; if the controller replies AUTH_OK the implant sends its assembled host fingerprint and proceeds, otherwise it closes the socket, sleeps, and retries (Figure 10).

Figure 10: TLS setup, certificate validation bypass, and AUTH / AUTH_OK handshake.

Once authenticated the agent hands control to an inner read loop that accepts operator instructions (Figure 11). It reads lines from the TLS stream and supports a small set of plaintext commands: EXIT to terminate the session, EXEC_CMD to run a cmd.exe command, and EXEC_POWERSHELL to run a powershell.exe command. Child processes are launched hidden with stdout and stderr redirected; captured output is framed as OUTPUT \n followed by the raw bytes and sent back over the TLS stream. Any unknown input elicits an ERROR: unknown command response. This is the interactive mechanism the operator used to run commands and retrieve results.

Figure 11: Command loop with hidden process spawn and output return.

The operator used KeyZero as a lightweight orchestration layer during the session we observed. The RAT gathered host details through reconnaissance and environment checks, then the operator issued follow-on payloads through its communication channel. This staged approach minimized noise on disk and deferred escalation until after the host was confirmed to be of value.

KeyZero’s script-based design further helped it evade traditional antivirus and EDR. By default, it made few local changes and only retrieved additional modules or executables on demand, reducing obvious indicators and keeping the initial footprint trivial until the operator directed further activity.

The operator utilized the EXEC_CMD and EXEC_POWERSHELL operators to push staged payloads to hosts that passed initial validation. In the session we analyzed the operator sent large base64 blobs which the host decoded, inflated with GZip, wrote to a randomly named temp PS1, executed silently via WScript.Shell, slept briefly, and then removed the temp file (Figure 12). That single command reproduces the same pattern used in the initial bootstrap and effectively turns KeyZero into an interactive download and run conduit under operator control.

Figure 12: Operator-issued command payload processed by KeyZero

This same pattern was repeated to introduce additional tooling. Beyond transient scripts, the operator used these payloads to deploy and establish additional C2 beacons delivered as executables. Each was staged into the same temporary directory, launched from there, and bypassed traditional AV. By chaining KeyZero with more traditional disk-based components, the operator gained both stealth in the early stages and persistence once a host was confirmed to be of interest.

In this incident, one of the staged payloads deployed by the operator was a PowerShell script that remotely created scheduled tasks named RegDump on hosts identified via reconnaissance. That payload lived briefly in %TEMP%, created a RegDump task configured to run as SYSTEM, used a web fetch and execute pattern to pull additional code from a malicious IP, invoked the task with schtasks /Run, and then deleted the task entry (Figure 13).

Figure 13: Creation and execution of the RegDump scheduled task.

When the scheduled task ran under the SYSTEM account it attempted to dump registry-held secrets, including LSA secrets, cached credentials and other high-privilege registry values. The dumped hives were written to C:\Users\Public for later collection, but at this point traditional antivirus detected the malicious activity and blocked execution.

In conclusion, KeyZero functioned as an operator-driven orchestration layer that validated hosts, kept an intentionally small initial footprint, and only pulled additional tooling when the operator decided to escalate. The payload itself is a custom PowerShell RAT that is lightweight and largely fileless by design, acting as a controlled conduit for staging more conventional components when needed. That approach reduced noisy disk activity during initial access while still enabling rapid escalation on confirmed targets. In the incident we observed the operator use staged follow-on payloads to create a SYSTEM level RegDump workflow that produced high value registry material, demonstrating how compact PowerShell implants can enable serious credential theft and privilege escalation when combined with targeted operator actions.

Indicators of Compromise (IOCs)

File NameHash
168492165.zip (Dropper)2ad19fca2ea257be275fb3ccc2d5a9a62fa6ee8467afb3f3b3e755f8cb666f60
Malicious .bat file3a7cd3b6824bdfa63b17fc01998d834ecf692c77090e66527f9a471d89f32a66
KeyZero Payload26ee9d1196fd724e091a8c6570813c07ff4ead30c16e01a2e17783cf3f6259dd
Transport.exe830f00f6925bbda4f12498e894f31c667aab8d6060d66c730c9202b586b06587
Nssransport.exe (.NET based implant)7323ce726148383755b2f8424d38e53cfdbfa0027ed93b64e8f571fc52c53c68
TemL.exe (.NET based implant)bb230a5284c208f51de16ac2748ff231640b30f0b8145fc7aec122da3a8e8d4f
~1026027564.u.vbs7a095d57bb7a24c091f742fe0fcb5af01a3065adc30ca5995921fa7b8507a5d6
~1883515761.u.vbsaddd4d9a9c93aa09b1905fc9454ad22586f986ddd3bb76fa58eb1975a1584649
~1075410054.x.ps1b8d83149009a7b21f4b7c9af46b98818bbce89d27abf00c9cf56c01710dcf4fe
~611311939.ps0.zelya.bloh.ps1d2efff7755fc9de1474b688a14c61d9edf3f70687d064bdec164b30bd07004dd
~1283713895.tmp.zelya.b.vbsee8d3e27172371b7520796a8702344124e425de87bafb1f974b30ea2a3d11d5b
~12408535.tmp.zelya.b.vbsa7642255504faff480b8995b8ae938a961795a25b8c2f4c89d29d0a5ca78f978
Network Address / Domain NameDescription
185.126.82[.]114  Malicious Staging Infrastructure
170.205.37[.]29KeyZero Communication Infrastructure
176.126.84[.]107  Threat Actor Command and Control Infrastructure
193.29.63[.]141  Threat Actor Command and Control Infrastructure

Recommendations

  • Restrict PowerShell usage for non-privileged users.
  • Create/Tune ACL (Access Control List) to reduce scheduled tasks being created from non-privileged users.
  • Utilize GPO to open common loaders (.bat, .js., .lnk) in notepad instead of executing.
  • Never download files from untrusted websites.
  • Enable LSA Protection (RunAsPPL). This makes LSASS a Protected Process Light (PPL) so many non-PPL processes cannot open handles or dump it.
  • Registry:
    •  reg add “HKLM\SYSTEM\CurrentControlSet\Control\Lsa” /v RunAsPPL /t REG_DWORD /d 1 /f
  • Monitor for outbound PowerShell connections to uncommon ports, such as 3389.
DATE PUBLISHEDSeptember 19, 2025
AUTHORSam Decker, Nevan Beal, and Caden Toellner