Technology sharing: how to embed an EXE file in a PowerShell script
I am trying to solve a problem, that is, only PowerShell scripts are used as the attack load in client attacks. Using PowerShell to run malicious code has many advantages, including:
1. You do not need to install anything else on the target.
2. Powerful engines (such as directly calling. NET code ).
3. You can use base64 encoding commands to confuse malicious commands, making them invisible. This is also a way to avoid using special characters, especially in an advanced attack that involves multiple steps that need to separate different attack loads.
4. You can use Invoke-Expression to interpret the string as a Powershell command. From the perspective of penetration testing, this can avoid writing complex scripts on the target disk. For example, you can use Powershell to download additional complex scripts, and then call Invoke-Expression to explain and execute the script downloaded to the memory. This process also avoids antivirus software detection and removal.
We want to run some very complex functions on the target, which are often part of the EXE file. I don't want to place a binary file directly on the target, because this may trigger the anti-virus mechanism. So I want to put it into the Powershell script, but I also don't want to rewrite the entire Powershell script.
Finally, I came up with a solution.
Embed a binary file into a Powershell script and run it directly using the script instead of writing it to the disk.
The following describes the solution steps:
1. base64 encoding of binary files
You can use the following functions:
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 as follows
1. Convert the EXE file into a string using the method in the previous step;
2. Prepare Invoke-ReflectivePEInjection (part of the Powersploit project );
3. Convert the string into a byte array;
4. Call Invoke-ReflectivePEInjection.
Therefore, the binary file is only a string in the Powershell script. After decoding the string into a binary array, you can call Invoke-reflectivepjecjection to run it directly in the memory.
Finally it looks like this:
# Base64 encoded binary file $ InputString = '........... 'function Invoke-ReflectivePEInjection {..................} # convert a binary string into a byte array $ PEBytes = [System. convert]: FromBase64String ($ InputString) # Run EXEInvoke-ReflectivePEInjection-PEBytes $ PEBytes-ExeArgs "Arg1 Arg2 Arg3 Arg4" in the memory"
Now you can run the script on the target:
powershell -ExecutionPolicy Bypass -File payload.ps1
The following error may occur depending on the binary file to be embedded:
PE platform doesn' t match the architecture of the process it is being loaded in (32/64 bit)
To solve this problem, you only need to run 32-bit PowerShell.
The following is an example of embedding plink.exe in payload. ps1: