@@ -9,19 +9,29 @@ module Formatter
9
9
# @param cred [credClass] A credential from framework.db
10
10
# @return [String] The hash in jtr format or nil on no match.
11
11
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/
17
27
# john --list=subformats | grep 'PostgreSQL MD5'
18
28
# UserFormat = dynamic_1034 type = dynamic_1034: md5($p.$u) (PostgreSQL MD5)
19
- hash_string = cred . private . data
29
+ hash_string = private_data
20
30
hash_string . gsub! ( /^md5/ , '' )
21
- return "#{ cred . public . username } :$dynamic_1034$#{ hash_string } :#{ cred . id } :"
31
+ return "#{ username } :$dynamic_1034$#{ hash_string } :#{ db_id } :"
22
32
end
23
- when 'Metasploit::Credential::NonreplayableHash'
24
- case cred . private . jtr_format
33
+ when :nonreplayable_hash
34
+ case format
25
35
# oracle 11+ password hash descriptions:
26
36
# this password is stored as a long ascii string with several sections
27
37
# 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)
40
50
# T: = 160 characters
41
51
# PBKDF2-based SHA512 hash specific to 12C (12.1.0.2+)
42
52
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 } :"
45
55
end
46
56
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 } :"
49
59
end
50
60
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 } :"
53
63
end
54
64
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 } :"
57
67
end
58
68
when /md5|des|bsdi|crypt|bf|sha256|sha512|xsha512/
59
69
# 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 } :"
61
71
when /xsha/
62
72
# xsha512
63
- return "#{ cred . public . username } :#{ cred . private . data . upcase } :::::#{ cred . id } :"
73
+ return "#{ username } :#{ private_data . upcase } :::::#{ db_id } :"
64
74
when /netntlm/
65
- return "#{ cred . private . data } ::::::#{ cred . id } :"
75
+ return "#{ private_data } ::::::#{ db_id } :"
66
76
when /qnx/
67
77
# 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 } "
70
80
when /Raw-MD5u/
71
81
# This is just md5(unicode($p)), where $p is the password.
72
82
# Avira uses to store their passwords, there may be other apps that also use this though.
73
83
# The trailing : shows an empty salt. This is because hashcat only has one unicode hash
74
84
# format which is compatible, type 30, but that is listed as md5(utf16le($pass).$salt)
75
85
# with a sample hash of b31d032cfdcf47a399990a71e43c5d2a:144816. So this just outputs
76
86
# The hash as *hash*: so that it is both JTR and hashcat compatible
77
- return "#{ cred . private . data } :"
87
+ return "#{ private_data } :"
78
88
when /vnc/
79
89
# 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 } " } "
81
91
when /^(krb5.|timeroast$)/
82
- return cred . private . data
92
+ return private_data
83
93
else
84
94
# /mysql|mysql-sha1/
85
95
# /mssql|mssql05|mssql12/
@@ -93,9 +103,10 @@ def self.hash_to_jtr(cred)
93
103
# /mscash2/
94
104
# This also handles *other* type credentials which aren't guaranteed to have a public
95
105
96
- return "#{ cred . public . nil? ? ' ' : cred . public . username } :#{ cred . private . data } :#{ cred . id } :"
106
+ return "#{ username } :#{ private_data } :#{ db_id } :"
97
107
end
98
108
end
109
+
99
110
nil
100
111
end
101
112
0 commit comments