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

Returns a new instance of CmdStagerBase.



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

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



173
174
175
# File 'lib/rex/exploitation/cmdstager/base.rb', line 173

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.



126
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
166
167
168
# File 'lib/rex/exploitation/cmdstager/base.rb', line 126

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

  concat = opts[:concat_operator] || cmd_concat_operator

  # Skip command concatentation if desired, returning individual commands
  return cmds if opts[:noconcat]

  # We cannot compress commands if there is no way to combine commands on
  # a single line.
  return cmds unless 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



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

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



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

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.



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

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



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

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



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

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”



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

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

#setup(mod = nil) ⇒ Object

Should be overriden if the cmd stager needs to setup anything before it’s executed



179
180
181
# File 'lib/rex/exploitation/cmdstager/base.rb', line 179

def setup(mod = nil)

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.



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

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

#teardown(mod = nil) ⇒ Object

Should be overriden if the cmd stager needs to do any clenaup



186
187
188
# File 'lib/rex/exploitation/cmdstager/base.rb', line 186

def teardown(mod = nil)

end