1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-12-21 05:35:54 +01:00
metasploit-payloads/powershell/build/generate.ps1
OJ c7f7bc2fc0
Remove method strings from TLV packets
We now use ints, and hopefully this means we don't have as much obvious
stuff in the binaries!

```
$ # Before:
$ strings metsrv.x86.dll | grep core_ | wc -l
46
$ # After:
$ strings metsrv.x86.dll | grep core_ | wc -l
0
```
Big win, and it's even bigger for the likes of stdapi.

Had to fix a bunch of other stuff along the way, including a subtle
issue with the Powershell Meterp bindings.
2020-04-28 23:41:06 +10:00

103 lines
4.4 KiB
PowerShell

function Generate-MetasploitPowershell {
<#
.SYNOPSIS
Generates the source and include files that are built in to the Metasploit
Powershell extension. These files contain the body of the MSF.Powershell.Runner
class in .NET that allow for the extension to interact with the interpreter.
.PARAMETER BuildDir
Specifies the 'build' folder the powershelll project. By default, the current
folder is used, however if this is invoked outside of the specified folder then
the location of the folder containing this script has to be specified.
.PARAMETER Debug
Indicates that the debug build should be used instead of the release build (for testing).
.INPUTS
None.
.OPUTPUTS
Writes some content to screen to inform the user of success or failure.
.EXAMPLE
PS C:\metasploit-payloads\powershell\build\> Generate-MetasploitPowershell -Debug
PS C:\> Generate-MetasploitPowershell -BuildDir C:\metasploit-payloads\powershell\build\
#>
param(
[ValidateScript({ Test-Path -Path $_ })]
[String]
$BuildDir = $(Get-Location),
[Switch]
$Debug
)
$Build = 'Release'
If ($Debug) {
$Build = 'Debug'
}
$SourceAssembly = [System.IO.Path]::Combine($BuildDir, '..', 'MSF.Powershell', 'bin', $Build, 'MSF.Powershell.dll')
Write-Host [+] Building source using binary at $SourceAssembly ...
If (-not (Test-Path -LiteralPath $SourceAssembly)) {
Write-Host [!] Unable to find $SourceAssembly
Write-Host [!] Make sure that BuildDir and Build are set correctly, and that the target binary has been built.
Exit
}
# We will assume that if the SourceAssembly path is correct, that we have the right folder and we
# can just generate a path based on the current folder for the target and it'll be ok.
$TargetPath = [System.IO.Path]::Combine($BuildDir, '..', '..', 'c', 'meterpreter', 'source', 'extensions', 'powershell')
# Time to generate some source
$AssemblyContent = [System.IO.File]::ReadAllBytes($SourceAssembly)
# Start with the include file
$SizeVar = 'PSHRUNNER_DLL_LEN'
$HeaderContent = New-Object System.Collections.ArrayList
[void] $HeaderContent.Add("/*!`n")
[void] $HeaderContent.Add(" * @file powershell_runner.h`n")
[void] $HeaderContent.Add(" * @brief This file was generated at $([DateTime]::UtcNow) UTC, do not modify directly.`n")
[void] $HeaderContent.Add(" */`n`n")
[void] $HeaderContent.Add("#ifndef _METERPRETER_SOURCE_EXTENSION_POWERSHELL_RUNNER_H`n")
[void] $HeaderContent.Add("#define _METERPRETER_SOURCE_EXTENSION_POWERSHELL_RUNNER_H`n`n")
[void] $HeaderContent.Add("#define $SizeVar $($AssemblyContent.Length)`n`n")
[void] $HeaderContent.Add("extern unsigned char PowerShellRunnerDll[$SizeVar];`n`n")
[void] $HeaderContent.Add("#endif`n`n")
$RunnerHeaderPath = [System.IO.Path]::Combine($TargetPath, 'powershell_runner.h')
[System.IO.File]::WriteAllText($RunnerHeaderPath, $HeaderContent)
Write-Host [+] $RunnerHeaderPath written.
# Now the body of the source
$SourceContent = New-Object System.Collections.ArrayList
[void] $SourceContent.Add("/*!`n")
[void] $SourceContent.Add(" * @file powershell_runner.cpp`n")
[void] $SourceContent.Add(" * @brief This file is generated, do not modify directly.`n")
[void] $SourceContent.Add(" */`n`n")
[void] $SourceContent.Add("#include `"powershell_runner.h`"`n`n")
[void] $SourceContent.Add("#pragma message(`"Compiling PowerShellRunner into app. Size: $($AssemblyContent.Length)`")`n`n")
[void] $SourceContent.Add("unsigned char PowerShellRunnerDll[$SizeVar] =`n")
[void] $SourceContent.Add("{`n")
# Do the magic to convert the bytes into an array of literal bytes.
For ($i = 0; $i -lt $AssemblyContent.Length; $i++) {
If (($i % 12) -eq 0) {
[void] $SourceContent.Add("`t")
}
[void] $SourceContent.Add("0x$($AssemblyContent[$i].ToString('X2')),")
If (($i % 12) -eq 11) {
[void] $SourceContent.Add("`n")
}
}
[void] $SourceContent.Add("`n};`n`n")
$RunnerCppPath = [System.IO.Path]::Combine($TargetPath, 'powershell_runner.cpp')
[System.IO.File]::WriteAllText($RunnerCppPath, $SourceContent)
Write-Host [+] $RunnerCppPath written.
Write-Host [+] Powershell Assembly content written. .NET Binary is $AssemblyContent.Length bytes.
}