Friday, May 26, 2023

The curious case of ♪ and ◙

demo.md

I was recently reading Chad Tilbury's post Finding Evil WMI Event Consumers with Disk Forensics and it reminded me of something. I have a script that automates the collection and parsing of KAPE that uses WMI event consumers and filters. The problem was, I needed a way to pass parameters to the the encrypted powershell script in the consumer. I found some information about putting the parameters in a file and reading the file to get the parameters. The problem with this solution is I needed the parameters to be dynamic. So what does one do in this case? This is where ♪ and ◙ come into play.

What is ♪ and ◙ in the first place?

These strange characters can be created using ALT codes (hello 90's). The first one ♪, can be created by holding down the alt key and typing 13 on the number pad. ◙ can be created by holding down the alt key and typing 10 on the number pad. A little bit of history behind ALT codes according to Wikipedia:

"On IBM PC compatible personal computers from the 1980s, the BIOS allowed the user to hold down the Alt key and type a decimal number on the keypad. It would place the corresponding code into the keyboard buffer so that it would look (almost) as if the code had been entered by a single keystroke. Applications reading keystrokes from the BIOS would behave according to what action they associate with that code. Some would interpret the code as a command, but often it would be interpreted as a code to be placed on the screen at the location of the cursor, thus displaying the corresponding 8-bit character from the current code page. On the original IBM PC this was CP437. In most cases typing a number greater than 255 produced the character associated with the remainder after the number is divided by 256."

Passing parameters to Powershell in a WMI consumer

So, how do we use this to our advantage to pass parameters to an encrypted powershell script? Lets say we have the following script:

Next, we'll take the script and encode it.

PS C:\Temp\Demo> $text = {
param
(
    [Parameter(Mandatory)]
    [string]
    $FileName,

    [Parameter(Mandatory)]
    [string]
    $Extension
)
    Write-Host "Filter Fired"
    $filein = $FileName +"."+ $Extension
    $fileout = $FileName +".zip"
    Write-Host $filein
    Write-Host $fileout

    Compress-Archive -LiteralPath $filein -DestinationPath $fileout

    Remove-Item -Path $filein
}
PS C:\Temp\Demo> $PScommand = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($text))
PS C:\Temp\Demo> $PScommand
CgBwAGEAcgBhAG0ACgAoAAoAIAAgACAAIABbAFAAYQByAGEAbQBlAHQAZQByACgATQBhAG4AZABhAHQAbwByAHkAKQBdAAoAIAAgACAAIABbAHMAdAByAGkAbgBnAF0ACgAgACAAIAAgACQARgBpAGwAZQBOAGEAbQBlACwACgAgACAAIAAgAAoAIAAgACAAIABbAFAAYQByAGEAbQBlAHQAZQByACgATQBhAG4AZABhAHQAbwByAHkAKQBdAAoAIAAgACAAIABbAHMAdAByAGkAbgBnAF0ACgAgACAAIAAgACQARQB4AHQAZQBuAHMAaQBvAG4ACgApAAoAIAAgACAAIABXAHIAaQB0AGUALQBIAG8AcwB0ACAAIgBGAGkAbAB0AGUAcgAgAEYAaQByAGUAZAAiAAoAIAAgACAAIAAkAGYAaQBsAGUAaQBuACAAPQAgACQARgBpAGwAZQBOAGEAbQBlAC4AVAByAGkAbQAoACkAKwAiAC4AIgArACQARQB4AHQAZQBuAHMAaQBvAG4ACgAgACAAIAAgACQAZgBpAGwAZQBvAHUAdAAgAD0AIAAkAEYAaQBsAGUATgBhAG0AZQAuAFQAcgBpAG0AKAApACsAIgAuAHoAaQBwACIACgAgACAAIAAgAFcAcgBpAHQAZQAtAEgAbwBzAHQAIAAkAGYAaQBsAGUAaQBuAAoAIAAgACAAIABXAHIAaQB0AGUALQBIAG8AcwB0ACAAJABmAGkAbABlAG8AdQB0AAoAIAAgACAAIAAKACAAIAAgACAAQwBvAG0AcAByAGUAcwBzAC0AQQByAGMAaABpAHYAZQAgAC0ATABpAHQAZQByAGEAbABQAGEAdABoACAAJABmAGkAbABlAGkAbgAgAC0ARABlAHMAdABpAG4AYQB0AGkAbwBuAFAAYQB0AGgAIAAkAGYAaQBsAGUAbwB1AHQACgAKACAAIAAgACAAUgBlAG0AbwB2AGUALQBJAHQAZQBtACAALQBQAGEAdABoACAAJABmAGkAbABlAGkAbgAKAA==

If we try and run this command and pass the parameters to it, we get the following error:

Another way we could do this is to just run the command and answer the prompts, like so:

Unfortunately, the mandatory parameters are needed but we do not have access to the command line to pass them in a WMI consumer. Lets try echoing the parameters.

Still no luck. The command prompt does not recognize \n as a line feed. Lets try something a little crazy here. We'll replace \n with ◙.

Bingo! But why does this work? If we look at the code page, we can see that ◙ is interpreted as LF (Line Feed) and ♪ as CR (Carriage Return).