@@ -9,19 +9,29 @@ module Formatter
99 # @param cred [credClass] A credential from framework.db
1010 # @return [String] The hash in jtr format or nil on no match.
1111 def self . hash_to_jtr ( cred )
12- case cred . private . type
13- when 'Metasploit::Credential::NTLMHash'
14- return "#{ cred . public . username } :#{ cred . id } :#{ cred . private . data } :::#{ cred . id } "
15- when 'Metasploit::Credential::PostgresMD5'
16- if cred . private . jtr_format =~ /postgres|raw-md5/
12+ params_to_jtr (
13+ ( cred . public . nil? ? '' : cred . public . username ) ,
14+ cred . private . data ,
15+ cred . class . model_name . element . to_sym ,
16+ format : cred . private . jtr_format ,
17+ db_id : cred . id
18+ )
19+ end
20+
21+ def self . params_to_jtr ( username , private_data , private_type , format : nil , db_id : nil )
22+ case private_type
23+ when :ntlm_hash
24+ return "#{ username } :#{ db_id } :#{ private_data } :::#{ db_id } "
25+ when :postgres_md5
26+ if format =~ /postgres|raw-md5/
1727 # john --list=subformats | grep 'PostgreSQL MD5'
1828 # UserFormat = dynamic_1034 type = dynamic_1034: md5($p.$u) (PostgreSQL MD5)
19- hash_string = cred . private . data
29+ hash_string = private_data
2030 hash_string . gsub! ( /^md5/ , '' )
21- return "#{ cred . public . username } :$dynamic_1034$#{ hash_string } :#{ cred . id } :"
31+ return "#{ username } :$dynamic_1034$#{ hash_string } :#{ db_id } :"
2232 end
23- when 'Metasploit::Credential::NonreplayableHash'
24- case cred . private . jtr_format
33+ when :nonreplayable_hash
34+ case format
2535 # oracle 11+ password hash descriptions:
2636 # this password is stored as a long ascii string with several sections
2737 # https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/changes-in-oracle-database-12c-password-hashes/
@@ -40,46 +50,46 @@ def self.hash_to_jtr(cred)
4050 # T: = 160 characters
4151 # PBKDF2-based SHA512 hash specific to 12C (12.1.0.2+)
4252 when /raw-sha1|oracle11/ # oracle 11
43- if cred . private . data =~ /S:([\d A-F]{60})/ # oracle 11
44- return "#{ cred . public . username } :#{ Regexp . last_match ( 1 ) } :#{ cred . id } :"
53+ if private_data =~ /S:([\d A-F]{60})/ # oracle 11
54+ return "#{ username } :#{ Regexp . last_match ( 1 ) } :#{ db_id } :"
4555 end
4656 when /oracle12c/
47- if cred . private . data =~ /T:([\d A-F]{160})/ # oracle 12c
48- return "#{ cred . public . username } :$oracle12c$#{ Regexp . last_match ( 1 ) . downcase } :#{ cred . id } :"
57+ if private_data =~ /T:([\d A-F]{160})/ # oracle 12c
58+ return "#{ username } :$oracle12c$#{ Regexp . last_match ( 1 ) . downcase } :#{ db_id } :"
4959 end
5060 when /dynamic_1506/
51- if cred . private . data =~ /H:([\d A-F]{32})/ # oracle 11
52- return "#{ cred . public . username . upcase } :$dynamic_1506$#{ Regexp . last_match ( 1 ) } :#{ cred . id } :"
61+ if private_data =~ /H:([\d A-F]{32})/ # oracle 11
62+ return "#{ username . upcase } :$dynamic_1506$#{ Regexp . last_match ( 1 ) } :#{ db_id } :"
5363 end
5464 when /oracle/ # oracle
55- if cred . private . jtr_format . start_with? ( 'des' ) # 'des,oracle', not oracle11/12c
56- return "#{ cred . public . username } :O$#{ cred . public . username } ##{ cred . private . data } :#{ cred . id } :"
65+ if format . start_with? ( 'des' ) # 'des,oracle', not oracle11/12c
66+ return "#{ username } :O$#{ username } ##{ private_data } :#{ db_id } :"
5767 end
5868 when /md5|des|bsdi|crypt|bf|sha256|sha512|xsha512/
5969 # md5(crypt), des(crypt), b(crypt), sha256(crypt), sha512(crypt), xsha512
60- return "#{ cred . public . username } :#{ cred . private . data } :::::#{ cred . id } :"
70+ return "#{ username } :#{ private_data } :::::#{ db_id } :"
6171 when /xsha/
6272 # xsha512
63- return "#{ cred . public . username } :#{ cred . private . data . upcase } :::::#{ cred . id } :"
73+ return "#{ username } :#{ private_data . upcase } :::::#{ db_id } :"
6474 when /netntlm/
65- return "#{ cred . private . data } ::::::#{ cred . id } :"
75+ return "#{ private_data } ::::::#{ db_id } :"
6676 when /qnx/
6777 # https://moar.so/blog/qnx-password-hash-formats.html
68- hash = cred . private . data . end_with? ( ':0:0' ) ? cred . private . data : "#{ cred . private . data } :0:0"
69- return "#{ cred . public . username } :#{ hash } "
78+ hash = private_data . end_with? ( ':0:0' ) ? private_data : "#{ private_data } :0:0"
79+ return "#{ username } :#{ hash } "
7080 when /Raw-MD5u/
7181 # This is just md5(unicode($p)), where $p is the password.
7282 # Avira uses to store their passwords, there may be other apps that also use this though.
7383 # The trailing : shows an empty salt. This is because hashcat only has one unicode hash
7484 # format which is compatible, type 30, but that is listed as md5(utf16le($pass).$salt)
7585 # with a sample hash of b31d032cfdcf47a399990a71e43c5d2a:144816. So this just outputs
7686 # The hash as *hash*: so that it is both JTR and hashcat compatible
77- return "#{ cred . private . data } :"
87+ return "#{ private_data } :"
7888 when /vnc/
7989 # add a beginning * if one is missing
80- return "$vnc$#{ cred . private . data . start_with? ( '*' ) ? cred . private . data . upcase : "*#{ cred . private . data . upcase } " } "
90+ return "$vnc$#{ private_data . start_with? ( '*' ) ? private_data . upcase : "*#{ private_data . upcase } " } "
8191 when /^(krb5.|timeroast$)/
82- return cred . private . data
92+ return private_data
8393 else
8494 # /mysql|mysql-sha1/
8595 # /mssql|mssql05|mssql12/
@@ -93,9 +103,10 @@ def self.hash_to_jtr(cred)
93103 # /mscash2/
94104 # This also handles *other* type credentials which aren't guaranteed to have a public
95105
96- return "#{ cred . public . nil? ? ' ' : cred . public . username } :#{ cred . private . data } :#{ cred . id } :"
106+ return "#{ username } :#{ private_data } :#{ db_id } :"
97107 end
98108 end
109+
99110 nil
100111 end
101112
0 commit comments