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 90265c5a0f
Rework powershell_shell to work with "streaming"
This commit changes the channel functionality within the powershell extension so that commands do execute behind the scenes and stream the results to the UI in the current channel.

This comes with the caveat that users are patient. I haven't yet made sure that running separate commands while long running ones are running will not cause problems. We'll have to see.
2018-05-07 21:13:08 +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 is generated, 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.
}