PowerShell Encoding with Go
Intro
The default character encoding used by Windows PowerShell is UTF-16LE, which is a less commonly used UTF encoding scheme which means you might come across encoding issues when trying to execute encoded commands in PowerShell. I wanted to create a quick utility Go script that encodes strings from the common UTF-8 format to UTF-16LE. I wrote this blog for those who are thinking of writing Windows exploits in Go or are commonly generating base64 PowerShell commands. With that said, let’s jump straight into some Go code!
UTF16 Encoding Strings with Go
In a new directory called “utf16”, create a Go file called main.go
and then run the following command to initalize a new Go module:
go mod init utf16
We need to “go get” the unicode
package from golang.org since this package isn’t part of the standard library:
go get -v golang.org/x/text/encoding/unicode
Lastly, paste the following code in main.go
and run it with go run main.go
(I’ll assume you have Go installed):
package main
import (
"encoding/base64"
"fmt"
"golang.org/x/text/encoding/unicode"
)
func main() {
pwshCmd := `iex "ping -n 5 localhost"`
utf16Encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
utf16EncodedCmd, err := utf16Encoder.Bytes([]byte(pwshCmd))
if err != nil {
panic(err.Error())
}
b64Cmd := base64.StdEncoding.EncodeToString(utf16EncodedCmd)
fmt.Println(b64Cmd)
}
The output from the program above should be:
aQBlAHgAIAAiAHAAaQBuAGcAIAAtAG4AIAA1ACAAbABvAGMAYQBsAGgAbwBzAHQAIgA=
Code Walkthrough
Here is a break down of what each significant line is doing:
- Creating a UTF-16LE encoder - the argument
IgnoreBOM
means to not incude byte order mark which is used to determine if a files content is UTF encoded
utf16Encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
- Encoding a UTF-8 byte slice to a UTF-16LE byte slice
utf16EncodedCmd, err := utf16Encoder.Bytes([]byte(pwshCmd))
- Base64 encoding a UTF-16LE byte slice into a string
b64Cmd := base64.StdEncoding.EncodeToString(utf16EncodedCmd)
With our corrently encoded PowerShell command, we can now execute our command with PowerShell:
EOF
At this point, it would be pretty simple to turn this program into a useful CLI tool using cobra or go-arg, but I’ll leave that up to you. Happy Hacking!
If you enjoyed reading this blog and learned something, keep an eye out for more of my posts and maybe consider following me on GitHub, where I work on cybersecurity projects. And if you are feeling really generous, consider buying me a coffee!