CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/metasploit/framework/hashes.rb
Views: 11779
1
module Metasploit
2
module Framework
3
# This module contains utilities for hashes, including one to identify them
4
# Resource list:
5
# https://code.google.com/archive/p/hash-identifier/
6
# https://github.com/psypanda/hashID
7
# https://hashcat.net/wiki/doku.php?id=example_hashes
8
# http://pentestmonkey.net/cheat-sheet/john-the-ripper-hash-formats
9
# https://openwall.info/wiki/john/sample-hashes
10
# QNX formats -> https://moar.so/blog/qnx-password-hash-formats.html
11
# rubocop:disable Metrics/ModuleLength
12
module Hashes
13
JTR_NTLMV1 = 'netntlm'.freeze
14
JTR_NTLMV2 = 'netntlmv2'.freeze
15
def self.identify_hash(hash)
16
# @param [str] a string of a hashed password
17
# @return [String] the jtr type or empty string on no match
18
hash = hash.to_s.strip
19
case
20
# operating systems
21
when hash.start_with?('$1$') && hash.length == 34
22
return 'md5'
23
when hash.start_with?('$2$') && hash.length == 59,
24
hash.start_with?('$2a$') && hash.length == 60,
25
hash.start_with?('$2b$') && hash.length == 60,
26
hash.start_with?('$2x$') && hash.length == 60,
27
hash.start_with?('$2y$') && hash.length == 60
28
return 'bf' # bcrypt
29
when hash.start_with?('$5$') && hash.split('$').last.length == 43
30
# we dont check full length since it may have 'rounds=' in the [1] area or not with an arbitrary length number
31
return 'sha256,crypt'
32
when hash.start_with?('$6$') && hash.split('$').last.length == 86
33
# we dont check full length since it may have 'rounds=' in the [1] area or not with an arbitrary length number
34
return 'sha512,crypt'
35
when hash.start_with?('@S@') && hash.length == 148
36
return 'qnx,sha512'
37
when hash.start_with?('@s@') && hash.length == 84
38
return 'qnx,sha256'
39
when hash.start_with?('@m@') && hash.length == 52
40
return 'qnx,md5'
41
when hash.start_with?('$y$') && hash.split('$').last.length == 43
42
return 'yescrypt'
43
when hash.start_with?('_') && hash.length == 20
44
return 'des,bsdi,crypt'
45
when hash =~ %r{^[./\dA-Za-z]{13}$} # hash.length == 13
46
return 'des,crypt'
47
when hash =~ /^\$dynamic_82\$[\da-f]{128}\$HEX\$[\da-f]{32}$/ # jtr vmware ldap https://github.com/rapid7/metasploit-framework/pull/13865#issuecomment-660718108
48
return 'dynamic_82'
49
when hash.start_with?(/{SSHA}/i)
50
return 'ssha'
51
when hash.start_with?(/{SHA512}/i)
52
return 'raw-sha512'
53
when hash.start_with?(/{SHA256}/i)
54
return 'raw-sha256'
55
when hash.start_with?(/{SHA}/i)
56
return 'raw-sha1'
57
when hash.start_with?(/{MD5}/i)
58
return 'raw-md5'
59
when hash.start_with?(/{SMD5}/i)
60
return 'smd5'
61
when hash.start_with?(/{SSHA256}/i)
62
return 'ssha256'
63
when hash.start_with?(/{SSHA512}/i)
64
return 'ssha512'
65
# windows
66
when hash.length == 65 && hash =~ /^[\da-fA-F]{32}:[\da-fA-F]{32}$/ && hash.split(':').first.upcase == 'AAD3B435B51404EEAAD3B435B51404EE'
67
return 'nt'
68
when hash.length == 65 && hash =~ /^[\da-fA-F]{32}:[\da-fA-F]{32}$/
69
return 'lm'
70
when hash =~ /^[^\\\/:*?"<>|]{1,20}[:]{2,3}([^\\\/:*?"<>|]{1,20})?:[a-f0-9]{48}:[a-f0-9]{48}:[a-f0-9]{16}$/
71
return 'netntlm'
72
when hash =~ /^([^\\\/:*?"<>|]{1,20}\\)?[^\\\/:*?"<>|]{1,20}[:]{2,3}([^\\\/:*?"<>|]{1,20}:)?[^\\\/:*?"<>|]{1,20}:[a-f0-9]{32}:[a-f0-9]+$/
73
return 'netntlmv2'
74
# OSX
75
when hash.start_with?('$ml$') && hash.split('$').last.length == 256
76
return 'pbkdf2-hmac-sha512,osx' # 10.8+
77
when hash =~ /^[\da-fA-F]{48}$/ # hash.length == 48
78
return 'xsha,osx' # 10.4-10.6
79
# databases
80
when hash.start_with?('0x0100') && hash.length == 54
81
return 'mssql05'
82
when hash.start_with?('0x0100') && hash.length == 94
83
return 'mssql'
84
when hash.start_with?('0x0200') && hash.length == 142
85
return 'mssql12'
86
when hash =~ /^[\da-f]{16}$/ # hash.length == 16
87
return 'mysql' # mysql323 (pre 4.1)
88
when hash.start_with?('*') && hash.length == 41
89
return 'mysql-sha1' # mysql 4.1+
90
when hash.start_with?('md5') && hash.length == 35
91
return 'postgres'
92
when hash =~ /^[\da-fA-F]{16}$/
93
return 'des,oracle' # pre 11g
94
when hash =~ /^S:[\dA-F]{60}$/
95
return 'raw-sha1,oracle11'
96
when hash =~ /^S:[\dA-F]{60};H:[\dA-F]{32};T:[\dA-F]{160}$/
97
return 'raw-sha1,oracle'
98
when hash =~ /^H:[\dA-F]{32};T:[\dA-F]{160}$/
99
return 'pbkdf2,oracle12c'
100
# webapps
101
when hash.start_with?('$P$') && hash.length == 34,
102
hash.start_with?('$H$') && hash.length == 34
103
return 'phpass' # wordpress, drupal, phpbb3 (H not P)
104
when hash.start_with?('$ml$') && hash.length == 203
105
return 'PBKDF2-HMAC-SHA512'
106
when hash.start_with?('{PKCS5S2}') && hash.length == 73
107
return 'PBKDF2-HMAC-SHA1'
108
when hash.start_with?('$B$') && hash.split('$').last.length == 32
109
return 'mediawiki'
110
# mobile
111
when hash =~ /^[A-F0-9]{40}:[a-f0-9]{16}$/
112
return 'android-sha1'
113
when hash =~ /^[A-F0-9]{32}:[a-f0-9]{16}$/
114
return 'android-md5'
115
# other
116
when hash =~ /^<\d+@.+?>#\w{32}$/
117
return 'hmac-md5'
118
when hash.length == 114 && hash.start_with?('$M$')
119
return 'F5-Secure-Vault'
120
when hash =~ /^M\$[[:print:]]+#[\da-fA-F]{32}(?:(?::[[:print:]]*$)|$)/
121
return 'mscash'
122
when hash =~ /^\$DCC2\$\d+#[[:print:]]+#[\da-fA-F]{32}(?:(?::[[:print:]]*$)|$)/
123
return 'mscash2'
124
when hash =~ /^\*?[\da-fA-F]{32}\*[\da-fA-F]{32}$/
125
# we accept the beginning star as optional
126
return 'vnc'
127
when hash =~ /^\$pbkdf2-sha256\$[0-9]+\$[a-z0-9\/.]+\$[a-z0-9\/.]{43}$/i
128
return 'pbkdf2-sha256'
129
end
130
''
131
end
132
# rubocop:enable Metrics/ModuleLength
133
end
134
end
135
end
136
137