Class: Rex::Exploitation::CmdStagerBase

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/exploitation/cmdstager/base.rb

Overview

This class provides an interface to generating cmdstagers.

Instance Method Summary collapse

Constructor Details

#initialize(exe) ⇒ CmdStagerBase


17
18
19
20
# File 'lib/rex/exploitation/cmdstager/base.rb', line 17

def initialize(exe)
  @linemax     = 2047 # covers most likely cases
  @exe         = exe
end

Instance Method Details

#cmd_concat_operatorObject

Can be overriden. For exmaple, use for unix use “;” instead


170
171
172
# File 'lib/rex/exploitation/cmdstager/base.rb', line 170

def cmd_concat_operator
  nil
end

#compress_commands(cmds, opts) ⇒ Object

Compress commands into as few lines as possible. Minimizes the number of commands to execute while maximizing the number of commands per execution.


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/rex/exploitation/cmdstager/base.rb', line 127

def compress_commands(cmds, opts)
  new_cmds = []
  line = ''
  concat = cmd_concat_operator

  # We cannot compress commands if there is no way to combine commands on
  # a single line.
  return cmds if not concat

  cmds.each { |cmd|

    # If this command will fit, concat it and move on.
    if ((line.length + cmd.length + concat.length) < opts[:linemax])
      line << concat if line.length > 0
      line << cmd
      next
    end

    # The command wont fit concat'd to this line, if we have something,
    # we have to add it to the array now.
    if (line.length > 0)
      new_cmds << line
      line = ''
    end

    # If it won't fit even after emptying the current line, error out..
    if (cmd.length > opts[:linemax])
      raise RuntimeError, 'Line too long - %u bytes, max %u' % [cmd.length, opts[:linemax]]
    end

    # It will indeed fit by itself, lets add it.
    line << cmd

  }
  new_cmds << line if (line.length > 0)

  # Return the final array.
  new_cmds
end

#encode_payload(opts) ⇒ Object

This method is intended to be override by the child class


78
79
80
81
# File 'lib/rex/exploitation/cmdstager/base.rb', line 78

def encode_payload(opts)
  # Defaults to nothing
  ""
end

#generate(opts = {}) ⇒ Object

Generates the cmd payload including the h2bv2 decoder and encoded payload. The resulting commands also perform cleanup, removing any left over files


26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/rex/exploitation/cmdstager/base.rb', line 26

def generate(opts = {})
  # Allow temporary directory override
  @tempdir = opts[:temp]
  @tempdir ||= "%TEMP%\\"
  if (@tempdir == '.')
    @tempdir = ''
  end

  opts[:linemax] ||= @linemax

  generate_cmds(opts)
end

#generate_cmds(opts) ⇒ Object

This does the work of actually building an array of commands that when executed will create and run an executable payload.


44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rex/exploitation/cmdstager/base.rb', line 44

def generate_cmds(opts)

  # Initialize an arry of commands to execute
  cmds = []

  # Add the exe building commands
  cmds += generate_cmds_payload(opts)

  # Add the decoder script building commands
  cmds += generate_cmds_decoder(opts)

  compress_commands(cmds, opts)
end

#generate_cmds_decoder(opts) ⇒ Object

Generate the commands that will decode the file we just created


116
117
118
119
# File 'lib/rex/exploitation/cmdstager/base.rb', line 116

def generate_cmds_decoder(opts)
  # Defaults to no commands.
  []
end

#generate_cmds_payload(opts) ⇒ Object

Generate the commands to create an encoded version of the payload file


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

def generate_cmds_payload(opts)

  # First encode the payload
  encoded = encode_payload(opts)

  # Now split it up into usable pieces
  parts = slice_up_payload(encoded, opts)

  # Turn each part into a valid command
  parts_to_commands(parts, opts)
end

#parts_to_commands(parts, opts) ⇒ Object

Combine the parts of the encoded file with the stuff that goes before / after it – example “echo ” and “ >>file”


106
107
108
109
# File 'lib/rex/exploitation/cmdstager/base.rb', line 106

def parts_to_commands(parts, opts)
  # Return as-is
  parts
end

#slice_up_payload(encoded, opts) ⇒ Object

We take a string of data and turn it into an array of parts.

We save opts bytes out of every opts for the parts appended and prepended to the resulting elements.


89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/rex/exploitation/cmdstager/base.rb', line 89

def slice_up_payload(encoded, opts)
  tmp = encoded.dup

  parts = []
  xtra_len = opts[:extra]
  xtra_len ||= 0
  while (tmp.length > 0)
    parts << tmp.slice!(0, (opts[:linemax] - xtra_len))
  end

  parts
end