Class: Metasploit::Framework::PasswordCracker::Cracker
- Inherits:
-
Object
- Object
- Metasploit::Framework::PasswordCracker::Cracker
- Includes:
- ActiveModel::Validations
- Defined in:
- lib/metasploit/framework/password_crackers/cracker.rb
Instance Attribute Summary collapse
-
#attack ⇒ String
The attack mode for hashcat to use (not applicable to John).
-
#config ⇒ String
The path to an optional config file for John to use.
-
#cracker ⇒ String
Which cracker to use.
-
#cracker_path ⇒ String
This attribute allows the user to specify a cracker binary to use.
-
#fork ⇒ String
If the cracker type is john, the amount of forks to specify.
-
#format ⇒ String
If the cracker type is john, this format will automatically be translated to the hashcat equivalent via jtr_format_to_hashcat_format.
-
#hash_path ⇒ String
The path to the file containing the hashes.
-
#increment_length ⇒ Array
The incremental min and max to use.
-
#incremental ⇒ String
The incremental mode to use.
-
#mask ⇒ Object
If the cracker type is hashcat, If set, the mask to use.
-
#max_length ⇒ Integer
An optional maximum length of password to attempt cracking.
-
#max_runtime ⇒ Integer
An optional maximum duration of the cracking attempt in seconds.
-
#optimize ⇒ Boolean
If the Optimize flag should be given to Hashcat.
-
#pot ⇒ String
The file path to an alternative John pot file to use.
-
#rules ⇒ String
The wordlist mangling rules to use inside John/Hashcat.
-
#wordlist ⇒ String
The file path to the wordlist to use.
Instance Method Summary collapse
-
#binary_path ⇒ NilClass, String
This method follows a decision tree to determine the path to the cracker binary we should use.
-
#crack {|String| ... } ⇒ void
This method runs the command from #crack_command and yields each line of output.
-
#cracker_session_id ⇒ Object
This method is a getter for a random Session ID for the cracker.
-
#cracker_version ⇒ Sring
This method returns the version of John the Ripper or Hashcat being used.
-
#each_cracked_password ⇒ Array
This runs the show command in john and yields cracked passwords.
-
#hashcat_crack_command ⇒ Array
This method builds an array for the command to actually run the cracker.
-
#initialize(attributes = {}) ⇒ Cracker
constructor
A new instance of Cracker.
-
#john_config_file ⇒ String
This method returns the path to a default john.conf file.
-
#john_crack_command ⇒ Array
This method builds an array for the command to actually run the cracker.
-
#john_pot_file ⇒ String
This method returns the path to a default john.pot file.
-
#jtr_format_to_hashcat_format(format) ⇒ String
This method takes a frameworkframework.dbframework.db.credframework.db.cred.privateframework.db.cred.private.jtr_format (string), and returns the string number associated to the hashcat format.
-
#mode_incremental ⇒ Object
This method sets the appropriate parameters to run a cracker in incremental mode.
-
#mode_normal ⇒ Object
This method sets the john to 'normal' mode.
-
#mode_pin ⇒ Object
This method sets the appropriate parameters to run a cracker in a pin mode (4-8 digits) on hashcat.
-
#mode_single(file) ⇒ Object
This method sets the john to single mode.
-
#mode_wordlist(file) ⇒ Object
This method sets the appropriate parameters to run a cracker in wordlist mode.
-
#show_command ⇒ Array
This method builds the command to show the cracked passwords.
Constructor Details
#initialize(attributes = {}) ⇒ Cracker
Returns a new instance of Cracker.
118 119 120 121 122 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 118 def initialize(attributes={}) attributes.each do |attribute, value| public_send("#{attribute}=", value) end end |
Instance Attribute Details
#attack ⇒ String
Returns The attack mode for hashcat to use (not applicable to John).
13 14 15 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 13 def attack @attack end |
#config ⇒ String
Returns The path to an optional config file for John to use.
17 18 19 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 17 def config @config end |
#cracker ⇒ String
Returns Which cracker to use. 'john' and 'hashcat' are valid.
21 22 23 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 21 def cracker @cracker end |
#cracker_path ⇒ String
This attribute allows the user to specify a cracker binary to use. If not supplied, the Cracker will search the PATH for a suitable john or hashcat binary and finally fall back to the pre-compiled john versions shipped with Metasploit.
29 30 31 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 29 def cracker_path @cracker_path end |
#fork ⇒ String
If the cracker type is john, the amount of forks to specify
42 43 44 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 42 def fork @fork end |
#format ⇒ String
If the cracker type is john, this format will automatically be translated to the hashcat equivalent via jtr_format_to_hashcat_format
36 37 38 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 36 def format @format end |
#hash_path ⇒ String
Returns The path to the file containing the hashes.
46 47 48 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 46 def hash_path @hash_path end |
#increment_length ⇒ Array
Returns The incremental min and max to use.
54 55 56 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 54 def increment_length @increment_length end |
#incremental ⇒ String
Returns The incremental mode to use.
50 51 52 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 50 def incremental @incremental end |
#mask ⇒ Object
If the cracker type is hashcat, If set, the mask to use. Should consist of the character sets pre-defined by hashcat, such as ?d ?s ?l etc
@return [String] The mask to use
61 62 63 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 61 def mask @mask end |
#max_length ⇒ Integer
Returns An optional maximum length of password to attempt cracking.
69 70 71 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 69 def max_length @max_length end |
#max_runtime ⇒ Integer
Returns An optional maximum duration of the cracking attempt in seconds.
65 66 67 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 65 def max_runtime @max_runtime end |
#optimize ⇒ Boolean
Returns If the Optimize flag should be given to Hashcat.
73 74 75 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 73 def optimize @optimize end |
#pot ⇒ String
Returns The file path to an alternative John pot file to use.
77 78 79 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 77 def pot @pot end |
#rules ⇒ String
Returns The wordlist mangling rules to use inside John/Hashcat.
81 82 83 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 81 def rules @rules end |
#wordlist ⇒ String
Returns The file path to the wordlist to use.
85 86 87 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 85 def wordlist @wordlist end |
Instance Method Details
#binary_path ⇒ NilClass, String
This method follows a decision tree to determine the path to the cracker binary we should use.
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 274 def binary_path # Always prefer a manually entered path if cracker_path && ::File.file?(cracker_path) return cracker_path else # Look in the Environment PATH for the john binary if cracker == 'john' path = Rex::FileUtils.find_full_path("john") || Rex::FileUtils.find_full_path("john.exe") elsif cracker == 'hashcat' path = Rex::FileUtils.find_full_path("hashcat") || Rex::FileUtils.find_full_path("hashcat.exe") else raise PasswordCrackerNotFoundError, 'No suitable Cracker was selected, so a binary could not be found on the system' end if path && ::File.file?(path) return path end raise PasswordCrackerNotFoundError, 'No suitable john/hashcat binary was found on the system' end end |
#crack {|String| ... } ⇒ void
This method returns an undefined value.
This method runs the command from #crack_command and yields each line of output.
302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 302 def crack if cracker == 'john' results = john_crack_command elsif cracker == 'hashcat' results = hashcat_crack_command end ::IO.popen(results, "rb") do |fd| fd.each_line do |line| yield line end end end |
#cracker_session_id ⇒ Object
This method is a getter for a random Session ID for the cracker. It allows us to dinstiguish between cracking sessions.
@ return [String] the Session ID to use
507 508 509 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 507 def cracker_session_id @session_id ||= ::Rex::Text.rand_text_alphanumeric(8) end |
#cracker_version ⇒ Sring
This method returns the version of John the Ripper or Hashcat being used.
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 319 def cracker_version if cracker == 'john' cmd = binary_path elsif cracker == 'hashcat' cmd = binary_path cmd << (" -V") end ::IO.popen(cmd, "rb") do |fd| fd.each_line do |line| if cracker == 'john' # John the Ripper 1.8.0.13-jumbo-1-bleeding-973a245b96 2018-12-17 20:12:51 +0100 OMP [linux-gnu 64-bit x86_64 AVX2 AC] # John the Ripper 1.9.0-jumbo-1 OMP [linux-gnu 64-bit x86_64 AVX2 AC] # John the Ripper password cracker, version 1.8.0.2-bleeding-jumbo_omp [64-bit AVX-autoconf] # John the Ripper password cracker, version 1.8.0 return $1.strip if line =~ /John the Ripper(?: password cracker, version)? ([^\[]+)/ elsif cracker == 'hashcat' # v5.1.0 return $1 if line =~ /(v[\d\.]+)/ end end end nil end |
#each_cracked_password ⇒ Array
This runs the show command in john and yields cracked passwords.
485 486 487 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 485 def each_cracked_password ::IO.popen(show_command, "rb").readlines end |
#hashcat_crack_command ⇒ Array
This method builds an array for the command to actually run the cracker. It builds the command from all of the attributes on the class.
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 400 def hashcat_crack_command cmd_string = binary_path cmd = [cmd_string, '--session=' + cracker_session_id, '--logfile-disable'] if pot.present? cmd << ("--potfile-path=" + pot) else cmd << ("--potfile-path=" + john_pot_file) end if format.present? cmd << ("--hash-type=" + jtr_format_to_hashcat_format(format)) end if optimize.present? # https://hashcat.net/wiki/doku.php?id=frequently_asked_questions#what_is_the_maximum_supported_password_length_for_optimized_kernels # Optimized Kernels has a large impact on speed. Here are some stats from Hashcat 5.1.0: # Kali Linux on Dell Precision M3800 ## hashcat -b -w 2 -m 0 # * Device #1: Quadro K1100M, 500/2002 MB allocatable, 2MCU # Speed.#1.........: 185.9 MH/s (11.15ms) @ Accel:64 Loops:16 Thr:1024 Vec:1 ## hashcat -b -w 2 -O -m 0 # * Device #1: Quadro K1100M, 500/2002 MB allocatable, 2MCU # Speed.#1.........: 463.6 MH/s (8.92ms) @ Accel:64 Loops:32 Thr:1024 Vec:1 # Windows 10 # PS C:\hashcat-5.1.0> .\hashcat64.exe -b -O -w 2 -m 0 # * Device #1: GeForce RTX 2070 SUPER, 2048/8192 MB allocatable, 40MCU # Speed.#1.........: 13914.0 MH/s (5.77ms) @ Accel:128 Loops:64 Thr:256 Vec:1 # PS C:\hashcat-5.1.0> .\hashcat64.exe -b -O -w 2 -m 0 # * Device #1: GeForce RTX 2070 SUPER, 2048/8192 MB allocatable, 40MCU # Speed.#1.........: 31545.6 MH/s (10.36ms) @ Accel:256 Loops:128 Thr:256 Vec:1 # This change should result in 225%-250% speed boost at the sacrifice of some password length, which most likely # wouldn't be tested inside of MSF since most users are using the MSF modules for word list and easy cracks. # Anything of length where this would cut off is most likely being done independently (outside MSF) cmd << ("-O") end if incremental.present? cmd << ("--increment") if increment_length.present? cmd << ("--increment-min=" + increment_length[0].to_s) cmd << ("--increment-max=" + increment_length[1].to_s) else # anything more than max 4 on even des took 8+min on an i7. # maybe in the future this can be adjusted or made a variable # but current time, we'll leave it as this seems like reasonable # time expectation for a module to run cmd << ("--increment-max=4") end end if rules.present? cmd << ("--rules-file=" + rules) end if attack.present? cmd << ("--attack-mode=" + attack) end if max_runtime.present? cmd << ("--runtime=" + max_runtime.to_s) end cmd << hash_path if mask.present? cmd << mask.to_s end # must be last if wordlist.present? cmd << (wordlist) end cmd end |
#john_config_file ⇒ String
This method returns the path to a default john.conf file.
492 493 494 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 492 def john_config_file ::File.join(::Msf::Config.data_directory, "jtr", "john.conf") end |
#john_crack_command ⇒ Array
This method builds an array for the command to actually run the cracker. It builds the command from all of the attributes on the class.
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 348 def john_crack_command cmd_string = binary_path cmd = [cmd_string, '--session=' + cracker_session_id, '--nolog'] if config.present? cmd << ("--config=" + config) else cmd << ("--config=" + john_config_file) end if pot.present? cmd << ("--pot=" + pot) else cmd << ("--pot=" + john_pot_file) end if fork.present? && fork > 1 cmd << ("--fork=" + fork.to_s) end if format.present? cmd << ("--format=" + format) end if wordlist.present? cmd << ("--wordlist=" + wordlist) end if incremental.present? cmd << ("--incremental=" + incremental) end if rules.present? cmd << ("--rules=" + rules) end if max_runtime.present? cmd << ("--max-run-time=" + max_runtime.to_s) end if max_length.present? cmd << ("--max-len=" + max_length.to_s) end cmd << hash_path end |
#john_pot_file ⇒ String
This method returns the path to a default john.pot file.
499 500 501 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 499 def john_pot_file ::File.join(::Msf::Config.config_directory, "john.pot") end |
#jtr_format_to_hashcat_format(format) ⇒ String
This method takes a Metasploit::Framework::PasswordCracker::Cracker.frameworkframework.dbframework.db.credframework.db.cred.privateframework.db.cred.private.jtr_format (string), and returns the string number associated to the hashcat format
@param a jtr_format string
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 129 def jtr_format_to_hashcat_format(format) case format when 'md5crypt' '500' when 'descrypt' '1500' when 'bsdicrypt' '12400' when 'sha256crypt' '7400' when 'sha512crypt' '1800' when 'bcrypt' '3200' when 'lm', 'lanman' '3000' when 'nt', 'ntlm' '1000' when 'mssql' '131' when 'mssql05' '132' when 'mssql12' '1731' # hashcat requires a format we dont have all the data for # in the current dumper, so this is disabled in module and lib #when 'oracle', 'des,oracle' # return '3100' when 'oracle11', 'raw-sha1,oracle' '112' when 'oracle12c', 'pbkdf2,oracle12c' '12300' when 'postgres', 'dynamic_1034', 'raw-md5,postgres' '12' when 'mysql' '200' when 'mysql-sha1' '300' when 'PBKDF2-HMAC-SHA512' # osx 10.8+ '7100' when 'xsha' # osx 10.4-6 '122' when 'xsha512' # osx 10.7 '1722' when 'PBKDF2-HMAC-SHA1' # Atlassian '12001' when 'phpass' # Wordpress/PHPass, Joomla, phpBB3 '400' when 'mediawiki' # mediawiki b type '3711' when 'android-samsung-sha1' '5800' when 'android-sha1' '110' when 'android-md5' '10' when 'hmac-md5' '10200' when 'dynamic_82' '1710' else nil end end |
#mode_incremental ⇒ Object
This method sets the appropriate parameters to run a cracker in incremental mode
196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 196 def mode_incremental self.increment_length = nil self.wordlist = nil self.mask = nil self.max_runtime = nil if cracker == 'john' self.rules = nil self.incremental = 'Digits' elsif cracker == 'hashcat' self.attack = '3' self.incremental = true end end |
#mode_normal ⇒ Object
This method sets the john to 'normal' mode
243 244 245 246 247 248 249 250 251 252 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 243 def mode_normal if cracker == 'john' self.max_runtime = nil self.mask = nil self.wordlist = nil self.rules = nil self.incremental = nil self.increment_length = nil end end |
#mode_pin ⇒ Object
This method sets the appropriate parameters to run a cracker in a pin mode (4-8 digits) on hashcat
230 231 232 233 234 235 236 237 238 239 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 230 def mode_pin self.rules = nil if cracker == 'hashcat' self.attack = '3' self.mask = '?d'*8 self.incremental = true self.increment_length = [4,8] self.max_runtime = 300 #5min on an i7 got through 4-7 digits. 8digit was 32min more end end |
#mode_single(file) ⇒ Object
This method sets the john to single mode
@param a file location of the wordlist to use
258 259 260 261 262 263 264 265 266 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 258 def mode_single(file) if cracker == 'john' self.wordlist = file self.rules = 'single' self.incremental = nil self.increment_length = nil self.mask = nil end end |
#mode_wordlist(file) ⇒ Object
This method sets the appropriate parameters to run a cracker in wordlist mode
@param a file location of the wordlist to use
214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 214 def mode_wordlist(file) self.increment_length = nil self.incremental = nil self.max_runtime = nil self.mask = nil if cracker == 'john' self.wordlist = file self.rules = 'wordlist' elsif cracker == 'hashcat' self.wordlist = file self.attack = '0' end end |
#show_command ⇒ Array
This method builds the command to show the cracked passwords.
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
# File 'lib/metasploit/framework/password_crackers/cracker.rb', line 515 def show_command cmd_string = binary_path pot_file = pot || john_pot_file if cracker=='hashcat' cmd = [cmd_string, "--show", "--potfile-path=#{pot_file}", "--hash-type=#{jtr_format_to_hashcat_format(format)}"] elsif cracker=='john' cmd = [cmd_string, "--show", "--pot=#{pot_file}", "--format=#{format}"] if config cmd << "--config=#{config}" else cmd << ("--config=" + john_config_file) end end cmd << hash_path end |