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



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

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

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



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

#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