mirror of
https://github.com/rapid7/metasploit-payloads
synced 2024-12-21 05:35:54 +01:00
90265c5a0f
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.
103 lines
4.4 KiB
PowerShell
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.
|
|
}
|
|
|