Skip to main content

Decoding a PowerShell -EncodedCommand During Incident Response (the UTF-16 gotcha)

Uncovering the common UTF-16LE gotcha when decoding PowerShell Base64 blobs, handling null bytes, and dealing with nested gzip payloads.

AI-written
Inewgen
09 Aug 2026Source: Dev.to3 min read (0 views)
Share
Decoding a PowerShell -EncodedCommand During Incident Response (the UTF-16 gotcha)

Stock photo for illustration only, not from the actual event

Font size
  • The PowerShell parameter -EncodedCommand or -enc expects Base64 encoded UTF-16LE bytes.
  • Spaced-out characters and null bytes appear when the decoded output is mistakenly read as UTF-8 instead of UTF-16LE.
  • Nested payloads compressed with gzip can be identified by the inner Base64 string starting with H4sI.
  • Decoding and inflating these payloads are completely safe data transformations without executing any actual commands.

During incident response triage, analysts frequently encounter suspicious scheduled tasks or unusual command lines such as powershell.exe -nop -w hidden -enc JABjACAAPQAg... Standard procedure involves grabbing the Base64 blob, decoding it, and reading the underlying script. However, pasting it into a decoder often yields a spaced-out mess with null characters between every single character, falsely suggesting double-encoding or encryption when it is actually the single most common gotcha with -EncodedCommand.

This behavior occurs because -enc expects Base64 of UTF-16LE, or little-endian Unicode bytes, mandated directly by PowerShell and .NET rather than attacker choice. In UTF-16LE, every ASCII character is stored as two bytes consisting of the character followed by a 0x00 null byte, meaning the letter c is stored as 0x63 0x00 instead of 0x63. Decoding this blob as UTF-8 causes every null byte to render as a space or an invisible control character, creating the characteristic h t t p spacing.

binary code data stream abstract

Stock photo for illustration only, not from the actual event

Understanding the underlying UTF-16LE encoding contract is essential for cybersecurity professionals because Windows and the .NET environment natively rely heavily on UTF-16. Legitimate automation scripts frequently leverage -EncodedCommand as a clean method to pass multi-line scripts through a single argument without running into quoting nightmares, which is precisely why malicious actors also hide within the same technique.

Fixing the spacing issue requires decoding the data using the proper character set specification:

  • In PowerShell: Use [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($enc))
  • In Python: Decode the raw bytes and read them using utf-16-le
  • In CyberChef: Build a recipe from From Base64 to Decode text using UTF-16LE, or use From Base64 followed by Remove null bytes

Sometimes, correct decoding still reveals binary garbage due to another common technique where the actual script is gzip-compressed before being encoded in Base64. The outer PowerShell stub acts as a tiny loader designed to inflate the inner payload directly in memory. The telltale sign is an inner Base64 string starting with H4sI, representing the gzip magic number 1f 8b in Base64. Recognizing this pattern means decoding the Base64 once more and applying gzip decompression to reach the true script, as payloads can sometimes nest two or three layers deep.

Source: Dev.to

Comments

Leave a Comment
0/2000

Found something wrong in this article? Report an issue with this article