Didier Stevens

Saturday 26 August 2017

Quickpost: Metasploit PowerShell BASE64 Commands

Filed under: Hacking,Quickpost — Didier Stevens @ 21:29

I wanted to generate some BASE64 encoded PowerShell commands (i.e. with option -EncodedCommand) for analysis with my tool base64dump.py, thus I turned to Metasploit to generate these commands.

Here is the list of encoders:

It looks like cmd/powershell_base64 is what I’m looking for.

I couldn’t get the results that I wanted with this encoder, so I took a look at the source code:

This encoder will actually encode commands you pass to cmd.exe, and not PowerShell scripts.

I wanted an encoder for PowerShell scripts, like this simple PowerShell script to display a message box:

Add-Type -AssemblyName PresentationFramework
[System.Windows.MessageBox]::Show('Hello from PowerShell!')

Or even simpler:

Write-Host "Hello from PowerShell!"

And at this point, I really got sidetracked…

I coded my own encoder (based on the powershell_base64 encoder):

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Encoder
  Rank = NormalRanking

  def initialize
    super(
      'Name'             => 'Powershell Base64 Script Encoder',
      'Description'      => %q{
        This encodes a PowerShell script as a base64 encoded script for PowerShell.
      },
      'Author'           => 'Didier Stevens',
      'Arch'             => ARCH_CMD,
      'Platform'         => 'win')

    register_options([
      OptBool.new('NOEXIT', [ false, 'Add -noexit option', false ]),
      OptBool.new('SYSWOW64', [ false, 'Call syswow64 powershell', false ])
    ])

  end

  #
  # Encodes the payload
  #
  def encode_block(state, buf)
    base64 = Rex::Text.encode_base64(Rex::Text.to_unicode(buf))
    cmd = ''
    if datastore['SYSWOW64']
      cmd += 'c:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe '
    else
      cmd += 'powershell.exe '
    end
    if datastore['NOEXIT']
      cmd += '-NoExit '
    end
    cmd += "-EncodedCommand #{base64}"
  end
end

To install my encoder, I created folder powershell inside folder C:\metasploit\apps\pro\vendor\bundle\ruby\2.3.0\gems\metasploit-framework-4.15.4\modules\encoders (that’s on Windows) and copied my encoder base64.rb into it.

That’s all that is needed to make it available:

And now I can just use it with msfvenom, for example:

 

–payload – indicates that the payload has to be taken from stdin.

What I have no explanation for, is why on Windows input redirection does not work while piping works:

Echo works too:

With this encoder, I can encode a PowerShell script generated with msfvenom, like this:

The first msfvenom command will generate a powershell script with 32-bit shellcode for a meterpreter shell. The second msfvenom command will encode this command into a BASE64 PowerShell command. Option NOEXIT adds -NoExit to the PowerShell command, and option SYSWOW64 uses 32-bit powershell.exe on 64-bit Windows.

As the generated code was too long for the command line, I had to use option –smallest with the first msfvenom command to reduce the size of the script.

Here is the generated command:

And here is the execution:

More info:

 


Quickpost info


2 Comments »

  1. nice

    Comment by none — Monday 28 August 2017 @ 7:57

  2. […] Quickpost: Metasploit PowerShell BASE64 Commands […]

    Pingback by Overview of Content Published In August | Didier Stevens — Wednesday 6 September 2017 @ 19:54


RSS feed for comments on this post. TrackBack URI

Leave a Reply (comments are moderated)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.