Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/data/jtr/john.conf
Views: 11766
#1# This file is part of John the Ripper password cracker,2# Copyright (c) 1996-2006,2008-2013,2019 by Solar Designer3#4# Redistribution and use in source and binary forms, with or without5# modification, are permitted.6#7# There's ABSOLUTELY NO WARRANTY, express or implied.8#9# Please note that although this configuration file is under the cut-down BSD10# license above, many source files in John the Ripper are under GPLv2.11# For licensing terms for John the Ripper as a whole, see doc/LICENSE.12#13# ...with changes in the jumbo patch, by various authors14#1516# The [Options] section is for general options only.17# Note that MPI specific options have been moved18# to [Options.MPI]19# There is also a new section [Options.OpenCL]20# for OpenCL specific options21# Default settings for Markov mode have been moved22# to [Markov.Default], but you can define other23# Markov modes as well, see ../doc/MARKOV24[Options]25# Default wordlist file name (including in batch mode)26Wordlist = $JOHN/password.lst27# Use idle cycles only28Idle = Y29# Crash recovery file saving delay in seconds30Save = 6031# Beep when a password is found (who needs this anyway?)32Beep = N33# if set to Y then dynamic format will always work with bare hashes. Normally34# dynamic only uses bare hashes if a single dynamic type is selected with35# the -format= (so -format=dynamic_0 would use valid bare hashes).36DynamicAlwaysUseBareHashes = N3738# Default Single mode rules39SingleRules = Single4041# Default batch mode Wordlist rules42BatchModeWordlistRules = Wordlist4344# Default wordlist mode rules when not in batch mode (if any). If this is45# changed from an 'empty list' to have default rules applied, and you later46# DO want to perform a run once without rules, use --rules:none on the47# command line. The default is 'empty' or NO rules run at all.48WordlistRules =4950# Default loopback mode rules (if any)51# If this is set and you want to run once without rules, use --rules:none52LoopbackRules = Loopback5354# Max. number of times to warn about crypting suboptimally small batches,55# before suppressing the warnings.56MaxKPCWarnings = 105758# Default/batch mode Incremental mode59# Warning: changing these might currently break resume on existing sessions60# one option frequently changed (with above caveat) is setting DefaultIncrementalUTF8 = UTF861DefaultIncremental = ASCII62DefaultIncrementalUTF8 = ASCII63DefaultIncrementalLM = LM_ASCII6465# Time formatting string used in status ETA.66#67# TimeFormat24 is used when ETA is within 24h, so it is possible to omit68# the date then if you like, and show seconds instead.69#70# %c means 'local' specific canonical form, such as:71# 05/06/11 18:10:3472#73# Other examples74# %d/%m/%y %H:%M (day/mon/year hour:min)75# %m/%d/%y %H:%M (mon/day/year hour:min)76# %Y-%m-%d %H:%M (ISO 8601 style, 2011-05-06 18:10)77TimeFormat = %Y-%m-%d %H:%M78TimeFormat24 = %H:%M:%S7980#81# optional add a date timestamp in front of every logged line.82# the default is no timestamp logging. See the docs for83# strftime for more information:84# http://en.cppreference.com/w/c/chrono/strftime85#86# examples:87# 2016-02-20T22:35:38+01:00 would be %Y-%m-%dT%H:%M:%S%z88# Feb 20 22:35:38 would be %b %d %H:%M:%S89LogDateFormat =9091# if log date is being used, the time will default to local92# time. But if the next line is changed to 'Y', date output93# in UTC. Note, if LogDateFormat is not set, this option94# is ignored.95LogDateFormatUTC = N9697# if logging to stderr (--log-stderr command line switch used),98# then use date format when outputting to the stderr.99#100# example101# Feb 20 22:35:38 would be %b %d %H:%M:%S102LogDateStderrFormat =103104# If this is given, it will be printed in the end on any cracked password105# output. In case some 8-bit passwords upset your terminal, putting an106# ANSI "SGR Reset/Normal" here might be a cure. Any "^" characters will be107# parsed as ESC for use in ANSI codes (like in the default)108TerminalReset = ^[0m109110# This can be used to colorize (on screen) or otherwise emphasize (in log111# files) output whenever a supposed administrator password gets cracked.112#113# Set this to N or comment it out to disable all "MarkAdmin" stuff.114MarkAdminCracks = Y115116# If MarkAdminCracks = Y above, the below will be used (if defined) for117# terminal output. The default is to change color to red before the username118# and reset to normal after it. Any "^" characters will be parsed as ESC for119# use in ANSI codes (like in the defaults).120# The "MarkOther" entries will make non-admin stuff brown.121MarkAdminStart = ^[0;31m122MarkAdminEnd = ^[0m123MarkOtherStart = ^[0;33m124MarkOtherEnd = ^[0m125126# If MarkAdminCracks = Y above, the below will be used (if defined) for logs.127# This literal string will be printed after the " + Cracked: root" line.128MarkAdminString = (ADMIN ACCOUNT)129130# Permissions to set for session.log file131# Default is 0600132LogFilePermissions = 0600133134# Permissions to set for POT file135# Default is 0600136PotFilePermissions = 0600137138# John exits if another user owns log or pot file because CHMOD fails,139# If this is set John prints a warning and continues140# Default is N141IgnoreChmodErrors = N142143# This figure is in MiB. The default is to memory map wordlists not larger144# than one GiB.145# Set this to 0 to disable any use of memory-mapping in wordlist mode.146WordlistMemoryMapMaxSize = 1024147148# For single mode, load the full GECOS field (before splitting) as one149# additional candidate. Normal behavior is to only load individual words150# from that field. Enabling this can help when this field contains email151# addresses or other strings that are better used unsplit, but it increases152# the number of words tried so it may also slow things down.153PristineGecos = N154155# Add an extra pass when loading Single words, that tries to parse things156# like JEdgarHoover to J Edgar Hoover and so on.157JumboSingleWords = N158159# For single mode, ignore the login field.160# Normal behavior is to use the login field for single mode.161# Skipping the login field should only be enabled if previous single mode162# sessions did already make use of the login field, but no other information,163# and now you want to use other information, skip the login field, but still164# want the login field to be reported on successful cracks or with --show.165SingleSkipLogin = N166167# Over-ride SINGLE_WORDS_PAIR_MAX in params.h. This may slow down Single mode168# but it may also help cracking a few more candidates. Default in core John169# is 4 while the Jumbo default is 6. This limit is automagically increased170# by word seed options --single-seed and/or --single-wordlist if needed.171SingleWordsPairMax = 6172173# Setting this to false stops Single mode from re-testing guessed plaintexts174# with all other salts. This is deprecated: Use command-line per-session175# option --single-retest-guess=no instead.176SingleRetestGuessed = Y177178# Max recursion depth for SingleRetestGuessed, so we don't blow the stack179SingleMaxRecursionDepth = 10000180181# Set the maximum word buffer size used by Single mode. The default is182# 4 GB. Note that you may want to set SingleMaxBufferAvailMem (below) to183# true instead.184#185# If this figure is explicitly set to zero, and SingleMaxBufferAvailMem186# is false, there will be NO LIMIT!187SingleMaxBufferSize = 4188189# If true, the actual amount of physical memory at runtime, if known, will190# override the figure from SingleMaxBufferSize (may increase or decrease!).191SingleMaxBufferAvailMem = N192193# When running single mode with a GPU or accelerator, we prioritize speed194# (saturating buffers) over resume ability: When resuming such a session195# it may take longer to catch up. Set this option to Y to prioritize196# resuming instead, at the cost of max. speed.197SinglePrioResume = N198199# Protect the restore files (*.rec) from being overwritten. The default200# mode is "Disabled". This mode will provide no protection, but has been201# the default mode in JtR forever, so to not change behavior, that mode202# has been kept as default. You can change this to "Named" or "Always"203# If this option is changed to "Named", then any restore file created204# with a --session=xxxx will be protected from being overwritten. If205# the option is set to "Always", then all .rec files will be kept from206# being overwritten, even ${JOHN}/john.rec file207SessionFileProtect = Disabled208209# Protect the log files (*.log) from being reused by new sessons.210# The default mode is "Disabled". That means, a nee session will just append211# to an existing log file.212# With "Named", a new session will not be allowed to append to an existing213# log file, except if the --session=NAME option hasn't been used.214# With "Always", not even the default log file ${JOHN}/john.log can be215# reused by a new session.216# (Of course, a restored session will always be allowed to append to an217# existing log file.)218# Unless you use the --no-log option, setting LogFileProtect will also219# prevent overwriting existing session files.220LogFileProtect = Disabled221222# Emit a status line whenever a password is cracked (this is the same as223# passing the --crack-status option flag to john). NOTE: if this is set224# to true here, --crack-status will toggle it back to false.225CrackStatus = N226227# When printing status, show number of candidates tried (eg. 123456p).228# This is added to the "+ Cracked" line in the log as well (and that figure229# will be exact while the screen output will be a multiple of batch size).230StatusShowCandidates = N231232# Show updated "Remaining" counts when we got rid of any salt(s).233ShowSaltProgress = N234235# Show updated "Remaining" counts on status output (if it changed).236ShowRemainOnStatus = N237238# Write cracked passwords to the log file (default is just the user name)239LogCrackedPasswords = N240241# Disable the dupe checking when loading hashes. For testing purposes only!242# This is deprecated: Use per-session option --loader-dupecheck=no instead.243NoLoaderDupeCheck = N244245# Default encoding for input files (ie. login/GECOS fields) and wordlists246# etc. If this is not set here and --encoding is not used either, the default247# is ISO-8859-1 for Unicode conversions and 7-bit ASCII encoding is assumed248# for rules, e.g., uppercasing of letters other than a-z will not work at all!249DefaultEncoding = UTF-8250251# Default --target-encoding for Microsoft hashes (LM, NETLM et al) when input252# encoding is UTF-8. CP850 would be a universal choice for covering most253# "Latin-1" countries.254DefaultMSCodepage = CP850255256# Default internal legacy codepage to be used by mask mode and within the257# rules engine, when both input and target encodings are Unicode (eg. UTF-8258# wordlist and NT hashes). In some cases this hits performance but lets us259# do things like Unicode case conversions. You can pick any supported260# legacy codepage that has as much support for the input data as possible,261# e.g., for "Latin-1" language passwords you can use ISO-8859-1, CP850 or262# CP1252 and it will hardly make any difference but in some cases, ISO-8859-1263# is fastest. Using "UTF-8" (which is not a legacy codepage!) will disable.264#265# The default is to NOT use any internal codepage.266DefaultInternalCodepage =267268# Warn if seeing UTF-8 when expecting some other encoding, or vice versa.269# This is disabled for ASCII or RAW encodings, for performance.270WarnEncoding = Y271272# Always report (to screen and log) cracked passwords as UTF-8, regardless of273# input encoding. This is recommended if you have your terminal set for UTF-8.274AlwaysReportUTF8 = Y275276# Always store Unicode (UTF-16) passwords as UTF-8 in john.pot, regardless277# of input encoding. This prevents john.pot from being filled with mixed278# and eventually unknown encodings. This is recommended if you have your279# terminal set for UTF-8 and/or you want to run --loopback for LM->NT280# including non-ASCII.281UnicodeStoreUTF8 = Y282283# Always report/store non-Unicode formats as UTF-8, regardless of input284# encoding. Note: The actual codepage that was used is not stored anywhere285# except in the log file.286# This is needed e.g. for --loopback to crack LM->NT including non-ASCII.287CPstoreUTF8 = Y288289# Normally, we try to handle Unicode characters not in our selected codepage290# with best effort. Enabling this option will instead translate any such291# character to "?" (default), to meet certain formats' behavior.292EmulateBrokenEncoding = N293ReplacementCharacter = ?294295# Default verbosity is 3, valid figures are 1-5 right now.296# 4-5 enables some extra output and diagnostics.297# 4 is same verbosity as "john proper" aka. non-jumbo.298# 3 mutes rules & incremental output in logs (LOTS of lines).299# 2 mutes some other diagnostics.300# 1 even mutes printing (to screen) of cracked passwords.301Verbosity = 3302303# If set to Y, do not output, log or store cracked passwords verbatim.304# This implies a different default .pot database file "secure.pot" instead305# of "john.pot" but it can still be overridden using --pot=FILE.306# This also overrides other options, e.g. LogCrackedPasswords.307SecureMode = N308309# If set to Y, a session using --fork or MPI will signal to other nodes when310# it has written cracks to the pot file, so they will re-sync. Note that this311# may be delayed by buffers and the "Save" timer setting near top of this file.312ReloadAtCrack = N313314# If set to Y, a session using --fork or MPI will signal to other nodes when315# it has cracked all hashes (there's nothing more to do!). This is ignored316# when ReloadAtCrack = Y because it's redundant.317ReloadAtDone = Y318319# If set to Y, resync pot file when saving session. This does not involve any320# signalling, we just detect that someone else wrote to the pot file.321# This will sync with concurrent sessions even when not using --fork or MPI322# but it may be delayed by the "Save" timer setting near top of this file.323ReloadAtSave = Y324325# If this file exists, john will abort cleanly (uncomment to enable)326#AbortFile = /var/run/john/abort327328# While this file exists, john will pause (uncomment to enable)329#PauseFile = /var/run/john/pause330331# If set to true, the uid will be appended to user name on cracks332# With: password123 (Administrator:500)333# Without password123 (Administrator)334# This is disabled by --save-memory.335# NOTE: For WPAPSK, this will actually show gid instead, which is the MAC336# address of the access point.337ShowUIDinCracks = N338339# This sets the "grace time" for --max-run-time=N. If john has not finished340# this long after the initial abort signal, it will send another one (similar341# to pressing ctrl-c a second time) which will stop john immediately and not342# wait further for an optimal resume point.343# Setting this to 0 means NO grace time - immediately abort. Setting it to344# a negative number means UNLIMITED grace time - never hard abort.345AbortGraceTime = 30346347# Setting this to true allows SAP-B and SAP-G "half hashes" to be cracked.348# These are taken from RFC_READ_TABLE and padded with nulls to correct length.349# This may produce some false positives if enabled, at least for SAP-B.350SAPhalfHashes = N351352[Options:CPUtune]353# If preset is given, use it and skip autotune (NOTE: non-intel archs will354# currently ignore this option and always autotune)355UsePreset = Y356# Performance sample time, default 10 ms357AutoTuneSampleTime = 10358# Required gain to consider this scale better. Default is 1 %359AutoTuneReqGain = 1360# Max crypt_all() duration for trying a higher scale, default 100 ms361AutoTuneMaxDuration = 100362# If we tried this many increases of scale w/o gain, give up. Default 3.363AutoTuneMaxNoProgress = 3364365[Options:MPI]366# Automagically disable OMP if MPI is used (set to N if367# you want to run one MPI process per multi-core host)368MPIOMPmutex = Y369370# Print a notice if disabling OMP (when MPIOMPmutex = Y)371# or when running OMP and MPI at the same time372MPIOMPverbose = Y373374# Assume all MPI nodes are homogenous; Enforce same OpenCL workgroup sizes.375MPIAllGPUsSame = N376377# Options that may affect both GPUs and other accelerators (eg. FPGA)378[Options:GPU]379# Show GPU temperature, fan and utilization along with normal status output380SensorsStatus = Y381382# If SensorsStatus is true, individual ones can be turned off383TempStatus = Y384UtilStatus = N385FanStatus = N386387# Abort the process or sleep for a while if a GPU hits this temperature (in C)388AbortTemperature = 95389390# Instead of aborting, sleep for this many seconds to cool the GPU down when391# the temperature hits the AbortTemperature value, then re-test the temperature392# and either wake up or go to sleep again. Set this to 0 to actually abort.393# Suppress repeated sleep/wakeup messages when SleepOnTemperature = 1, which we394# interpret as intent to keep the GPU temperature around the limit.395SleepOnTemperature = 1396397[Options:OpenCL]398# Set default OpenCL device(s). Command line option will override this.399# If not set, we will search for a GPU or fall-back to the most400# powerful device. Syntax is same as --device option.401Device =402403# *Always* show local/global work sizes (LWS/GWS). This is mostly for404# debugging, we try to show them when reasonable.405AlwaysShowWorksizes = N406407# If set to true, store LWS and GWS in session file for later resume.408# Note that when resuming, this option is ignored: If the session file409# was written with this option set, it will still be used.410ResumeWS = N411412# Global max. single kernel invocation duration, in ms. Setting this low413# (eg. 10-100 ms) gives you a better responding desktop but lower performance.414# Setting it high (eg. 200-500 ms) will maximize performance but your desktop415# may lag. Really high values may trip watchdogs (eg. 5 seconds). Some versions416# of AMD Catalyst may hang if you go above 200 ms, and in general any good417# kernel will perform optimally at 100-200 ms anyway.418Global_MaxDuration =419420# Some formats vectorize their kernels in case the device says it's a good421# idea. Some devices give "improper" hints which means we vectorize but get422# a performance drop. If you have such a device, uncommenting the below423# will disable vectorizing globally.424# With this set to N (or commented out) you can force it per session with425# the --force-scalar command-line option instead.426ForceScalar = N427428# Global build options. Format-specific build options below may be429# concatenated to this.430GlobalBuildOpts = -cl-mad-enable431432# Initial local work-size for auto-tune (CPU devices excepted).433# 0 means let the OpenCL implementation pick a suitable value.434# 1 means query for "best multiple" (usually corresponds to "warp size").435# Any other value (eg. 64) will be taken verbatim.436AutotuneLWS = 1437438# Format-specific settings:439440# Uncomment the below for nvidia sm_30 and beyond.441# Please, check if it is really better.442#sha512crypt_BuildOpts = -cl-nv-maxrregcount=80443444# Best configuration value to be used at runtime.445sha512crypt_Bonaire = -DUNROLL_LOOP=132104446447# Example: Override auto-tune for RAR format.448#rar_LWS = 128449#rar_GWS = 8192450451[List.OpenCL:Drivers]452#Driver ; Description ; Recommendation453#AMD driver versions454938 , 2 ; 12.8 ;4551084, 4 ; 13.1 ;4561124, 2 ; 13.4 ;4571214, 3 ; 13.6 beta ;4581311, 2 ; 13.11 beta-1 ;4591348, 5 ; 13.12 ;4601445, 5 ; 14.4 (Mantle) ;4611526, 3 ; 14.6 beta (Mantle) ;4621573, 4 ; 14.9 (Mantle) ; VGL S4631642, 5 ; 14.12 (Omega) ; VGL S4641702, 3 ; 15.5 beta ; T4651729, 3 ; 15.5 ;4661800, 5 ; 15.7 ; VG* R4671800, 8 ; 15.7.1 ; VGW R4681800, 11; 15.9 ; VGL S4691912, 5 ; 15.12 ;470#NVIDIA driver versions471346, 0 ; ; N* R472319, 0 ; ; N* S473#End4740, 0 ; ;475476#Labels477# * -> all OS478# N -> NVIDIA479# G -> GCN480# V -> VLIW4 and VLIW5481# W -> Windows482# L -> Linux483# R -> recommended484# S -> supported485# T -> not recommended: really bad software. I mean "trash".486487# ZTEX specific settings488[List.ZTEX:Devices]489# If you list Serial Numbers (SN) of ZTEX boards here, it will display490# numbers (starting from 1) instead of factory programmed SN's.491# These numbers can be used in --dev command-line option.492#04A36E0000493#04A36D0000494495[ZTEX:descrypt]496# The design has programmable clock. Design tools reported possible497# frequency to be 221 MHz. Tested boards work reliably at 190.498Frequency = 190499500[ZTEX:bcrypt]501# Define typical setting of hashes it's going to process. It allows502# to adjust for best performance.503TargetSetting = 5504# Design tools reported possible frequency to be 141.5 MHz.505# Tested boards work reliably at 150, so that's what we use by default.506Frequency = 150507# For any algorithm it's possible to set frequency on per-board and508# per-FPGA basis, but the lowest frequency will determine performance.509#Frequency_04A36E0FD6 = 142510#Frequency_04A36E0FD6_1 = 143511#Frequency_04A36E0FD6_4 = 144512513[ZTEX:sha512crypt]514#TargetRounds = 5000515# Design tools reported possible frequency to be 215 MHz.516# We never encountered a board where this worked anywhere close517# to such high frequency. Default frequency is set to 160 MHz.518# Some lucky boards might run at some higher frequency.519Frequency = 160520#Config1 = \x00\x00521522[ZTEX:Drupal7]523#TargetRounds = 16384524# Drupal7 uses same bitstream as sha512crypt, see comment regarding525# default frequency in sha512crypt section.526#Frequency = 160527# Some bitstreams accept runtime configuration.528# In sha512crypt/Drupal7, configuration is 2 bytes. That's interpreted529# as a bitmask. By setting any of the lowest 12 bits to 1 it turns off530# the corresponding unit (there are 12 units in the bitstream).531# This turns off units 0 and 1.532#Config1 = \x03\x00533# This turns off all 12 units (resulting in a timeout).534#Config1_04A36E0FD6_0 = \xff\x0f535536[ZTEX:sha256crypt]537# Design tools reported possible frequency is 241 MHz but tested boards538# miss guesses, often fail unless frequency is decreased.539# Tested boards work reliably at 175.540Frequency = 175541#TargetRounds = 500000542543# md5crypt and phpass use same bitstream. Design tools reported544# possible frequency is 202 MHz. Tested boards run OK at 180 MHz.545[ZTEX:md5crypt]546Frequency = 180547548[ZTEX:phpass]549Frequency = 180550#TargetRounds = 2048551552# These formats are disabled from listing or self-test/benchmark unless553# specifically requested. You can use them as long as you add them out with554# the --format option. Or you can delete a line, comment it out, or change555# to 'N' and the format will be enabled again.556[Disabled:Formats]557#formatname = Y558.include '$JOHN/dynamic_disabled.conf'559560[Formats:7z]561# With this enabled, the 7z formats check padding after AES decryption which562# more or less guarantees we don't get any false positives, and also makes563# the formats faster (in some cases a LOT faster). We've had one (1) report564# of getting a false negative having this enabled though, so if you fail to565# crack some archive you may want to disable this and re-try all attacks.566TrustPadding = Y567568# This allows you to list a few words/names that will be used by single mode569# as if they were included in every GECOS field. Use sparingly! Please note570# that the example words are commented out, so the list is empty!571[List.Single:SeedWords]572#Pass573#Secret574#Test575576# This allows you to read extra pot files when loading hashes. Nothing will577# ever be written to these files, they are just read. Any directory in this578# list will be traversed and files in it with an extension of .pot will be579# read. However there will NOT be any recursion down further directory levels.580# Any entries that don't exist will be silently ignored.581[List.Extra:Potfiles]582#somefile.pot583#somedirectory584#$JOHN/my.pot585586[Debug]587# Changing this to Yes will enable legacy-style benchmarks, for comparisons588Benchmarks_1_8 = N589# Changing this to Yes will test salted formats as one/many salts, for debug590BenchmarkMany = N591592[PRINCE]593# Default wordlist file name. Will fall back to standard wordlist if not594# defined.595Wordlist =596597# Markov modes, see ../doc/MARKOV for more information598[Markov:Default]599# Default Markov mode settings600#601# Statsfile cannot be specified on the command line, so602# specifying it here is mandatory603Statsfile = $JOHN/stats604# MkvLvl and MkvMaxLen should also be specified here, as a fallback for605# --markov usage without specifying LEVEL and/or --max-length on the606# command line.607MkvLvl = 200608MkvMaxLen = 12609# MkvMinLvl and MkvMinLen should not be specified at all in [Markov:Default],610# or they should be equal to 0 (which is the default if not specified.611# MkvMinLvl and MkvMinLen can be used in other Markov mode sections612# except [Markov:Default]613; MkvMinLvl = 0614; MkvMinLen = 0615616# A user defined character class is named with a single digit, ie. 0..9. After617# the equal-sign, just list all characters that this class should match. You618# can specify ranges within brackets, much like pre-processor ranges in rules.619# BEWARE of encoding if using non-ASCII characters. If you put UTF-8 characters620# here, it will *not* work! You must use a singlebyte encoding and it should621# be the same here as you intend to use for your dictionary.622# You can however put characters here in \xA3 format (for codepoint 0xA3 - in623# many iso-8859 codepages that would mean a pound sign). This works in ranges624# too. Using \x00 is not supported though - it will not be parsed as null.625#626# This is a couple of example classes:627# ?0 matches (one version of) base64 characters628# ?1 matches hex digits629# ?2 matches the TAB character (never try to use \x00!)630[UserClasses]6310 = [a-zA-Z0-9/.]6321 = [0-9a-fA-F]6332 = \x09634635[Mask]636# When iterating over length, emit a status line after each length is done637MaskLengthIterStatus = Y638639# Default mask for -mask if none is given. This is same as hashcat's default.640DefaultMask = ?1?2?2?2?2?2?2?3?3?3?3?d?d?d?d641642# Default mask for Hybrid mask mode if none is given.643DefaultHybridMask = ?w?d?d?d?d644645# Mask mode have custom placeholders ?1..?9 that look similar to user classes646# but are a different thing. They are merely defaults for the -1..-9 command647# line options. As delivered, they resemble hashcat's defaults.6481 = ?l?d?u6492 = ?l?d6503 = ?l?d*!$@_6514 =6525 =6536 =6547 =6558 =6569 =657658[Subsets]659# When iterating over length, emit a status line after each length is done660LengthIterStatus = Y661662# Min/Max number of unique characters. MaxDiff can't be set larger than 16.663MinDiff = 1664MaxDiff = 7665666# Default charset, either a literal string or a single-digit number pointing667# to one of the sets below. If not defined, all printable ASCII is used.668DefaultCharset =669670# Subsets mode charsets 0-9. These are literal strings. TAB and space671# characters can be used as long as they do not come first or last. The only672# "magic" used here is \U+HHHH or \U+HHHHH for any Unicode character (except673# the very highest private area that has six hex digits). For example, you674# could say \U+1F600 for a "Grinning Face".6750 = 0123456789abcdef6761 = ABCDEF01234567896772 = 0123456789abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿6783 = 0123456789άέήίαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫ !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~6794 = 0123456789абвгдежзийклмнопрстуфхцчшщъыьэюяёЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ№ !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~6805 =6816 =6827 =6838 =6849 =685686[Regen_Salts_UserClasses]687# These are user defined character sets. Their purpose is to allow custom salt688# values to be used within the salt_regen logic. These will be the characters689# to use for this character within the salt. So if we had a salt that was 4690# characters, and 0-9a-m, we can easily do this by 0 = [0-9a-m]. If this is691# used, the regen salt value would be ?0?0?0?0 and salts such as a47m 2kd5692# would be valid.6931 = [1-9]694695# A "no rules" rule for eg. super-fast Single mode (use with --single=none)696[List.Rules:None]697:698699# A "drop all" rule for even faster Single mode (debugging :)700[List.Rules:Drop]701<1'0702703# These are good rules on larger sites where a user ID may already be used,704# so a user simply appends numbers to create his loginID, but then uses the705# login name he wanted as basis for password. Just strip off digits and treat706# the base-word to some manipulation. These rules found from the 2015 A-M707# leak. Only adds 30-50 permutations and only applied to user names that have708# digits contained within them, and cracks quite a few.709# These are currently Jumbo-specific.710[List.Rules:JumboSingle]711/?d @?d >4712/?d @?d M @?A >4 Q713-c /?d @?d >4 M [lc] Q714-c /?d @?d M @?A >4 Q M [lc] Q715@?D Q >4716/?d @?d >3 <* $[0-9] Q717-c /?d @?d >3 <* M [lc] Q $[0-9]718/?d @?d >3 <- Az"12" <+ Q719-c /?d @?d >3 <- M [lc] Q Az"12" <+720/?d @?d >3 Az"123" <+ Q721-c /?d @?d >3 M [lc] Q Az"123" <+722/?d @?d >2 al d723-c /?d @?d >2 al M [lc] Q d724(?a )?d /?d a0 'p Xpz0725)?a (?d /?a a0 'p Xpz0726727# "Single crack" mode rules728[List.Rules:Single]729# Simple rules come first...730:731-s x**732-c (?a c Q733-c l Q734-s-c x** /?u l735# These were not included in crackers I've seen, but are pretty efficient,736# so I include them near the beginning737-<6 >6 '6738-<7 >7 '7 l739-<6 -c >6 '6 /?u l740-<5 >5 '5741742# Wedge the Jumbo-specific addons in here!743.include [List.Rules:JumboSingle]744745# Weird order, eh? Can't do anything about it, the order is based on the746# number of successful cracks...747<* d748r c749-c <* (?a d c750-<5 -c >5 '5 /?u l751-c u Q752-c )?a r l753-[:c] <* !?A \p1[lc] p754-c <* c Q d755-<7 -c >7 '7 /?u756-<4 >4 '4 l757-c <+ (?l c r758-c <+ )?l l Tm759-<3 >3 '3760-<4 -c >4 '4 /?u761-<3 -c >3 '3 /?u l762-c u Q r763<* d M 'l f Q764-c <* l Q d M 'l f Q765# About 50% of single-mode-crackable passwords get cracked by now...766# >2 x12 ... >8 x18767>[2-8] x1\1768>9 \[769# >3 x22 ... >9 x28770>[3-9] x2\p[2-8]771# >4 x32 ... >9 x37772>[4-9] x3\p[2-7]773# >2 x12 /?u l ... >8 x18 /?u l774-c >[2-8] x1\1 /?u l775-c >9 \[ /?u l776# >3 x22 /?u l ... >9 x28 /?u l777-c >[3-9] x2\p[2-8] /?u l778# >4 x32 /?u l ... >9 x37 /?u l779-c >[4-9] x3\p[2-7] /?u l780# Now to the suffix stuff...781<* l $[1-9!0a-rt-z"-/:-@\[-`{-~]782-c <* (?a c $[1-9!0a-rt-z"-/:-@\[-`{-~]783-[:c] <* !?A (?\p1[za] \p1[lc] $s M 'l p Q X0z0 'l $s784-[:c] <* /?A (?\p1[za] \p1[lc] $s785<* l r $[1-9!]786-c <* /?a u $[1-9!]787-[:c] <- (?\p1[za] \p1[lc] Az"'s"788-[:c] <- (?\p1[za] \p1[lc] Az"!!"789-[:c] (?\p1[za] \p1[lc] $! <- Az"!!"790# Removing vowels...791-[:c] /?v @?v >2 (?\p1[za] \p1[lc]792/?v @?v >2 <* d793# crack -> cracked, crack -> cracking794<* l [PI]795-c <* l [PI] (?a c796# mary -> marie797-[:c] <* (?\p1[za] \p1[lc] )y omi $e798# marie -> mary799-[:c] (?\p1[za] \p1[lc] )e \] <+ )i val1 oay800# The following are some 3l33t rules801-[:c] l /[aelos] s\0\p[4310$] (?\p1[za] \p1[:c]802-[:c] l /a /[elos] sa4 s\0\p[310$] (?\p1[za] \p1[:c]803-[:c] l /e /[los] se3 s\0\p[10$] (?\p1[za] \p1[:c]804-[:c] l /l /[os] sl1 s\0\p[0$] (?\p1[za] \p1[:c]805-[:c] l /o /s so0 ss$ (?\p1[za] \p1[:c]806-[:c] l /a /e /[los] sa4 se3 s\0\p[10$] (?\p1[za] \p1[:c]807-[:c] l /a /l /[os] sa4 sl1 s\0\p[0$] (?\p1[za] \p1[:c]808-[:c] l /a /o /s sa4 so0 ss$ (?\p1[za] \p1[:c]809-[:c] l /e /l /[os] se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]810-[:c] l /[el] /o /s s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]811-[:c] l /a /e /l /[os] sa4 se3 sl1 s\0\p[0$] (?\p1[za] \p1[:c]812-[:c] l /a /[el] /o /s sa4 s\0\p[31] so0 ss$ (?\p1[za] \p1[:c]813-[:c] l /e /l /o /s se3 sl1 so0 ss$ (?\p1[za] \p1[:c]814-[:c] l /a /e /l /o /s sa4 se3 sl1 so0 ss$ (?\p1[za] \p1[:c]815# Now to the prefix stuff...816l ^[1a-z2-90]817-c l Q ^[A-Z]818^[A-Z]819l ^["-/:-@\[-`{-~]820-[:c] <9 (?a \p1[lc] A0"[tT]he"821-[:c] <9 (?a \p1[lc] A0"[aA]my"822-[:c] <9 (?a \p1[lc] A0"[mdMD]r"823-[:c] <9 (?a \p1[lc] A0"[mdMD]r."824-[:c] <9 (?a \p1[lc] A0"__"825<- !?A l p ^[240-9]826# Some word pair rules...827# johnsmith -> JohnSmith, johnSmith828-p-c (?a 2 (?a c 1 [cl]829# JohnSmith -> john smith, john_smith, john-smith830-p 1 <- $[ _\-] + l831# JohnSmith -> John smith, John_smith, John-smith832-p-c 1 <- (?a c $[ _\-] 2 l833# JohnSmith -> john Smith, john_Smith, john-Smith834-p-c 1 <- l $[ _\-] 2 (?a c835# johnsmith -> John Smith, John_Smith, John-Smith836-p-c 1 <- (?a c $[ _\-] 2 (?a c837# Applying different simple rules to each of the two words838-p-[c:] 1 \p1[ur] 2 l839-p-c 2 (?a c 1 [ur]840-p-[c:] 1 l 2 \p1[ur]841-p-c 1 (?a c 2 [ur]842# jsmith -> smithj, etc...843-[:c] (?a \p1[lc] [{}]844-[:c] (?a \p1[lc] [{}] \0845# Toggle case...846-c <+ )?u l Tm847-c T0 Q M c Q l Q u Q C Q X0z0 'l848-c T[1-9A-E] Q M l Tm Q C Q u Q l Q c Q X0z0 'l849-c l Q T[1-9A-E] Q M T\0 Q l Tm Q C Q u Q X0z0 'l850-c >2 <G %2?a [lu] T0 M T2 T4 T6 T8 TA TC TE Q M l Tm Q X0z0 'l851-c >2 /?l /?u t Q M c Q C Q l Tm Q X0z0 'l852# Deleting chars...853>[2-8] D\p[1-7]854>[8-9A-E] D\1855-c /?u >[2-8] D\p[1-7] l856-c /?u >[8-9A-E] D\1 l857=1?a \[ M c Q858-c (?a >[1-9A-E] D\1 c859# Inserting a dot...860-[:c] >3 (?a \p1[lc] i[12].861# More suffix stuff...862<- l Az"[190][0-9]"863-c <- (?a c Az"[190][0-9]"864<- l Az"[782][0-9]"865-c <- (?a c Az"[782][0-9]"866<* l $[A-Z]867-c <* (?a c $[A-Z]868# cracking -> CRACKiNG869-c u /I sIi870# Crack96 -> cRACK96871%2?a C Q872# Crack96 -> cRACK(^873/?A S Q874# Crack96 -> CRaCK96875-c /?v V Q876# Really weird charset conversions, like "england" -> "rmh;smf"877:[RL] Q878l Q [RL]879-c (?a c Q [RL]880:[RL] \0 Q881# Both prefixing and suffixing...882<- l ^[1!@#$%^&*\-=_+.?|:'"] $\1883<- l ^[({[<] $\p[)}\]>]884# The rest of two-digit suffix stuff, less common numbers...885<- l Az"[63-5][0-9]"886-c <- (?a c Az"[63-5][0-9]"887# Some multi-digit numbers...888-[:c] (?a \p1[lc] Az"007" <+889-[:c] (?a \p1[lc] Az"123" <+890-[:c] (?a \p1[lc] Az"[0-9]\0\0" <+891-[:c] (?a \p1[lc] Az"1234" <+892-[:c] (?a \p1[lc] Az"[0-9]\0\0\0" <+893-[:c] (?a \p1[lc] Az"12345" <+894-[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0" <+895-[:c] (?a \p1[lc] Az"123456" <+896-[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0\0" <+897# Some [birth] years...898l Az"19[7-96-0]" <+ >-899l Az"20[012]" <+ >-900l Az"19[7-9][0-9]" <+901l Az"20[012][0-9]" <+902l Az"19[6-0][9-0]" <+903904[List.Rules:Extra]905# Insert/overstrike some characters...906!?A >[1-6] l i\0[a-z]907!?A l o0[a-z]908!?A >[1-7] l o\0[a-z]909# Toggle case everywhere (up to length 8), assuming that certain case910# combinations were already tried.911-c T1 Q M T0 Q912-c T2 Q M T[z0] T[z1] Q913-c T3 Q M T[z0] T[z1] T[z2] Q914-c T4 Q M T[z0] T[z1] T[z2] T[z3] Q915-c T5 Q M T[z0] T[z1] T[z2] T[z3] T[z4] Q916-c T6 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] Q917-c T7 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] T[z6] Q918# Very slow stuff...919l Az"[1-90][0-9][0-9]" <+920-c (?a c Az"[1-90][0-9][0-9]" <+921<[\-9] l A\p[z0]"[a-z][a-z]"922<- l ^[a-z] $[a-z]923924# Wordlist mode rules925[List.Rules:Wordlist]926# Try words as they are927:928# Lowercase every pure alphanumeric word929-c >3 !?X l Q930# Capitalize every pure alphanumeric word931-c (?a >2 !?X c Q932# Lowercase and pluralize pure alphabetic words933<* >2 !?A l p934# Lowercase pure alphabetic words and append '1'935<* >2 !?A l $1936# Capitalize pure alphabetic words and append '1'937-c <* >2 !?A c $1938# Duplicate reasonably short pure alphabetic words (fred -> fredfred)939<7 >1 !?A l d940# Lowercase and reverse pure alphabetic words941>3 !?A l M r Q942# Prefix pure alphabetic words with '1'943>2 !?A l ^1944# Uppercase pure alphanumeric words945-c >2 !?X u Q M c Q u946# Lowercase pure alphabetic words and append a digit or simple punctuation947<* >2 !?A l $[2!37954860.?]948# Words containing punctuation, which is then squeezed out, lowercase949/?p @?p >3 l950# Words with vowels removed, lowercase951/?v @?v >3 l952# Words containing whitespace, which is then squeezed out, lowercase953/?w @?w >3 l954# Capitalize and duplicate short pure alphabetic words (fred -> FredFred)955-c <7 >1 !?A c d956# Capitalize and reverse pure alphabetic words (fred -> derF)957-c <+ >2 !?A c r958# Reverse and capitalize pure alphabetic words (fred -> Derf)959-c >2 !?A l M r Q c960# Lowercase and reflect pure alphabetic words (fred -> fredderf)961<7 >1 !?A l d M 'l f Q962# Uppercase the last letter of pure alphabetic words (fred -> freD)963-c <+ >2 !?A l M r Q c r964# Prefix pure alphabetic words with '2' or '4'965>2 !?A l ^[24]966# Capitalize pure alphabetic words and append a digit or simple punctuation967-c <* >2 !?A c $[2!3957468.?0]968# Prefix pure alphabetic words with digits969>2 !?A l ^[379568]970# Capitalize and pluralize pure alphabetic words of reasonable length971-c <* >2 !?A c p972# Lowercase/capitalize pure alphabetic words of reasonable length and convert:973# crack -> cracked, crack -> cracking974-[:c] <* >2 !?A \p1[lc] M [PI] Q975# Try the second half of split passwords976-s x**977-s-c x** M l Q978979# Case toggler for cracking MD4-based NTLM hashes (with the contributed patch)980# given already cracked DES-based LM hashes. Use --rules=NT to use this.981[List.Rules:NT]982:983-c T0Q984-c ->2 a0 T1QT[z0]985-c ->3 a0 T2QT[z0]T[z1]986-c ->4 a0 T3QT[z0]T[z1]T[z2]987-c ->5 a0 T4QT[z0]T[z1]T[z2]T[z3]988-c ->6 a0 T5QT[z0]T[z1]T[z2]T[z3]T[z4]989-c ->7 a0 T6QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]990-c ->8 a0 T7QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]991-c ->9 a0 T8QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]992-c ->A a0 T9QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]993-c ->B a0 TAQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]994-c ->C a0 TBQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]995-c ->D a0 TCQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]T[zB]996-c ->E a0 TDQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]T[zB]T[zC]997998# Shift toggler, up to length 16999[List.Rules:ShiftToggle]1000:1001W0Q1002->2 a0 W1QW[z0]1003->3 a0 W2QW[z0]W[z1]1004->4 a0 W3QW[z0]W[z1]W[z2]1005->5 a0 W4QW[z0]W[z1]W[z2]W[z3]1006->6 a0 W5QW[z0]W[z1]W[z2]W[z3]W[z4]1007->7 a0 W6QW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]1008->8 a0 W7QW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]1009->9 a0 W8QW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]1010->A a0 W9QW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]1011->B a0 WAQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]1012->C a0 WBQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]1013->D a0 WCQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]W[zB]1014->E a0 WDQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]W[zB]W[zC]1015->F a0 WEQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]W[zB]W[zC]W[zD]1016->G a0 WFQW[z0]W[z1]W[z2]W[z3]W[z4]W[z5]W[z6]W[z7]W[z8]W[z9]W[zA]W[zB]W[zC]W[zD]W[zE]10171018# This ruleset partially overlaps with some Phrase* rulesets below, but it was1019# historically introduced and made part of the jumbo ruleset first, so it stays1020[List.Rules:Multiword]1021-c / Dp l1022-c / Dp c Tp1023-c / Dp / Dp l1024-c / Dp c Tp / Dp Tp1025-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %3[ ] vbpa Tb Q M %2[ ] vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]1026-c %3[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %2[ ] vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]1027-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]1028-c /[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q @?[Zw]1029-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q @?[Zw]1030-c %3[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q @?[Zw]1031-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q @?[Zw]1032-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]1033-c %3[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]1034-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]1035-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %3[ ] vbpa Tb Q @?[Zw]1036-c %2[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %4[ ] vbpa Tb Q @?[Zw]1037-c %3[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %4[ ] vbpa Tb Q @?[Zw]1038-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %3[ ] vbpa Tb Q M %2[ ] vbpa Tb Q @?[Zw]1039-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %2[ ] vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]1040-c %4[ ] T[0z] \p0[Q:] \p0[M:] va01 vbpa Tb Q M %3[ ] vbpa Tb Q M /[ ] vbpa Tb Q @?[Zw]10411042# A special ruleset intended for stacking before other Phrase* rules below,1043# such that you have the option to run its output through "unique" first1044[List.Rules:PhrasePreprocess]1045/[ ] :1046-c /[ ] l Q1047/[ ] @' Q1048-c /[ ] @' Q M l Q10491050# The main optimized Phrase ruleset, almost no duplicates with proper input1051[List.Rules:Phrase]1052# This one rule cracks ~1050 HIBP v7 passwords per million with sequences of1053# 2 to 6 words occurring 2+ times across Project Gutenberg Australia books1054# when our sequence list includes them in both their original case and1055# all-lowercase, as well as both with apostrophes intact and removed (these1056# variations are not implemented in this ruleset not to produce duplicates)1057@?w Q1058# Sorted separator characters: 1_24 -.3785690@,&+*!'$/?:=#~^%;`>"[)<]|({}\1059# (the apostrophe is probably overrated since it also occurs inside words)1060# Each character in 1_24 cracks ~82 to ~61 passwords per million1061s[ ][1_24] Q1062# Leaving the space separators intact cracks ~59 passwords per million1063/[ ]1064# Each character in -.3785690@ cracks ~53 to ~12 passwords per million1065s[ ][\-.3785690@] Q1066# Each character in ,&+*!'$/?:=#~ cracks ~10 to ~1 passwords per million1067s[ ][,&+*!'$/?:=#~] Q10681069# Toggle capitalization of words 1 to 6 individually1070[List.Rules:PhraseCaseOne]1071-c /[ ] T0 Q1072-c /[ ] va01 vapa Ta Q1073-c %2[ ] va01 vapa Ta Q1074-c %3[ ] va01 vapa Ta Q1075-c %4[ ] va01 vapa Ta Q1076-c %5[ ] va01 vapa Ta Q10771078# Move first word to be after last word1079[List.Rules:PhraseWrap]1080/[ ] ^[ ] Xpz0 \[ 'l1081# Other ways to write this rule1082#/[ ] xpz \[ $[ ] X0pz 'l1083#/[ ] 'p ^[ ] va01 vapa Xaz010841085# Used for loopback. This rule will produce candidates "PASSWOR" and "D" for1086# an input of "PASSWORD" (assuming LM, which has halves of length 7).1087[List.Rules:Split]1088:1089-s x**10901091# Some Office <=2003 files have passwords truncated at 151092[List.Rules:OldOffice]1093:1094->F -<F >F 'F10951096# Rules from Hash Runner 20141097[List.Rules:o1]1098# o[0-9A-Z][ -~]1099->\r[1-9A-ZZ] >\p[0-9A-Z] o\0[ -~] Q11001101[List.Rules:o2]1102# o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q1103->[1-9A-F] ->[1-9A-F] >\p1[0-9A-E] >\p2[0-9A-E] o\3[ -~] Q M o\4[ -~] Q11041105[List.Rules:o3]1106# o[0-9][ -~] Q M o[0-9][ -~] Q M o[0-9][ -~] Q1107->[1-9A] ->[1-9A] ->[1-9A] >\p1[0-9] >\p2[0-9] >\p3[0-9] o\4[ -~] Q M o\5[ -~] Q M o\6[ -~] Q11081109[List.Rules:o]1110.include [List.Rules:o1]1111.include [List.Rules:o2]11121113[List.Rules:i1]1114# i[0-9A-Z][ -~]1115->\r[2-9A-ZZZ] >\p1[0-9A-Z] i\0[ -~]11161117[List.Rules:i2]1118# i[0-9A-E][ -~] i[0-9A-E][ -~]1119->[2-9A-G] ->[2-9A-G] >\p1[0-9A-E] >\p2[0-9A-E] i\3[ -~] i\4[ -~]11201121[List.Rules:i3]1122# i[0-9][ -~] i[0-9][ -~] i[0-9][ -~]1123->[4-9A-D] ->[4-9A-D] ->[4-9A-D] >\p1[0-9] >\p2[0-9] >\p3[0-9] i\4[ -~] i\5[ -~] i\6[ -~]11241125[List.Rules:i]1126.include [List.Rules:i1]1127.include [List.Rules:i2]11281129[List.Rules:oi]1130.include [List.Rules:o1]1131.include [List.Rules:i1]1132.include [List.Rules:o2]1133.include [List.Rules:i2]11341135[List.Rules:T9]1136a0 /?D l sa2 sb2 sc2 sd3 se3 sf3 sg4 sh4 si4 sj5 sk5 sl5 sm6 sn6 so6 sp7 sq7 sr7 ss7 st8 su8 sv8 sw9 sx9 sy9 sz9 s?D*1137a0 /?D l sa2 sb2 sc2 sd3 se3 sf3 sg4 sh4 si4 sj5 sk5 sl5 sm6 sn6 so6 sp7 sq7 sr7 ss7 st8 su8 sv8 sw9 sx9 sy9 sz9 /?D s?D#11381139# A few rule sets from hashcat (taken as-is from https://github.com/hashcat/)1140#1141# Note that these are very poorly optimized with our measure, as they lack1142# rule-rejection flags. Also, they don't use the preprocessor so are a lot1143# harder to digest (for a human looking at them that is, for JtR there's1144# virtually no difference).1145#1146[List.Rules:best64]1147!! hashcat logic ON1148.include <rules/best64.rule>1149!! hashcat logic OFF11501151[List.Rules:d3ad0ne]1152!! hashcat logic ON1153.include <rules/d3ad0ne.rule>1154!! hashcat logic OFF11551156[List.Rules:dive]1157!! hashcat logic ON1158.include <rules/dive.rule>1159!! hashcat logic OFF11601161[List.Rules:InsidePro]1162!! hashcat logic ON1163.include <rules/InsidePro-PasswordsPro.rule>1164!! hashcat logic OFF11651166[List.Rules:T0XlC]1167!! hashcat logic ON1168.include <rules/T0XlC.rule>1169.include <rules/T0XlCv1.rule>1170.include <rules/T0XlC-insert_top_100_passwords_1_G.rule>1171!! hashcat logic OFF11721173[List.Rules:rockyou-30000]1174!! hashcat logic ON1175.include <rules/rockyou-30000.rule>1176!! hashcat logic OFF11771178[List.Rules:specific]1179!! hashcat logic ON1180.include <rules/specific.rule>1181!! hashcat logic OFF11821183[List.Rules:hashcat]1184.include [List.Rules:best64]1185.include [List.Rules:d3ad0ne]1186.include [List.Rules:dive]1187.include [List.Rules:InsidePro]1188.include [List.Rules:T0XlC]1189.include [List.Rules:rockyou-30000]1190.include [List.Rules:specific]11911192# These are for phrase wordlists w/ spaces1193[List.Rules:passphrase-rule1]1194.include <rules/passphrase-rule1.rule>11951196[List.Rules:passphrase-rule2]1197.include <rules/passphrase-rule2.rule>11981199# Default Loopback mode rules.1200[List.Rules:Loopback]1201.include [List.Rules:ShiftToggle]1202.include [List.Rules:Split]1203!! hashcat logic ON1204+m1205-m1206!! hashcat logic OFF1207b1 ]12081209# For Single Mode against fast hashes1210[List.Rules:Single-Extra]1211.include [List.Rules:Single]1212.include [List.Rules:Extra]1213.include [List.Rules:OldOffice]12141215# Unicode substitution rules1216.include <unisubst.conf>12171218# For Wordlist mode and very fast hashes1219[List.Rules:Jumbo]1220.include [List.Rules:Single-Extra]1221.include [List.Rules:Wordlist]1222.include [List.Rules:ShiftToggle]1223.include [List.Rules:Multiword]1224.include [List.Rules:best64]1225.include [List.Rules:UnicodeSubstitution]12261227# KoreLogic rules1228.include <korelogic.conf>12291230# Everything, including all KoreLogic and the rest of included hashcat rules.1231# Only for very fast hashes and/or Single mode. Some of these rules are of1232# ridiculous quality and lack optimizations - you have been warned.1233[List.Rules:All]1234.include [List.Rules:Jumbo]1235.include [List.Rules:KoreLogic]1236.include [List.Rules:T9]1237.include [List.Rules:hashcat]12381239# Incremental modes12401241# This is for one-off uses (make your own custom.chr).1242# A charset can now also be named directly from command-line, so no config1243# entry needed: --incremental=whatever.chr1244[Incremental:Custom]1245File = $JOHN/custom.chr1246MinLen = 012471248# The theoretical CharCount is 211, we've got 196.1249[Incremental:UTF8]1250File = $JOHN/utf8.chr1251MinLen = 01252CharCount = 19612531254# This is CP1252, a super-set of ISO-8859-1.1255# The theoretical CharCount is 219, we've got 203.1256[Incremental:Latin1]1257File = $JOHN/latin1.chr1258MinLen = 01259CharCount = 20312601261[Incremental:ASCII]1262File = $JOHN/ascii.chr1263MinLen = 01264MaxLen = 131265CharCount = 9512661267[Incremental:LM_ASCII]1268File = $JOHN/lm_ascii.chr1269MinLen = 01270MaxLen = 71271CharCount = 6912721273# This is CP858 (CP850 + Euro sign, superset of CP437).1274# The theoretical CharCount is 209 minus lowercase, we've got 132.1275[Incremental:LanMan]1276File = $JOHN/lanman.chr1277MinLen = 01278MaxLen = 71279CharCount = 13212801281# This is alnum (upper & lower case) as well as space.1282[Incremental:Alnumspace]1283File = $JOHN/alnumspace.chr1284MinLen = 11285MaxLen = 131286CharCount = 6312871288[Incremental:Alnum]1289File = $JOHN/alnum.chr1290MinLen = 11291MaxLen = 131292CharCount = 6212931294[Incremental:Alpha]1295File = $JOHN/alpha.chr1296MinLen = 11297MaxLen = 131298CharCount = 5212991300[Incremental:LowerNum]1301File = $JOHN/lowernum.chr1302MinLen = 11303MaxLen = 131304CharCount = 3613051306[Incremental:UpperNum]1307File = $JOHN/uppernum.chr1308MinLen = 11309MaxLen = 131310CharCount = 3613111312[Incremental:LowerSpace]1313File = $JOHN/lowerspace.chr1314MinLen = 11315MaxLen = 131316CharCount = 2713171318[Incremental:Lower]1319File = $JOHN/lower.chr1320MinLen = 11321MaxLen = 131322CharCount = 2613231324[Incremental:Upper]1325File = $JOHN/upper.chr1326MinLen = 11327MaxLen = 131328CharCount = 2613291330[Incremental:Digits]1331File = $JOHN/digits.chr1332MinLen = 11333MaxLen = 201334CharCount = 1013351336# Some pre-defined word filters as used to generate the supplied .chr files1337[List.External:Filter_ASCII]1338void filter()1339{1340int i, c;13411342i = 0;1343while (c = word[i++])1344if (c < 0x20 || c > 0x7e || i > 13) {1345word = 0; return;1346}1347}13481349[List.External:Filter_LanMan]1350void filter()1351{1352int i, c;13531354i = 0;1355while (c = word[i]) {1356if (i >= 14) { // of up to 14 characters long1357word = 0; return;1358}1359if (c >= 'a' && c <= 'z') // Convert to uppercase1360word[i] &= 0xDF;1361i++;1362}13631364word[7] = 0; // Truncate at 7 characters1365}13661367[List.External:Filter_LM_ASCII]1368void filter()1369{1370int i, c;13711372i = 0;1373while (c = word[i]) {1374if (c < 0x20 || c > 0x7e || // Require ASCII-only1375i >= 14) { // of up to 14 characters long1376word = 0; return;1377}1378if (c >= 'a' && c <= 'z') // Convert to uppercase1379word[i] &= 0xDF;1380i++;1381}13821383word[7] = 0; // Truncate at 7 characters1384}13851386[List.External:Filter_Alnumspace]1387void filter()1388{1389int i, c;13901391i = 0;1392while (c = word[i++])1393if (c != ' ' && (((c < '0' || c > '9') &&1394((c &= 0xDF) < 'A' || c > 'Z'))) || i > 13) {1395word = 0; return;1396}1397}13981399[List.External:Filter_Alnum]1400void filter()1401{1402int i, c;14031404i = 0;1405while (c = word[i++])1406if (((c < '0' || c > '9') && ((c &= 0xDF) < 'A' || c > 'Z')) ||1407i > 13) {1408word = 0; return;1409}1410}14111412[List.External:Filter_Alpha]1413void filter()1414{1415int i, c;14161417i = 0;1418while (c = word[i++])1419if ((c &= 0xDF) < 'A' || c > 'Z' || i > 13) {1420word = 0; return;1421}1422}14231424[List.External:Filter_LowerNum]1425void filter()1426{1427int i, c;14281429i = 0;1430while (c = word[i++])1431if (((c < 'a' || c > 'z') && (c < '0' || c > '9')) || i > 13) {1432word = 0; return;1433}1434}14351436[List.External:Filter_UpperNum]1437void filter()1438{1439int i, c;14401441i = 0;1442while (c = word[i++])1443if (((c < 'A' || c > 'Z') && (c < '0' || c > '9')) || i > 13) {1444word = 0; return;1445}1446}14471448[List.External:Filter_LowerSpace]1449void filter()1450{1451int i, c;14521453i = 0;1454while (c = word[i++])1455if (((c < 'a' || c > 'z') && c != ' ') || i > 13) {1456word = 0; return;1457}1458}14591460[List.External:Filter_Lower]1461void filter()1462{1463int i, c;14641465i = 0;1466while (c = word[i++])1467if (c < 'a' || c > 'z' || i > 13) {1468word = 0; return;1469}1470}14711472[List.External:Filter_Upper]1473void filter()1474{1475int i, c;14761477i = 0;1478while (c = word[i++])1479if (c < 'A' || c > 'Z' || i > 13) {1480word = 0; return;1481}1482}14831484[List.External:Filter_Digits]1485void filter()1486{1487int i, c;14881489i = 0;1490while (c = word[i++])1491if (c < '0' || c > '9' || i > 20) {1492word = 0; return;1493}1494}14951496[List.External:Filter_No_Cap_or_Symbols]1497void filter()1498{1499int i, c;15001501i = 0;1502while (c = word[i++])1503if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) {1504return;1505}1506word = 0; return;1507}150815091510# Reject words that are illegal UTF-81511# We obviously let pure ASCII through too1512[List.External:Filter_UTF8]1513void filter()1514{1515int s, a, p;15161517p = 0;1518while (s = word[p++] & 0xff) {1519if (s > 0x7f) {1520if (s < 0xc2 || s > 0xf7) { // illegal single-byte1521word = 0; return;1522}1523// two-byte c2..df1524a = word[p++] & 0xff;1525if (a < 0x80 || a > 0xbf) {1526word = 0; return;1527}1528if (s > 0xdf) { // three-byte e0..ef1529if (s == 0xe0 && a < 0xa0) {1530word = 0; return;1531}1532if (s == 0xed && a > 0x9f) {1533word = 0; return;1534}1535if (s == 0xf0 && a < 0x90) {1536word = 0; return;1537}1538if (s == 0xf4 && a > 0x8f) {1539word = 0; return;1540}1541a = word[p++] & 0xff;1542if (a < 0x80 || a > 0xbf) {1543word = 0; return;1544}1545if (s > 0xef) { // four-byte f0..f71546a = word[p++] & 0xff;1547if (a < 0x80 || a > 0xbf) {1548word = 0; return;1549}1550}1551}1552}1553}1554}15551556# Reject words that are LEGAL UTF-8 (also rejects pure ASCII)1557[List.External:Filter_non-UTF8]1558void filter()1559{1560int s, a, p;15611562p = 0;1563while (s = word[p++] & 0xff) {1564if (s > 0x7f) {1565if (s < 0xc2 || s > 0xf7) { // illegal single-byte1566return;1567}1568// two-byte c2..df1569a = word[p++] & 0xff;1570if (a < 0x80 || a > 0xbf) {1571return;1572}1573if (s > 0xdf) { // three-byte e0..ef1574if (s == 0xe0 && a < 0xa0) {1575return;1576}1577if (s == 0xed && a > 0x9f) {1578return;1579}1580if (s == 0xf0 && a < 0x90) {1581return;1582}1583if (s == 0xf4 && a > 0x8f) {1584return;1585}1586a = word[p++] & 0xff;1587if (a < 0x80 || a > 0xbf) {1588return;1589}1590if (s > 0xef) { // four-byte f0..f71591a = word[p++] & 0xff;1592if (a < 0x80 || a > 0xbf) {1593return;1594}1595}1596}1597}1598}1599word = 0;1600}16011602# Skip candidate passwords that contain the same character more than once1603[List.External:Filter_NoRepeats]1604int seen[0x100], now;16051606void init()1607{1608now = 1;1609}16101611void filter()1612{1613int i, c;16141615if (!--now) {1616i = 0;1617while (i < 0x100)1618seen[i++] = 0;1619now = 1000000000;1620}16211622i = 0;1623while (c = word[i++]) {1624if (seen[c] == now) {1625word = 0; return;1626}1627seen[c] = now;1628}1629}16301631# Keep only candidate passwords that contain the same character more than once1632[List.External:Filter_Repeats]1633int seen[0x100], now;16341635void init()1636{1637now = 1;1638}16391640void filter()1641{1642int i, c;16431644if (!--now) {1645i = 0;1646while (i < 0x100)1647seen[i++] = 0;1648now = 1000000000;1649}16501651i = 0;1652while (c = word[i++]) {1653if (seen[c] == now)1654return;1655seen[c] = now;1656}16571658word = 0;1659}16601661# A simple cracker for LM hashes1662[List.External:LanMan]1663int length; // Current length1664int maxlength;16651666void init()1667{1668if (req_minlen)1669length = req_minlen;1670else1671length = 1;1672if (req_maxlen)1673maxlength = req_maxlen;1674else // the format's limit1675maxlength = cipher_limit;1676word[0] = 'A' - 1; // Start with "A"1677word[length] = 0;1678}16791680void generate()1681{1682int i;16831684i = length - 1; // Start from the last character1685while (++word[i] > 'Z') // Try to increase it1686if (i) // Overflow here, any more positions?1687word[i--] = 'A'; // Yes, move to the left, and repeat1688else // No16891690if (length < maxlength) {1691word[i = ++length] = 0; // Switch to the next length1692while (i--)1693word[i] = 'A';1694return;1695} else {1696word = 0; return; // We're done1697}1698}16991700void restore()1701{1702length = 0; // Calculate the length1703while (word[length]) length++;1704}17051706# Simple and well-commented, yet useful external mode example1707# NOTE, this has now been 'split' up into a base extern, 'base', and then1708# multiple External:double functions. It still has same code as original1709# double, but now can be easily expanded.1710[List.External_base:Double]1711/*1712* This cracking mode tries all the possible duplicated lowercase alphabetic1713* "words" of up to 8 characters long. Since word halves are the same, it1714* only has to try about 500,000 words.1715*/17161717/* Global variables: current length and word */1718/* make this 'long' enough for other externs that include this one */1719/* (up to 125 bytes long) */17201721int length, current[126], max;17221723/* this new 'type' variable, is used to tell double what character set to1724* use. It can use the original (alpha). If type is 0 (i.e. unset), then1725* a-z (alpha) character set is used. If type is '0' (a zero ascii byte)1726* then alnum charset is used, a-z0-9. If type is a space char, then all1727* charset is used [space - tilde] or [ -~]. This required setting the1728* type var in the init() of alnum or all doubles (it can be left unset1729* in the alpha versions). It also requires some if logic in generate.1730* other than that, it works the same, with almost no performance hit */1731int type;17321733/* Generates a new word */1734void generate()1735{1736int i;17371738/* Export last generated word, duplicating it at the same time; here "word"1739* is a pre-defined external variable. */1740word[(i = length) << 1] = 0;1741while (i--) word[length + i] = word[i] = current[i];17421743/* Generate a new word */1744i = length - 1; // Start from the last character1745if (type == 0) {1746/* alpha */1747while (++current[i] > 'z') // Try to increase it1748if (i) // Overflow here, any more positions?1749current[i--] = 'a'; // Yes, move to the left, and repeat1750else { // No1751current = 0; // Request a length switch1752break; // Break out of the loop1753}1754} else if (type == '0') {1755/* alnum */1756if (current[i] == 'z') current[i] = '0'-1;1757while (++current[i] == '9') { // Try to increase it1758if (i) // Overflow here, any more positions?1759current[i--] = 'a'; // Yes, move to the left, and repeat1760else { // No1761current = 0; // Request a length switch1762break; // Break out of the loop1763}1764if (current[i] == 'z') current[i] = '0'-1;1765}1766} else if (type == ' ') {1767/* all */1768while (++current[i] > '~') { // Try to increase it1769if (i) // Overflow here, any more positions?1770current[i--] = ' '; // Yes, move to the left, and repeat1771else { // No1772current = 0; // Request a length switch1773break; // Break out of the loop1774}1775}1776}1777/* else ????? wtf?? */17781779/* Switch to the next length, unless we were generating 8 character long1780* words already. */1781if (!current && length < max) {1782i = ++length;1783if (type == 0 || type == '0')1784while (i--) current[i] = 'a';1785else if (type == ' ')1786while (i--) current[i] = ' ';1787}1788}17891790/* Called when restoring an interrupted session */1791void restore()1792{1793int i;17941795/* Import the word back */1796i = 0;1797while (current[i] = word[i]) i++;17981799/* ...and calculate the half-word length */1800length = i >> 1;1801}18021803[List.External:Double]1804.include [List.External_base:Double]18051806/* Called at startup to initialize the global variables */1807void init()1808{1809int i;18101811if (req_minlen)1812i = length = (req_minlen + 1) / 2;1813else1814i = length = 2; // Start with 4 character long words1815while (i--) current[i] = 'a'; // Set our half-word to "aa"1816if (req_maxlen)1817max = (req_maxlen + 1) / 2;1818else if (length > 4)1819max = length;1820else1821max = 4;1822}18231824[List.External:Double_alnum]1825.include [List.External_base:Double]18261827/* Called at startup to initialize the global variables */1828void init()1829{1830int i;18311832if (req_minlen)1833i = length = (req_minlen + 1) / 2;1834else1835i = length = 2; // Start with 4 character long words1836while (i--) current[i] = 'a'; // Set our half-word to "aa"1837if (req_maxlen)1838max = (req_maxlen + 1) / 2;1839else if (length > 4)1840max = length;1841else1842max = 4;18431844type = '0';1845}18461847[List.External:Double_all]1848.include [List.External_base:Double]1849void init()1850{1851int i;18521853if (req_minlen)1854i = length = (req_minlen + 1) / 2;1855else1856i = length = 2; // Start with 4 character long words1857while (i--) current[i] = ' '; // Set our half-word to " "1858if (req_maxlen)1859max = (req_maxlen + 1) / 2;1860else if (length > 4)1861max = length;1862else1863max = 4;18641865type = ' ';1866}18671868# Try strings of repeated characters.1869#1870# This is the code which is common for all [List.External:Repeats*]1871# sections which include this External_base section.1872# The generate() function will limit the maximum length of generated1873# candidates to either the format's limit (maximum password length)1874# or to the limit specified with --stdout=LENGTH (Default: 125),1875# thus avoiding duplicate candidates for formats with limited maximum1876# passwortd length.1877# The comparison of the current length and the limit is only done1878# after switching to a new length.1879# So, if the minimum length specified already exceeds this limit,1880# then all the candidates for the minimum length will be generated1881# nevertheless.1882[List.External_base:Repeats]1883int minlength, maxlength, minc, maxc, length, c;18841885void generate()1886{1887int i;18881889i = 0;1890while (i < length)1891word[i++] = c;1892word[i] = 0;18931894if (c++ < maxc)1895return;18961897c = minc;18981899if (++length > maxlength)1900c = 0; // Will NUL out the next "word" and thus terminate1901}19021903# Try strings of repeated characters (range: space - 0xff).1904[List.External:Repeats]1905.include [List.External_base:Repeats]1906void init()1907{1908if (req_minlen)1909minlength = req_minlen;1910else1911minlength = 1;1912if (req_maxlen)1913maxlength = req_maxlen;1914else1915maxlength = cipher_limit; // the format's limit1916minc = 0x20;1917maxc = 0xff;19181919length = minlength; c = minc;1920}19211922# Try strings of repeated digits (range: '0' - '9').1923[List.External:Repeats_digits]1924.include [List.External_base:Repeats]1925void init()1926{1927if (req_minlen)1928minlength = req_minlen;1929else1930minlength = 1;1931if (req_maxlen)1932maxlength = req_maxlen;1933else1934maxlength = cipher_limit; // the format's limit1935minc = '0';1936maxc = '9';19371938length = minlength; c = minc;1939}19401941# Try strings of repeated lowercase letters (range: 'a' - 'z').1942[List.External:Repeats_lowercase]1943.include [List.External_base:Repeats]1944void init()1945{1946if (req_minlen)1947minlength = req_minlen;1948else1949minlength = 1;1950if (req_maxlen)1951maxlength = req_maxlen;1952else1953maxlength = cipher_limit; // the format's limit1954minc = 'a';1955maxc = 'z';19561957length = minlength; c = minc;1958}19591960# Try strings of repeated printable ASCII characters1961# (range: ' ' - '~').1962[List.External:Repeats_printable_ASCII]1963.include [List.External_base:Repeats]1964void init()1965{1966if (req_minlen)1967minlength = req_minlen;1968else1969minlength = 1;1970if (req_maxlen)1971maxlength = req_maxlen;1972else1973maxlength = cipher_limit; // the format's limit1974minc = ' ';1975maxc = '~';19761977length = minlength; c = minc;1978}19791980# Try character sequences ("0123456", "acegikmoqs", "ZYXWVU", etc.).1981#1982# The generate() function will limit the maximum length of generated1983# candidates to either the format's limit (maximum password length)1984# or to the limit specified with --stdout=LENGTH (Default: 125),1985# thus avoiding duplicate candidates for formats with limited maximum1986# passwortd length.1987# The comparison of the current length and the limit is only done1988# after switching to a new length.1989# So, if the minimum length specified already exceeds this limit,1990# then all the candidates for the minimum length will be generated1991# nevertheless.1992# External modes reusing this External_base mode should only need to1993# adjust the init() function.1994# In the init() function, a minimum length which is > 1 should be1995# specified.1996# Otherwise, the generated candidates will not depend on the increment1997# specified.1998# For length = 1, the candidates will be the same as for external mode1999# Repeats with length 1.2000# Actually, Repeats is a special case of Sequence, using increment = 0.2001# External modes reusing this External_base mode should also make sure2002# that the number of different characters (specified as a range from "from"2003# to "to") is not smaller than the minimum length ("minlength"),2004# if the start increment "inc" is 1.2005# For a start increment > 1, the number of different characters in the2006# range "from" - "to" must be greater than or equal to2007# (1 + ("minlength" - 1) * "inc").2008# Otherwise you might get unexpected results.2009# The range of characters to be used for the sequences needs to be2010# specified by adjusting the "from" and "to" variables.2011# To generate sequences which decrement characters ("987654"),2012# "from" must be > "to".2013# Otherwise, the generated sequences will increment characters ("abcdef").2014#2015# Variables to be used and the generate() function are common2016# for all sections which include this External_base section.2017[List.External_base:Sequence]2018/*2019* See the [List.External:Sequence_0-9] section to learn more about2020* the meaning of these variables which can be adjusted to define2021* new external modes based on an existing one:2022*/2023int minlength, from, to, maxlength, inc, direction;20242025/*2026* The value of these variables shouldn't be changed when copying2027* an existing external mode:2028*/2029int length, first;20302031void generate()2032{2033int i;20342035i = 0;20362037while (i < length) {2038word[i] = first + (i * inc * direction);2039++i;2040}2041word[i] = 0;20422043// start the next sequence of the same length2044// with the next character2045first = first + direction;20462047// But check that a sequence of the current length2048// is still possible (without leaving the range of2049// characters allowed2050if ((direction > 0 && first + (length - 1) * inc > to) ||2051(direction < 0 && first - (length - 1) * inc < to)) {2052// No more sequence is possible. Reset start character2053first = from;2054// Now try the next length.2055// But just in case an individual External mode reusing2056// this External_base mode did specify a maxlength2057// which is larger than the one supported by the format2058// or by --stdout=LENGTH, make sure no more candidates2059// are generated.2060// Checking this just once per length per increment2061// doen't really hurt performance.2062if (maxlength > cipher_limit)2063maxlength = cipher_limit;20642065// For a similar reason, the maximum length of a2066// sequence is limited by the number of different2067// characters and by the increment.2068// The larger the increment, the smaller2069// the maximum possible length for a given2070// character range.2071while (inc * (maxlength - 1) > direction * (to - from))2072--maxlength;20732074if (++length > maxlength) {2075// The maximum length for this increment has been reached.2076// Restart at minimum length with the next possible2077// increment2078++inc;2079// Unfortunately, we have to check again2080// if the maximum length needs to be reduced2081// for the new increment2082while (inc * (maxlength - 1) > direction * (to - from))2083--maxlength;20842085length = minlength;2086}2087if (maxlength < minlength)2088// With the current increment, we can't even generate2089// sequences of the minimum required length.2090// So we need to stop here.2091// This will make sure that no more candidiates2092// will be generated:2093first = 0;2094}2095}20962097# Try sequences of digits (range: '0' - '9').2098#2099# Aditional comments can be found in the2100# section [List.External_base:Sequence]2101#2102# This external mode is thoroughly commented,2103# to make it easier to copy and adjust it as needed.2104[List.External:Sequence_0-9]2105.include [List.External_base:Sequence]2106void init()2107{2108// Adjust the following 4 variables if you want to define2109// a different external mode.21102111// This is the start character for the generated sequence2112// if "from" is smaller than "to", the increment from2113// first to second character ... will be positive ("0123456789").2114// Otherwise, it will be negative ("987654321").2115from = '0';2116to = '9';21172118// minimum length of the sequence2119// make sure it is not larger than the number of different characters2120// in the range between "from" and "to" specified above2121minlength = 2;21222123// start increment for generating the sequence, usually 12124// if it is larger than 1, you need even more characters2125// in the range between "from" and "to"2126// Don't specify a negative value here.2127// If you want to generate sequences like "zyxwvu" or "86420",2128// adjust "from" and "to" so that "from" is larger than "to".2129// (A start increment of 0 is also possible, in that case the first2130// sequences will be candidates which just repeat the same character.)2131inc = 1;21322133// For copied external modes, no further changes should be required2134// in the statements following this comment21352136length = minlength;2137first = from;21382139if (from <= to) {2140maxlength = to - from + 1;2141direction = 1;2142} else {2143// We have to create sequences which decrement the previous character2144maxlength = from - to + 1;2145direction = -1;2146}2147}21482149# Try sequence of lower case letters (range: 'a' - 'z').2150# This external mode is not very well documented.2151# Refer to [List.External:Sequence_0-9] for more detailed information.2152[List.External:Sequence_a-z]2153.include [List.External_base:Sequence]2154void init()2155{2156from = 'a';2157to = 'z';2158minlength = 2;2159inc = 1;21602161length = minlength;2162first = from;21632164if (from <= to) {2165maxlength = to - from + 1;2166direction = 1;2167} else {2168maxlength = from - to + 1;2169direction = -1;2170}2171}21722173# Try sequence of lower case letters (range: 'a' - 'z'), but reversed2174# ("zxywvu").2175# This external mode is not very well documented.2176# Refer to [List.External:Sequence_0-9] for more detailed information.2177[List.External:Sequence_z-a]2178.include [List.External_base:Sequence]2179void init()2180{2181from = 'z';2182to = 'a';2183minlength = 2;2184inc = 1;21852186length = minlength;2187first = from;21882189if (from <= to) {2190maxlength = to - from + 1;2191direction = 1;2192} else {2193maxlength = from - to + 1;2194direction = -1;2195}2196}21972198# Try sequence of printable ASCII characters (range: ' ' - '~').2199# This external mode is not very well documented.2200# Refer to [List.External:Sequence_0-9] for more detailed information.2201[List.External:Sequence_printable_ascii]2202.include [List.External_base:Sequence]2203void init()2204{2205from = ' ';2206to = '~';2207minlength = 2;2208inc = 1;22092210length = minlength;2211first = from;22122213if (from <= to) {2214maxlength = to - from + 1;2215direction = 1;2216} else {2217maxlength = from - to + 1;2218direction = -1;2219}2220}22212222# Try sequence of printable ASCII characters (range: ' ' - '~'),2223# but decrementing characters ("fedcba") instead of incrementing.2224# This external mode is not very well documented.2225# Refer to [List.External:Sequence_0-9] for more detailed information.2226[List.External:Sequence_reversed_ascii]2227.include [List.External_base:Sequence]2228void init()2229{2230from = '~';2231to = ' ';2232minlength = 2;2233inc = 1;22342235length = minlength;2236first = from;22372238if (from <= to) {2239maxlength = to - from + 1;2240direction = 1;2241} else {2242maxlength = from - to + 1;2243direction = -1;2244}2245}22462247# Try sequence of characters (range: space - 0xff).2248# This external mode is not very well documented.2249# Refer to [List.External:Sequence_0-9] for more detailed information.2250[List.External:Sequence]2251.include [List.External_base:Sequence]2252void init()2253{2254from = ' ';2255to = 0xff;2256minlength = 2;2257inc = 1;22582259length = minlength;2260first = from;22612262if (from <= to) {2263maxlength = to - from + 1;2264direction = 1;2265} else {2266maxlength = from - to + 1;2267direction = -1;2268}2269}227022712272# Generate candidate passwords from many small subsets of characters from a2273# much larger full character set. This will test for passwords containing too2274# few different characters. As currently implemented, this code will produce2275# some duplicates, although their number is relatively small when the maximum2276# number of different characters (the maxdiff setting) is significantly lower2277# than the maximum length (the maxlength setting). Nevertheless, you may want2278# to pass the resulting candidate passwords through "unique" if you intend to2279# test them against hashes that are salted and/or of a slow to compute type.2280#2281# Note that we now have a full blown cracking mode --subsets that is way faster2282# than this code and never produce a duplicate. See doc/SUBSETS2283[List.External:Subsets]2284int minlength; // Minimum password length to try2285int maxlength; // Maximum password length to try2286int startdiff; // Initial number of characters in a subset to try2287int maxdiff; // Maximum number of characters in a subset to try2288int last; // Last character position, zero-based2289int lastid; // Character index in the last position2290int id[0x7f]; // Current character indices for other positions2291int subset[0x100], c0; // Current subset2292int subcount; // Number of characters in the current subset2293int subid[0x100]; // Indices into charset[] of characters in subset[]2294int charset[0x100]; // Full character set2295int charcount; // Number of characters in the full charset22962297void init()2298{2299int i, c;23002301// Minimum password length to try, must be at least 12302if (req_minlen)2303minlength = req_minlen;2304else2305minlength = 1;23062307// Maximum password length to try, must be at least same as minlength2308// This external mode's default maximum length can be adjusted2309// using --max-length= on the command line2310if (req_maxlen)2311maxlength = req_maxlen;2312else2313maxlength = 8;23142315// "cipher_limit" is the variable which contains the format's2316// maximum password length2317if (maxlength > cipher_limit)2318maxlength = cipher_limit;23192320startdiff = 1; // Initial number of different characters to try2321maxdiff = 3; // Maximum number of different characters to try23222323/* This defines the character set */2324i = 0;2325c = 0x20;2326while (c <= 0x7e)2327charset[i++] = c++;23282329if (maxdiff > (charcount = i))2330maxdiff = i;2331if (maxdiff > maxlength)2332maxdiff = maxlength;23332334/*2335* Initialize the variables such that generate() gets to its "next subset"2336* code, which will initialize everything for real.2337*/2338subcount = (i = startdiff) - 1;2339while (i--)2340subid[i] = charcount;2341subset[0] = c0 = 0;2342last = maxlength - 1;2343lastid = -1;2344}23452346void generate()2347{2348int i;23492350/* Handle the typical case specially */2351if (word[last] = subset[++lastid]) return;23522353lastid = 0;2354word[i = last] = c0;2355while (i--) { // Have a preceding position?2356if (word[i] = subset[++id[i]]) return;2357id[i] = 0;2358word[i] = c0;2359}23602361if (++last < maxlength) { // Next length?2362id[last] = lastid = 0;2363word[last] = c0;2364word[last + 1] = 0;2365return;2366}23672368/* Next subset */2369if (subcount) {2370int j;2371i = subcount - 1;2372j = charcount;2373while (++subid[i] >= j) {2374if (i--) {2375j--;2376continue;2377}2378subid[i = 0] = 0;2379subset[++subcount] = 0;2380break;2381}2382} else {2383subid[i = 0] = 0;2384subset[++subcount] = 0;2385}2386subset[i] = charset[subid[i]];2387while (++i < subcount)2388subset[i] = charset[subid[i] = subid[i - 1] + 1];23892390if (subcount > maxdiff) {2391word = 0; // Done2392return;2393}23942395/*2396* We won't be able to fully use the subset if the length is smaller than the2397* character count. We assume that we've tried all smaller subsets before, so2398* we don't bother with such short lengths.2399*/2400if (minlength < subcount)2401last = subcount - 1;2402else2403last = minlength - 1;2404c0 = subset[0];2405i = 0;2406while (i <= last) {2407id[i] = 0;2408word[i++] = c0;2409}2410lastid = 0;2411word[i] = 0;2412}24132414# Try sequences of adjacent keys on a keyboard as candidate passwords2415[List.External:Keyboard]2416int maxlength, length; // Maximum password length to try, current length2417int fuzz; // The desired "fuzz factor", either 0 or 12418int id[15]; // Current character indices for each position2419int m[0x800]; // The keys matrix2420int mc[0x100]; // Counts of adjacent keys2421int f[0x40], fc; // Characters for the first position, their count24222423void init()2424{2425int minlength;2426int i, j, c, p;2427int k[0x40];24282429// Initial password length to try2430if (req_minlen)2431minlength = req_minlen;2432else2433minlength = 1;2434if (req_maxlen)2435maxlength = req_maxlen;2436else2437maxlength = cipher_limit; // the format's limit2438fuzz = 1; // "Fuzz factor", set to 0 for much quicker runs24392440/*2441* This defines the keyboard layout, by default for a QWERTY keyboard.2442*/2443i = 0; while (i < 0x40) k[i++] = 0;2444k[0] = '`';2445i = 0; while (++i <= 9) k[i] = '0' + i;2446k[10] = '0'; k[11] = '-'; k[12] = '=';2447k[0x11] = 'q'; k[0x12] = 'w'; k[0x13] = 'e'; k[0x14] = 'r';2448k[0x15] = 't'; k[0x16] = 'y'; k[0x17] = 'u'; k[0x18] = 'i';2449k[0x19] = 'o'; k[0x1a] = 'p'; k[0x1b] = '['; k[0x1c] = ']';2450k[0x1d] = '\\';2451k[0x21] = 'a'; k[0x22] = 's'; k[0x23] = 'd'; k[0x24] = 'f';2452k[0x25] = 'g'; k[0x26] = 'h'; k[0x27] = 'j'; k[0x28] = 'k';2453k[0x29] = 'l'; k[0x2a] = ';'; k[0x2b] = '\'';2454k[0x31] = 'z'; k[0x32] = 'x'; k[0x33] = 'c'; k[0x34] = 'v';2455k[0x35] = 'b'; k[0x36] = 'n'; k[0x37] = 'm'; k[0x38] = ',';2456k[0x39] = '.'; k[0x3a] = '/';24572458i = 0; while (i < 0x100) mc[i++] = 0;2459fc = 0;24602461/* rows */2462c = 0;2463i = 0;2464while (i < 0x40) {2465p = c;2466c = k[i++] & 0xff;2467if (!c) continue;2468f[fc++] = c;2469if (!p) continue;2470m[(c << 3) + mc[c]++] = p;2471m[(p << 3) + mc[p]++] = c;2472}2473f[fc] = 0;24742475/* columns */2476i = 0;2477while (i < 0x30) {2478p = k[i++] & 0xff;2479if (!p) continue;2480j = 1 - fuzz;2481while (j <= 1 + fuzz) {2482c = k[i + 0x10 - j++] & 0xff;2483if (!c) continue;2484m[(c << 3) + mc[c]++] = p;2485m[(p << 3) + mc[p]++] = c;2486}2487}24882489length = 0;2490while (length < minlength)2491id[length++] = 0;2492}24932494void generate()2495{2496int i, p, maxcount;24972498word[i = 0] = p = f[id[0]];2499while (++i < length)2500word[i] = p = m[(p << 3) + id[i]];2501word[i--] = 0;25022503if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;2504while (++id[i] >= maxcount) {2505if (!i) {2506if (length < maxlength) {2507id[0] = 0;2508id[length++] = 0;2509}2510return;2511}2512id[i--] = 0;2513if (i) maxcount = mc[word[i - 1]]; else maxcount = fc;2514}2515}25162517void restore()2518{2519int i;25202521/* Calculate the length */2522length = 0;2523while (word[length])2524id[length++] = 0;25252526/* Infer the first character index */2527i = -1;2528while (++i < fc) {2529if (f[i] == word[0]) {2530id[0] = i;2531break;2532}2533}25342535/* This sample can be enhanced to infer the rest of the indices here */2536}25372538# Simplest (fastest?) possible dumb exhaustive search, demonstrating a2539# mode that does not need any special restore() handling.2540# Defaults to printable ASCII.2541[List.External:DumbDumb]2542int maxlength; // Maximum password length to try2543int startchar, endchar; // Range of characters (inclusive)25442545void init()2546{2547int i;25482549startchar = ' '; // Start with space2550endchar = '~'; // End with tilde25512552// Create first word, honoring --min-len2553if (!(i = req_minlen))2554i++;2555word[i] = 0;2556while (i--)2557word[i] = startchar;2558word[0] = startchar - 1;25592560if (req_maxlen)2561maxlength = req_maxlen; // --max-len2562else2563maxlength = cipher_limit; // format's limit2564}25652566void generate()2567{2568int i;25692570if (++word <= endchar)2571return;25722573i = 0;25742575while (word[i] > endchar) {2576word[i++] = startchar;2577if (!word[i]) {2578word[i] = startchar;2579word[i + 1] = 0;2580} else2581word[i]++;2582}25832584if (i >= maxlength)2585word = 0;2586}25872588/*2589* This mode will resume correctly without any restore handing.2590* The empty function just confirms to John that everything is in order.2591*/2592void restore()2593{2594}25952596# Generic implementation of "dumb" exhaustive search, given a range of lengths2597# and an arbitrary charset. This is pre-configured to try 8-bit characters2598# against LM hashes, which is only reasonable to do for very short password2599# half lengths.2600[List.External:DumbForce]2601int maxlength; // Maximum password length to try2602int last; // Last character position, zero-based2603int lastid; // Character index in the last position2604int id[0x7f]; // Current character indices for other positions2605int charset[0x100], c0; // Character set26062607void init()2608{2609int minlength;2610int i, c;26112612// Initial password length to try, must be at least 12613if (req_minlen)2614minlength = req_minlen;2615else2616minlength = 1;2617if (req_maxlen)2618maxlength = req_maxlen;2619else2620maxlength = cipher_limit; // the format's limit26212622/*2623* This defines the character set.2624*2625* Let's say, we want to try TAB, all non-control ASCII characters, and all2626* 8-bit characters, including the 8-bit terminal controls range (as these are2627* used as regular national characters with some 8-bit encodings), but except2628* for known terminal controls (risky for the terminal we may be running on).2629*2630* Also, let's say our hashes are case-insensitive, so skip lowercase letters2631* (this is right for LM hashes).2632*/2633i = 0;2634charset[i++] = 9; // Add horizontal TAB (ASCII 9), then2635c = ' '; // start with space (ASCII 32) and2636while (c < 'a') // proceed till lowercase 'a'2637charset[i++] = c++;2638c = 'z' + 1; // Skip lowercase letters and2639while (c <= 0x7e) // proceed for all printable ASCII2640charset[i++] = c++;2641c++; // Skip DEL (ASCII 127) and2642while (c < 0x84) // proceed over 8-bit codes till IND2643charset[i++] = c++;2644charset[i++] = 0x86; // Skip IND (84 hex) and NEL (85 hex)2645charset[i++] = 0x87;2646c = 0x89; // Skip HTS (88 hex)2647while (c < 0x8d) // Proceed till RI (8D hex)2648charset[i++] = c++;2649c = 0x91; // Skip RI, SS2, SS3, DCS2650while (c < 0x96) // Proceed till SPA (96 hex)2651charset[i++] = c++;2652charset[i++] = 0x99; // Skip SPA, EPA, SOS2653c = 0xa0; // Skip DECID, CSI, ST, OSC, PM, APC2654while (c <= 0xff) // Proceed with the rest of 8-bit codes2655charset[i++] = c++;26562657/* Zero-terminate it, and cache the first character */2658charset[i] = 0;2659c0 = charset[0];26602661last = minlength - 1;2662i = 0;2663while (i <= last) {2664id[i] = 0;2665word[i++] = c0;2666}2667lastid = -1;2668word[i] = 0;2669}26702671void generate()2672{2673int i;26742675/* Handle the typical case specially */2676if (word[last] = charset[++lastid]) return;26772678lastid = 0;2679word[i = last] = c0;2680while (i--) { // Have a preceding position?2681if (word[i] = charset[++id[i]]) return;2682id[i] = 0;2683word[i] = c0;2684}26852686if (++last < maxlength) { // Next length?2687id[last] = lastid = 0;2688word[last] = c0;2689word[last + 1] = 0;2690} else // We're done2691word = 0;2692}26932694void restore()2695{2696int i, c;26972698/* Calculate the current length and infer the character indices */2699last = 0;2700while (c = word[last]) {2701i = 0; while (charset[i] != c && charset[i]) i++;2702if (!charset[i]) i = 0; // Not found2703id[last++] = i;2704}2705lastid = id[--last];2706}27072708# Generic implementation of exhaustive search for a partially-known password.2709# This is pre-configured for length 8, lowercase and uppercase letters in the2710# first 4 positions (52 different characters), and digits in the remaining 42711# positions - however, the corresponding part of init() may be modified to use2712# arbitrary character sets or even fixed characters for each position.2713[List.External:KnownForce]2714int last; // Last character position, zero-based2715int lastofs; // Last character position offset into charset[]2716int lastid; // Current character index in the last position2717int id[0x7f]; // Current character indices for other positions2718int charset[0x7f00]; // Character sets, 0x100 elements for each position27192720void init()2721{2722int length, maxlength;2723int pos, ofs, i, c;27242725if (req_minlen)2726length = req_minlen;2727else2728length = 8; // Password length to try (NOTE: other [eg. shorter]2729// lengths will not be tried!)2730if (req_maxlen)2731maxlength = req_maxlen;2732else2733maxlength = cipher_limit; // the format's limit27342735/* This defines the character sets for different character positions */2736if (length > maxlength)2737length = maxlength;2738pos = 0;2739while (pos < 4) {2740ofs = pos++ << 8;2741i = 0;2742c = 'a';2743while (c <= 'z')2744charset[ofs + i++] = c++;2745c = 'A';2746while (c <= 'Z')2747charset[ofs + i++] = c++;2748charset[ofs + i] = 0;2749}2750while (pos < length) {2751ofs = pos++ << 8;2752i = 0;2753c = '0';2754while (c <= '9')2755charset[ofs + i++] = c++;2756charset[ofs + i] = 0;2757}27582759last = length - 1;2760pos = -1;2761while (++pos <= last)2762word[pos] = charset[id[pos] = pos << 8];2763lastid = (lastofs = last << 8) - 1;2764word[pos] = 0;2765}27662767void generate()2768{2769int pos;27702771/* Handle the typical case specially */2772if (word[last] = charset[++lastid]) return;27732774word[pos = last] = charset[lastid = lastofs];2775while (pos--) { // Have a preceding position?2776if (word[pos] = charset[++id[pos]]) return;2777word[pos] = charset[id[pos] = pos << 8];2778}27792780word = 0; // We're done2781}27822783void restore()2784{2785int i, c;27862787/* Calculate the current length and infer the character indices */2788last = 0;2789while (c = word[last]) {2790i = lastofs = last << 8;2791while (charset[i] != c && charset[i]) i++;2792if (!charset[i]) i = lastofs; // Not found2793id[last++] = i;2794}2795lastid = id[--last];2796}27972798# A variation of KnownForce configured to try likely date and time strings.2799[List.External:DateTime]2800int last; // Last character position, zero-based2801int lastofs; // Last character position offset into charset[]2802int lastid; // Current character index in the last position2803int id[0x7f]; // Current character indices for other positions2804int charset[0x7f00]; // Character sets, 0x100 elements for each position28052806void init()2807{2808int length;2809int pos, ofs, i, c;28102811length = 8; // Must be one of: 4, 5, 7, 828122813/* This defines the character sets for different character positions */2814pos = 0;2815while (pos < length - 6) {2816ofs = pos++ << 8;2817i = 0;2818c = '0';2819while (c <= '9')2820charset[ofs + i++] = c++;2821charset[ofs + i] = 0;2822}2823if (pos) {2824ofs = pos++ << 8;2825charset[ofs] = '/';2826charset[ofs + 1] = '.';2827charset[ofs + 2] = ':';2828charset[ofs + 3] = 0;2829}2830while (pos < length - 3) {2831ofs = pos++ << 8;2832i = 0;2833c = '0';2834while (c <= '9')2835charset[ofs + i++] = c++;2836charset[ofs + i] = 0;2837}2838ofs = pos++ << 8;2839charset[ofs] = '/';2840charset[ofs + 1] = '.';2841charset[ofs + 2] = ':';2842charset[ofs + 3] = 0;2843while (pos < length) {2844ofs = pos++ << 8;2845i = 0;2846c = '0';2847while (c <= '9')2848charset[ofs + i++] = c++;2849charset[ofs + i] = 0;2850}28512852last = length - 1;2853pos = -1;2854while (++pos <= last)2855word[pos] = charset[id[pos] = pos << 8];2856lastid = (lastofs = last << 8) - 1;2857word[pos] = 0;2858}28592860void generate()2861{2862int pos;28632864/* Handle the typical case specially */2865if (word[last] = charset[++lastid]) return;28662867word[pos = last] = charset[lastid = lastofs];2868while (pos--) { // Have a preceding position?2869if (word[pos] = charset[++id[pos]]) return;2870word[pos] = charset[id[pos] = pos << 8];2871}28722873word = 0; // We're done2874}28752876void restore()2877{2878int i, c;28792880/* Calculate the current length and infer the character indices */2881last = 0;2882while (c = word[last]) {2883i = lastofs = last << 8;2884while (charset[i] != c && charset[i]) i++;2885if (!charset[i]) i = lastofs; // Not found2886id[last++] = i;2887}2888lastid = id[--last];2889}28902891# A variation of KnownForce configured to try all the 385641000 possible2892# auto-generated passwords of DokuWiki versions up to at least 2013-05-10.2893[List.External:DokuWiki]2894int last; // Last character position, zero-based2895int lastofs; // Last character position offset into charset[]2896int lastid; // Current character index in the last position2897int id[0x7f]; // Current character indices for other positions2898int charset[0x7f00]; // Character sets, 0x100 elements for each position28992900void init()2901{2902int A[26], C[26], V[26];2903int length;2904int pos, ofs, i, c;29052906i = 0; while (i < 26) { A[i] = C[i] = 1; V[i++] = 0; }2907i = 'a' - 'a'; C[i] = 0; V[i] = 1;2908i = 'e' - 'a'; C[i] = 0; V[i] = 1;2909i = 'i' - 'a'; C[i] = 0; V[i] = 1;2910i = 'o' - 'a'; C[i] = 0; V[i] = 1;2911i = 'u' - 'a'; C[i] = 0; V[i] = 1;2912i = 'q' - 'a'; A[i] = C[i] = 0;2913i = 'x' - 'a'; A[i] = C[i] = 0;2914i = 'y' - 'a'; A[i] = C[i] = 0;29152916length = 8;29172918/* This defines the character sets for different character positions */2919pos = 0;2920while (pos < 6) {2921ofs = pos++ << 8;2922i = 0;2923c = 'a' - 1;2924while (++c <= 'z')2925if (C[c - 'a'])2926charset[ofs + i++] = c;2927charset[ofs + i] = 0;2928ofs = pos++ << 8;2929i = 0;2930c = 'a' - 1;2931while (++c <= 'z')2932if (V[c - 'a'])2933charset[ofs + i++] = c;2934charset[ofs + i] = 0;2935ofs = pos++ << 8;2936i = 0;2937c = 'a' - 1;2938while (++c <= 'z')2939if (A[c - 'a'])2940charset[ofs + i++] = c;2941charset[ofs + i] = 0;2942}2943c = '1';2944while (pos < length) {2945ofs = pos++ << 8;2946i = 0;2947while (c <= '9')2948charset[ofs + i++] = c++;2949charset[ofs + i] = 0;2950c = '0';2951}29522953last = length - 1;2954pos = -1;2955while (++pos <= last)2956word[pos] = charset[id[pos] = pos << 8];2957lastid = (lastofs = last << 8) - 1;2958word[pos] = 0;2959}29602961void generate()2962{2963int pos;29642965/* Handle the typical case specially */2966if (word[last] = charset[++lastid]) return;29672968word[pos = last] = charset[lastid = lastofs];2969while (pos--) { // Have a preceding position?2970if (word[pos] = charset[++id[pos]]) return;2971word[pos] = charset[id[pos] = pos << 8];2972}29732974word = 0; // We're done2975}29762977void restore()2978{2979int i, c;29802981/* Calculate the current length and infer the character indices */2982last = 0;2983while (c = word[last]) {2984i = lastofs = last << 8;2985while (charset[i] != c && charset[i]) i++;2986if (!charset[i]) i = lastofs; // Not found2987id[last++] = i;2988}2989lastid = id[--last];2990}29912992# Strip 0.5 ("Secure Tool for Recalling Important Passwords") cracker,2993# based on analysis done by Thomas Roessler and Ian Goldberg. This will2994# crack passwords you may have generated with Strip; other uses of Strip2995# are unaffected.2996[List.External:Strip]2997int minlength, maxlength, mintype, maxtype;2998int crack_seed, length, type;2999int count, charset[128];30003001void init()3002{3003int c;30043005/* Password lengths to try; Strip can generate passwords of 4 to 163006* characters, but traditional crypt(3) hashes are limited to 8. */3007minlength = req_minlen;3008if (minlength < 4)3009minlength = 4;3010if (req_maxlen)3011maxlength = req_maxlen;3012else // the format's limit3013maxlength = cipher_limit;3014if (maxlength >16) maxlength = 16;30153016/* Password types to try (Numeric, Alpha-Num, Alpha-Num w/ Meta). */3017mintype = 0; // 03018maxtype = 2; // 230193020crack_seed = 0x10000;3021length = minlength - 1;3022type = mintype;30233024count = 0;3025c = '0'; while (c <= '9') charset[count++] = c++;3026}30273028void generate()3029{3030int seed, random;3031int i, c;30323033if (crack_seed > 0xffff) {3034crack_seed = 0;30353036if (++length > maxlength) {3037length = minlength;30383039if (++type > maxtype) {3040word[0] = 0;3041return;3042}3043}30443045count = 10;3046if (type >= 1) {3047c = 'a'; while (c <= 'f') charset[count++] = c++;3048c = 'h'; while (c <= 'z') charset[count++] = c++;3049c = 'A'; while (c <= 'Z') charset[count++] = c++;3050}3051if (type == 2) {3052charset[count++] = '!';3053c = '#'; while (c <= '&') charset[count++] = c++;3054c = '('; while (c <= '/') charset[count++] = c++;3055c = '<'; while (c <= '>') charset[count++] = c++;3056charset[count++] = '?'; charset[count++] = '@';3057charset[count++] = '['; charset[count++] = ']';3058charset[count++] = '^'; charset[count++] = '_';3059c = '{'; while (c <= '~') charset[count++] = c++;3060}3061}30623063seed = (crack_seed++ << 16 >> 16) * 22695477 + 1;30643065i = 0;3066while (i < length) {3067random = ((seed = seed * 22695477 + 1) >> 16) & 0x7fff;3068word[i++] = charset[random % count];3069}30703071word[i] = 0;3072}30733074/*3075* This takes advantage of CVE-2013-2120 to find seeds that KDE Paste applet3076* uses to generate passwords.3077*3078* This software is Copyright (c) Michael Samuel <[email protected]>,3079* and it is hereby released to the general public under the following terms:3080* Redistribution and use in source and binary forms, with or without3081* modification, are permitted.3082*/3083[List.External:KDEPaste]3084int charset[95];3085int charset_length, password_length, endTime, startTime, msec;30863087void init()3088{3089password_length = 8; /* Change this to match config */3090endTime = session_start_time;3091startTime = 1343743200; /* Aug 1 2012 - Change this as necessary */30923093msec = 1; /* msec is never 0 - it would crash the applet */30943095charset_length = 0;3096int c;30973098/* Comment out classes that you don't need, but keep the order the same */3099/* Lowers */3100c = 'a'; while (c <= 'z') charset[charset_length++] = c++;31013102/* Uppers */3103c = 'A'; while (c <= 'Z') charset[charset_length++] = c++;31043105/* Numbers */3106c = '0'; while (c <= '9') charset[charset_length++] = c++;3107charset[charset_length++] = '0'; /* Yep, it's there twice */31083109/* Symbols */3110c = '!'; while (c <= '/') charset[charset_length++] = c++;3111c = ':'; while (c <= '@') charset[charset_length++] = c++;3112c = '['; while (c <= '`') charset[charset_length++] = c++;3113c = '{'; while (c <= '~') charset[charset_length++] = c++;3114}31153116void generate()3117{3118int i, rand_seed, rand_result;31193120/* Terminate once we've generated for all *3121* of the time range (Plus a bit more...) */3122if (endTime + 1000 < startTime) {3123word = 0;3124return;3125}31263127/* Skip msecs that would generate dupes */3128while (endTime % msec != 0) {3129if (++msec > 999) {3130endTime--;3131msec = 1;3132}3133}31343135rand_seed = endTime / msec;31363137i = 0;3138while (i < password_length) {3139/* this works like rand_r() from eglibc */3140rand_seed = rand_seed * 1103515245 + 12345;3141rand_result = (rand_seed >> 16) & 2047;31423143rand_seed = rand_seed * 1103515245 + 12345;3144rand_result <<= 10;3145rand_result ^= (rand_seed >> 16) & 1023;31463147rand_seed = rand_seed * 1103515245 + 12345;3148rand_result <<= 10;3149rand_result ^= (rand_seed >> 16) & 1023;31503151word[i++] = charset[rand_result % charset_length];3152}3153word[i] = 0;31543155if (++msec > 999) {3156endTime--;3157msec = 1;3158}3159}31603161void restore()3162{3163int i, rand_seed, rand_result;31643165i = 0;31663167/* Very crude restore, just dry-run until we hit last word */3168while (i != password_length) {31693170while (endTime % msec != 0) {3171if (++msec > 999) {3172endTime--;3173msec = 1;3174}3175}31763177rand_seed = endTime / msec;31783179i = 0;3180while (i < password_length) {3181/* this works like rand_r() from eglibc */3182rand_seed = rand_seed * 1103515245 + 12345;3183rand_result = (rand_seed >> 16) & 2047;31843185rand_seed = rand_seed * 1103515245 + 12345;3186rand_result <<= 10;3187rand_result ^= (rand_seed >> 16) & 1023;31883189rand_seed = rand_seed * 1103515245 + 12345;3190rand_result <<= 10;3191rand_result ^= (rand_seed >> 16) & 1023;31923193if (charset[rand_result % charset_length] != word[i++])3194break;3195}31963197if (++msec > 999) {3198endTime--;3199msec = 1;3200}3201}3202}32033204/* Awesome Password Generator RNG replay3205* Written by Michael Samuel <[email protected]>3206* Public Domain.3207*3208* This takes advantage of a subtle bug, where a crypto RNG is used to3209* seed the C# System.Random() class, which takes a 32-bit input, but3210* converts negative numbers into non-negative numbers, resulting in3211* only 31 bits of security.3212*3213* This only implements "easy to type" being *unticked*, and numbers,3214* lowers, uppers and symbols being ticked, in random password mode.3215* Changing the password length is easy, anything else is left as an3216* exercise to the reader.3217*3218* Running Awesome Password Generator (1.3.2 or lower) in Mono is still3219* vulnerable, but uses a different RNG, so this mode isn't compatible.3220*/32213222/* Awesome Password Generator 1.3.2 does a two-pass run, selecting which3223* charset each position will have, then picking the character. This3224* leads to heavy bias, and is fixed in 1.4.0 (along with many other3225* fixes). If you have been using Awesome Password Generator, you should3226* upgrade immediately and change your passwords.3227*/3228[List.External:AwesomePasswordGenerator]3229int numbers[10];3230int lowers[26];3231int uppers[26];3232int symbols[32];32333234/* Since we don't have a double datatype, I simply pre-calculated the3235* transition numbers calculating the scale formula:3236* (double)randNum * 4.656612873077393e-10 * {4/10/26/32}3237*/3238int boundaries_charclass[4];3239int boundaries_numbers[10];3240int boundaries_letters[26];3241int boundaries_symbols[32];32423243/* This is the bug we're exploiting - the seed for the RNG is 32 bits3244* from the crypto rng. The non-crypto RNG converts negative numbers3245* into non-negative numbers, so there's only 2^31 possible seeds.3246*/3247int seed;32483249int password_length;32503251void init()3252{3253password_length = 16; /* Change this to match config */32543255int c, i;32563257c = '0'; i = 0; while (c <= '9') numbers[i++] = c++;3258c = 'a'; i = 0; while (c <= 'z') lowers[i++] = c++;3259c = 'A'; i = 0; while (c <= 'Z') uppers[i++] = c++;32603261/* Symbols */3262i = 0;3263symbols[i++] = '!'; symbols[i++] = '@'; symbols[i++] = '#'; symbols[i++] = '$';3264symbols[i++] = '%'; symbols[i++] = '^'; symbols[i++] = '&'; symbols[i++] = '*';3265symbols[i++] = '('; symbols[i++] = ')'; symbols[i++] = '~'; symbols[i++] = '-';3266symbols[i++] = '_'; symbols[i++] = '='; symbols[i++] = '+'; symbols[i++] = '\\';3267symbols[i++] = '|'; symbols[i++] = '/'; symbols[i++] = '['; symbols[i++] = ']';3268symbols[i++] = '{'; symbols[i++] = '}'; symbols[i++] = ';'; symbols[i++] = ':';3269symbols[i++] = '`'; symbols[i++] = '\''; symbols[i++] = '"'; symbols[i++] = ',';3270symbols[i++] = '.'; symbols[i++] = '<'; symbols[i++] = '>'; symbols[i++] = '?';32713272i = 0;3273boundaries_charclass[i++] = 536870912; boundaries_charclass[i++] = 1073741824;3274boundaries_charclass[i++] = 1610612736; boundaries_charclass[i++] = 2147483647;32753276i = 0;3277boundaries_numbers[i++] = 214748365; boundaries_numbers[i++] = 429496730;3278boundaries_numbers[i++] = 644245095; boundaries_numbers[i++] = 858993460;3279boundaries_numbers[i++] = 1073741824; boundaries_numbers[i++] = 1288490189;3280boundaries_numbers[i++] = 1503238554; boundaries_numbers[i++] = 1717986919;3281boundaries_numbers[i++] = 1932735284; boundaries_numbers[i++] = 2147483647;32823283i = 0;3284boundaries_letters[i++] = 82595525; boundaries_letters[i++] = 165191050;3285boundaries_letters[i++] = 247786575; boundaries_letters[i++] = 330382100;3286boundaries_letters[i++] = 412977625; boundaries_letters[i++] = 495573150;3287boundaries_letters[i++] = 578168675; boundaries_letters[i++] = 660764200;3288boundaries_letters[i++] = 743359725; boundaries_letters[i++] = 825955250;3289boundaries_letters[i++] = 908550775; boundaries_letters[i++] = 991146300;3290boundaries_letters[i++] = 1073741824; boundaries_letters[i++] = 1156337349;3291boundaries_letters[i++] = 1238932874; boundaries_letters[i++] = 1321528399;3292boundaries_letters[i++] = 1404123924; boundaries_letters[i++] = 1486719449;3293boundaries_letters[i++] = 1569314974; boundaries_letters[i++] = 1651910499;3294boundaries_letters[i++] = 1734506024; boundaries_letters[i++] = 1817101549;3295boundaries_letters[i++] = 1899697074; boundaries_letters[i++] = 1982292599;3296boundaries_letters[i++] = 2064888124; boundaries_letters[i++] = 2147483647;32973298i = 0;3299boundaries_symbols[i++] = 67108864; boundaries_symbols[i++] = 134217728;3300boundaries_symbols[i++] = 201326592; boundaries_symbols[i++] = 268435456;3301boundaries_symbols[i++] = 335544320; boundaries_symbols[i++] = 402653184;3302boundaries_symbols[i++] = 469762048; boundaries_symbols[i++] = 536870912;3303boundaries_symbols[i++] = 603979776; boundaries_symbols[i++] = 671088640;3304boundaries_symbols[i++] = 738197504; boundaries_symbols[i++] = 805306368;3305boundaries_symbols[i++] = 872415232; boundaries_symbols[i++] = 939524096;3306boundaries_symbols[i++] = 1006632960; boundaries_symbols[i++] = 1073741824;3307boundaries_symbols[i++] = 1140850688; boundaries_symbols[i++] = 1207959552;3308boundaries_symbols[i++] = 1275068416; boundaries_symbols[i++] = 1342177280;3309boundaries_symbols[i++] = 1409286144; boundaries_symbols[i++] = 1476395008;3310boundaries_symbols[i++] = 1543503872; boundaries_symbols[i++] = 1610612736;3311boundaries_symbols[i++] = 1677721600; boundaries_symbols[i++] = 1744830464;3312boundaries_symbols[i++] = 1811939328; boundaries_symbols[i++] = 1879048192;3313boundaries_symbols[i++] = 1946157056; boundaries_symbols[i++] = 2013265920;3314boundaries_symbols[i++] = 2080374784; boundaries_symbols[i++] = 2147483647;33153316seed = 0;3317}33183319void generate()3320{3321int i, j, s, next, nextp, val, bucket, randnum, used_charsets;3322int seedarray[56];33233324/* BEGIN System.Random(seed) */3325if(seed < 0) {3326/* Only bother with non-negative integers */3327word = 0;3328return;3329}33303331s = 161803398 - seed++;3332seedarray[55] = s;3333i = val = 1;33343335while(i < 55) {3336bucket = 21 * i % 55;3337seedarray[bucket] = val;3338val = s - val;3339if(val < 0) val += 2147483647;3340s = seedarray[bucket];3341i++;3342}33433344i = 1;3345while(i < 5) {3346j = 1;3347while(j < 56) {3348seedarray[j] -= seedarray[1 + (j + 30) % 55];3349if(seedarray[j] < 0) seedarray[j] += 2147483647;3350j++;3351}3352i++;3353}3354next = 0;3355nextp = 21;3356/* END System.Random(seed) */33573358used_charsets = 0;3359while(used_charsets != 15) {3360i = 0;3361while(i < password_length) {3362/* BEGIN Random.Sample() */3363if (++next >= 56) next = 1;3364if (++nextp >= 56) nextp = 1;3365randnum = seedarray[next] - seedarray[nextp];3366if (randnum == 2147483647) randnum--;3367if (randnum < 0) randnum += 2147483647;3368seedarray[next] = randnum;3369/* END Random.Sample() */33703371j = 0;3372while(boundaries_charclass[j] < randnum) j++;33733374word[i] = j; /* Temporarily store in word[] */3375used_charsets |= (1 << j);3376i++;3377}3378}33793380i = 0;3381while(i < password_length) {3382/* BEGIN Random.Sample() */3383if (++next >= 56) next = 1;3384if (++nextp >= 56) nextp = 1;3385randnum = seedarray[next] - seedarray[nextp];3386if (randnum == 2147483647) randnum--;3387if (randnum < 0) randnum += 2147483647;3388seedarray[next] = randnum;3389/* END Random.Sample() */3390j = 0;33913392if(word[i] == 0) {3393while(boundaries_letters[j] < randnum) j++;3394word[i++] = lowers[j];3395} else if (word[i] == 1) {3396while(boundaries_letters[j] < randnum) j++;3397word[i++] = uppers[j];3398} else if (word[i] == 2) {3399while(boundaries_numbers[j] < randnum) j++;3400word[i++] = numbers[j];3401} else { /* if (word[i] == 3) */3402while(boundaries_symbols[j] < randnum) j++;3403word[i++] = symbols[j];3404}3405}3406word[i] = 0;3407}340834093410void restore()3411{3412int i, j, s, next, nextp, val, bucket, randnum, used_charsets;3413int seedarray[56];3414int candidate[32]; /* This needs to be at-least as big as password-length */34153416seed = 0;34173418while(seed > 0) {3419/* BEGIN System.Random(seed) */3420s = 161803398 - seed++;3421seedarray[55] = s;3422i = val = 1;34233424while(i < 55) {3425bucket = 21 * i % 55;3426seedarray[bucket] = val;3427val = s - val;3428if(val < 0) val += 2147483647;3429s = seedarray[bucket];3430i++;3431}34323433i = 1;3434while(i < 5) {3435j = 1;3436while(j < 56) {3437seedarray[j] -= seedarray[1 + (j + 30) % 55];3438if(seedarray[j] < 0) seedarray[j] += 2147483647;3439j++;3440}3441i++;3442}3443next = 0;3444nextp = 21;3445/* END System.Random(seed) */34463447used_charsets = 0;3448while(used_charsets != 15) {3449i = 0;3450while(i < password_length) {3451/* BEGIN Random.Sample() */3452if (++next >= 56) next = 1;3453if (++nextp >= 56) nextp = 1;3454randnum = seedarray[next] - seedarray[nextp];3455if (randnum == 2147483647) randnum--;3456if (randnum < 0) randnum += 2147483647;3457seedarray[next] = randnum;3458/* END Random.Sample() */34593460j = 0;3461while(boundaries_charclass[j] < randnum) j++;34623463candidate[i] = j;3464used_charsets |= (1 << j);3465i++;3466}3467}34683469i = 0;3470while(i < password_length) {3471/* BEGIN Random.Sample() */3472if (++next >= 56) next = 1;3473if (++nextp >= 56) nextp = 1;3474randnum = seedarray[next] - seedarray[nextp];3475if (randnum == 2147483647) randnum--;3476if (randnum < 0) randnum += 2147483647;3477seedarray[next] = randnum;3478/* END Random.Sample() */3479j = 0;34803481if(candidate[i] == 0) {3482while(boundaries_letters[j] < randnum) j++;3483if(lowers[j] != word[i++]) break;3484} else if (candidate[i] == 1) {3485while(boundaries_letters[j] < randnum) j++;3486if(uppers[j] != word[i++]) break;3487} else if (candidate[i] == 2) {3488while(boundaries_numbers[j] < randnum) j++;3489if(numbers[j] != word[i++]) break;3490} else { /* if (word[i] == 3) */3491while(boundaries_symbols[j] < randnum) j++;3492if(symbols[j] != word[i++]) break;3493}3494}3495if(i == password_length) return;3496}3497}34983499# generate all possible wps pins3500[List.External:wpspin]3501int pin;3502void init() {3503pin = 0;3504}3505void generate() {3506if (pin > 9999999) {3507word = 0;3508return;3509}3510int i, p;3511i = 0;3512while (i < 8) word[i++] = '0';3513word[8] = 0;3514p = pin;3515i = 6;3516while (p) {3517word[i] = '0' + p % 10;3518p /= 10;3519--i;3520}3521p = pin;3522i = 0;3523while (p) {3524i += 3 * (p % 10);3525p /= 10;3526i += p % 10;3527p /= 10;3528}3529word[7] = '0' + ((10 - i % 10) % 10);3530++pin;3531}35323533# Append the Luhn algorithm digit to arbitrary all-digit strings. Optimized3534# for speed, not for size nor simplicity. The primary optimization trick is to3535# compute the length and four sums in parallel (in two SIMD'ish variables).3536# Then whether the length is even or odd determines which two of the four sums3537# are actually used. Checks for non-digits and for NUL are packed into the3538# SIMD'ish bitmasks as well.3539[List.External:AppendLuhn]3540int map1[0x100], map2[0x1fff];35413542void init()3543{3544int i;35453546map1[0] = ~0x7fffffff;3547i = 1;3548while (i < 0x100)3549map1[i++] = ~0x7effffff;3550i = -1;3551while (++i < 10)3552map1['0' + i] = i + ((i * 2 % 10 + i / 5) << 12);3553i = -1;3554while (++i < 0x1fff) {3555if (i % 10)3556map2[i] = '9' + 1 - i % 10;3557else3558map2[i] = '0';3559}3560}35613562void filter()3563{3564int i, o, e;35653566i = o = e = 0;3567while ((o += map1[word[i++]]) >= 0) {3568if ((e += map1[word[i++]]) >= 0)3569continue;3570if (e & 0x01000000)3571return; // Not all-digit, leave unmodified3572word[i--] = 0;3573word[i] = map2[(e & 0xfff) + (o >> 12)];3574return;3575}3576if (o & 0x01000000)3577return; // Not all-digit, leave unmodified3578word[i--] = 0;3579word[i] = map2[(o & 0xfff) + (e >> 12)];3580}35813582# Simple password policy matching: require at least one digit.3583[List.External:AtLeast1-Simple]3584void filter()3585{3586int i, c;35873588i = 0;3589while (c = word[i++])3590if (c >= '0' && c <= '9')3591return; // Found at least one suitable character, good35923593word = 0; // No suitable characters found, skip this "word"3594}35953596# The same password policy implemented in a more efficient and more generic3597# fashion (easy to expand to include other "sufficient" characters as well).3598[List.External:AtLeast1-Generic]3599int mask[0x100];36003601void init()3602{3603int c;36043605mask[0] = 0; // Terminate the loop in filter() on NUL3606c = 1;3607while (c < 0x100)3608mask[c++] = 1; // Continue looping in filter() on most chars36093610c = '0';3611while (c <= '9')3612mask[c++] = 0; // Terminate the loop in filter() on digits3613}36143615void filter()3616{3617int i;36183619i = -1;3620while (mask[word[++i]])3621continue;3622if (word[i])3623return; // Found at least one suitable character, good36243625word = 0; // No suitable characters found, skip this "word"3626}36273628# An efficient and fairly generic password policy matcher. The policy to match3629# is specified in the check at the end of filter() and in mask[]. For example,3630# lowercase and uppercase letters may be treated the same by initializing the3631# corresponding mask[] elements to the same value, then adjusting the value to3632# check "seen" for accordingly.3633[List.External:Policy]3634int mask[0x100];36353636void init()3637{3638int c;36393640mask[0] = 0x100;3641c = 1;3642while (c < 0x100)3643mask[c++] = 0x200;36443645c = 'a';3646while (c <= 'z')3647mask[c++] = 1;3648c = 'A';3649while (c <= 'Z')3650mask[c++] = 2;3651c = '0';3652while (c <= '9')3653mask[c++] = 4;3654}36553656void filter()3657{3658int i, seen;36593660/*3661* This loop ends when we see NUL (sets 0x100) or a disallowed character3662* (sets 0x200).3663*/3664i = -1; seen = 0;3665while ((seen |= mask[word[++i]]) < 0x100)3666continue;36673668/*3669* We should have seen at least one character of each type (which "add up"3670* to 7) and then a NUL (adds 0x100), but not any other characters (would3671* add 0x200). The length must be 8.3672*/3673if (seen != 0x107 || i != 8)3674word = 0; // Does not conform to policy3675}36763677# Trivial Rotate function, which rotates letters in a word3678# by a given number of places (like 13 in case of ROT13).3679# Words which don't contain any letters (and thus wouldn't be changed3680# by this filter) are skipped, because these unchanged words probably3681# should have been tried before trying a mangled version.3682[List.External_base:Filter_Rotate]36833684int rot; // The number of places to rotate each letter in a word36853686void filter()3687{3688int i, j, c;36893690i = 0;3691j = 0; // j counts the number of changed characters36923693while (c = word[i]) {3694if (c >= 'a' && c <= 'z') {3695c = c - 26 + rot;3696if (c < 'a') c += 26;3697word[i] = c;3698j++;3699} else if (c >= 'A' && c <= 'Z' ) {3700c = c - 26 + rot;3701if (c < 'A') c += 26;3702word[i] = c;3703j++;3704}3705i++;3706}3707if (j == 0)3708// Nothing changed. Reject this word.3709word = 0;3710}37113712# ROT13 Example3713[List.External:Filter_ROT13]3714.include [List.External_base:Filter_Rotate]3715void init()3716{3717// Just in case someone wants to "rotate" by other values,3718// adjust the value of the rot variable3719// (may be in a copied external mode):3720// 13: "abcABCxyzXYZ" -> "nopNOPklmKLM"3721// 1: "abcABCxyzXYZ" -> "bcdBCDyzaYZA"3722// 25: "abcABCxyzXYZ" -> "zabZABwxyWXY"3723// -1: "abcABCxyzXYZ" -> "zabZABwxyWXY"3724// and so on3725// Allowed range: -25 <= rot <= -1, or 1 <= rot <= 253726rot = 13;37273728// Don't change the following statement.3729// It is supposed to "sanitize" the value to be in the3730// range3731rot = (rot + 26) % 26;3732}37333734# Trivial parallel processing example (obsoleted by the "--node" option)3735[List.External:Parallel]3736/*3737* This word filter makes John process some of the words only, for running3738* multiple instances on different CPUs. It can be used with any cracking3739* mode except for "single crack". Note: this is not a good solution, but3740* is just an example of what can be done with word filters.3741*/37423743int node, total; // This node's number, and node count3744int number; // Current word number37453746void init()3747{3748node = 1; total = 2; // Node 1 of 2, change as appropriate3749number = node - 1; // Speedup the filter a bit3750}37513752void filter()3753{3754if (number++ % total) // Word for a different node?3755word = 0; // Yes, skip it3756}37573758# Interrupt the cracking session after "max" words tried3759[List.External:AutoAbort]3760int max; // Maximum number of words to try3761int number; // Current word number37623763void init()3764{3765max = 1000;3766number = 0;3767}37683769void filter()3770{3771if (++number > max)3772abort = 1; // Interrupt the cracking session3773}37743775# Print the status line after every "interval" words tried3776[List.External:AutoStatus]3777int interval; // How often to print the status3778int number; // Current word number37793780void init()3781{3782interval = 1000;3783number = 0;3784}37853786void filter()3787{3788if (number++ % interval)3789return;3790status = 1; // Print the status line3791}37923793#3794# Reference example hybrid-mode external. same as jtr-rule: $[0-9]$[0-9]3795# this format is to be used similar to a filter, in that it requires some3796# other word generator (markov, wordlist, etc). However, this type external3797# will get new() called with each word, and then have next() called, until3798# the word[0]=0 is seen (meaning all candidates for the base word have been3799# generated. Prior to new() or restore(), word[] is the 'base' word.3800# if the script is able to properly resume, then it should set the global3801# variable hybrid_total to the count of candidates that will be generated3802# for this word (in new() / restore(), then in the body of restore() there3803# is a global variable set 'hybrid_resume' that was the prior number of3804# canidates generated for this base-word. Resume should start at the NEXT3805# If the script is not able to easily resume, then simply do NOT set the3806# global hybrid_total to anything either function. JtR will 'still' resume3807# propery, but it will do so by calling new()/next()/next().../next() until3808# back to the proper resume location.3809#3810# script changed to append a _ character before the number, each time within3811# the next() function. Done this way to better validate that -restore within3812# jtr is working properly.3813#3814[List.External:Hybrid_example]3815/* static vars for the script */3816int cnt, length, total;38173818void init()3819{3820/* in this simple example, we always generate 100 candidates per word */3821total = 100;/* this is a VERY simple example */3822}38233824/* new word */3825void new()3826{3827/* get the word length) */3828length = 0; while (word[length++]) ; --length;38293830/*3831* If this was a more complex script, we would compute total candidates3832* at this location, if we can. If we can not compute total candidates3833* then it is likely we can not resume 'easily', so if that is the3834* case, we would simply set hybrid_total to -1, or do nothing, since3835* do_external_hybrid_crack() sets it to -1 before calling this function.3836*/3837hybrid_total = total;38383839/* Reset or counter for THIS word. */3840cnt = 0;38413842/*3843* word will be too long to be used, or too short to be used. If so3844* then set hybrid_total to 0 and this entire word will be skipped.3845*/3846if (req_minlen > length - 2 || (req_maxlen && req_maxlen < length + 2))3847hybrid_total = 0;3848}38493850void next()3851{3852/* in this simple script, if cnt is 100, this word is DONE */3853if (cnt == 100) {3854word[0] = 0;3855return;3856}38573858/* set word[] to the next candidate */3859word[length++] = '_';3860word[length ] = '0' + cnt / 10;3861word[length+1] = '0' + cnt % 10;3862word[length+2] = 0;3863++cnt;3864}38653866/* Called when restoring an interrupted session */3867void restore()3868{3869int i;38703871length = 0; while (word[length++]) ; --length;38723873/* for this simple script, simply setting cnt resumes */3874cnt = hybrid_resume + 1; if (cnt > 100) cnt=100;3875i = 0;3876while (i++ < cnt) word[length++] = '_';3877word[length] = 0;38783879/* tell john that we have properly 'resumed', by setting a 'proper' total */3880hybrid_total = total;3881}38823883# External hybrid 'leet code3884[List.External:Leet]3885/*3886* 1337 language in this script:3887* a -> a4@3888* b -> b83889* e -> e33890* g -> g93891* i -> i1!3892* l -> l13893* o -> o03894* s -> s$53895* t -> t73896*/38973898int rotor[626]; /* max length input is 125 bytes [125*5+1]; */3899int rotors[125];3900int rotor_ptr[125];3901int rotor_idx[125];3902int rotor_cnt[125];3903int current_word_count;3904int max_mangle; /* controls how many bytes we run through our 'leet' code */3905int max_mangle_letters;3906int original_word; /* if set to 1 then we start with original word. If 0, then start with first mangled word */39073908void init()3909{3910/* note, 3^10 is 59k so aaaaaaaaaa will produce that many words! */3911max_mangle_letters = 10; /* only mangle 10 characters max */3912max_mangle = 4000; /* Stop building new letters if our count goes over this value */3913original_word = 0;3914}39153916/* new word */3917void new()3918{3919int rotor_off, idx, wlen;3920idx = rotor_off = wlen = 0;3921hybrid_total = 1;3922while (word[wlen++]) ; --wlen;3923if (req_minlen > wlen || (req_maxlen && req_maxlen < wlen )) {3924hybrid_total = 0;3925return;3926}3927wlen = 0;3928while (word[wlen] && idx < max_mangle_letters && hybrid_total < max_mangle) {3929rotor_cnt[wlen] = rotor_idx[wlen] = 0;3930rotor_ptr[wlen] = rotor_off;3931if (word[wlen] == 'a') {3932rotor[rotor_off++] = 'a';3933rotor[rotor_off++] = '4';3934rotor[rotor_off++] = '@';3935}3936else if (word[wlen] == 'b') {3937rotor[rotor_off++] = 'b';3938rotor[rotor_off++] = '8';3939}3940else if (word[wlen] == 'e') {3941rotor[rotor_off++] = 'e';3942rotor[rotor_off++] = '3';3943}3944else if (word[wlen] == 'g') {3945rotor[rotor_off++] = 'g';3946rotor[rotor_off++] = '9';3947}3948else if (word[wlen] == 'i') {3949rotor[rotor_off++] = 'i';3950rotor[rotor_off++] = '1';3951rotor[rotor_off++] = '!';3952}3953else if (word[wlen] == 'l') {3954rotor[rotor_off++] = 'l';3955rotor[rotor_off++] = '1';3956}3957else if (word[wlen] == 'o') {3958rotor[rotor_off++] = 'o';3959rotor[rotor_off++] = '0';3960}3961else if (word[wlen] == 's') {3962rotor[rotor_off++] = 's';3963rotor[rotor_off++] = '$';3964rotor[rotor_off++] = '5';3965}3966else if (word[wlen] == 't') {3967rotor[rotor_off++] = 't';3968rotor[rotor_off++] = '7';3969}3970if (rotor_off > rotor_ptr[wlen]) {3971rotor_cnt[wlen] = rotor_off-rotor_ptr[wlen];3972hybrid_total *= rotor_cnt[wlen];3973rotors[idx++] = wlen;3974}3975++wlen;3976}3977/* hybrid_total+666 is our indicator that this is the original word */3978if (original_word)3979current_word_count = hybrid_total+666;3980else {3981current_word_count = 1; /* skip the 'original' word */3982}3983}39843985/* next iteration of this word word */3986void next()3987{3988int idx, idx2;3989if (current_word_count >= hybrid_total) {3990if (current_word_count == hybrid_total+666) {3991/* first word (starting word) we leave alone */3992/* by making it > hybrid_total, we avoid a 2nd if statement */3993current_word_count = 1;3994return;3995}3996word[0] = 0;3997return;3998}3999idx = rotors[idx2=0];4000while (++rotor_idx[idx] >= rotor_cnt[idx]) {4001rotor_idx[idx] = 0;4002word[idx] = rotor[ rotor_ptr[idx] ];4003idx = rotors[++idx2];4004}4005word[idx] = rotor[ rotor_ptr[idx]+rotor_idx[idx] ];4006++current_word_count;4007}4008/* restore() not needed. john properly restores fast enough without it */40094010# Shared base code for External hybrid CaSE and Wordcase mutation code4011[List.External_base:Case]40124013int rotor[251]; /* max length input is 125 bytes [125*5+1]; */4014int rotors[125];4015int rotor_ptr[125];4016int rotor_idx[125];4017int rotor_cnt[125];4018int current_word_count;4019int max_mangle; /* controls how many bytes we run through our 'leet' code */4020int original_word; /* if set to 1 then we start with original word. If 0, then start with first mangled word */4021int word_mode; /* if set to 1, only first character of each space-separated word is case-toggled, else every character */40224023/* new word */4024void new()4025{4026int rotor_off, idx, wlen, ch, prevch;4027idx = rotor_off = wlen = 0;4028hybrid_total = 1;4029while (word[wlen++]) ; --wlen;4030if (req_minlen > wlen || (req_maxlen && req_maxlen < wlen )) {4031hybrid_total = 0;4032return;4033}4034wlen = 0;4035prevch = ' '; /* at word start, behave as if previous char was space for wordcase mode */4036while (word[wlen] && idx < max_mangle) {4037rotor_cnt[wlen] = rotor_idx[wlen] = 0;4038rotor_ptr[wlen] = rotor_off;4039ch = word[wlen];4040/* traditionally, this block was always executed, with Wordcase4041mode added we execute it either always when word_mode isn't4042used or at the beginning of a word or when the previous char4043was space */4044if (!word_mode || prevch == ' ') {4045if (ch >= 'A' && ch <= 'Z') {4046ch += 0x20;4047word[wlen] = ch;4048rotor[rotor_off++] = ch;4049rotor[rotor_off++] = ch-0x20;4050}4051if (ch >= 'a' && ch <= 'z') {4052rotor[rotor_off++] = ch;4053rotor[rotor_off++] = ch-0x20;4054rotor_cnt[wlen] = 2;4055hybrid_total *= 2;4056rotors[idx++] = wlen;4057}4058}4059++wlen;4060prevch = ch;4061}4062/* hybrid_total+666 is our indicator that this is the original word */4063if (original_word)4064current_word_count = hybrid_total+666;4065else {4066current_word_count = 1; /* skip the 'original' word */4067}4068}40694070/* next iteration of this word word */4071void next()4072{4073int idx, idx2;4074if (current_word_count >= hybrid_total) {4075if (current_word_count == hybrid_total+666) {4076/* first word (starting word) we leave alone */4077/* by making it > hybrid_total, we avoid a 2nd if statement */4078current_word_count = 1;4079return;4080}4081word[0] = 0;4082return;4083}4084idx = rotors[idx2=0];4085while (++rotor_idx[idx] >= rotor_cnt[idx]) {4086rotor_idx[idx] = 0;4087word[idx] = rotor[ rotor_ptr[idx] ];4088idx = rotors[++idx2];4089}4090word[idx] = rotor[ rotor_ptr[idx]+rotor_idx[idx] ];4091++current_word_count;4092}4093/* restore() not needed. john properly restores fast enough without it */40944095# External hybrid CaSE mutation code4096[List.External:Case]4097.include [List.External_base:Case]40984099void init()4100{4101max_mangle = 20; /* only mangle 20 characters max (2^20 is 1 million) */4102original_word = 1; /* for case mangle, unless the data is 100% lower case, we really can not skip the original word */4103word_mode = 0;4104}410541064107# external mode toggling case in all word combinations, e.g:4108# foo bar -> foo bar, foo Bar, Foo bar, Foo Bar4109[List.External:Wordcase]4110.include [List.External_base:Case]41114112void init()4113{4114max_mangle = 20; /* only mangle 20 characters max (2^20 is 1 million) */4115original_word = 1; /* for case mangle, unless the data is 100% lower case, we really can not skip the original word */4116word_mode = 1;4117}41184119# Alternate hybrid external 'leet' mode (HybridLeet)4120.include <hybrid.conf>41214122# Note that the (newer) cracking mode --subsets=full-unicode is way faster than4123# the external dumb/repeats modes below, although not as easy to adapt to smaller4124# portions of the Unicode space. See doc/SUBSETS41254126# dumb-force UTF-16, in an external file4127.include <dumb16.conf>41284129# dumb-force UTF-32, in an external file4130.include <dumb32.conf>41314132# repeats UTF-16, in an external file4133.include <repeats16.conf>41344135# repeats UTF-32, in an external file4136.include <repeats32.conf>41374138# Dynamic ($dynamic_n$) scripting code, in an external file4139.include <dynamic.conf>41404141# Regex alphabets4142.include <regex_alphabets.conf>41434144# NOTE, this file (john.local.conf) is deprecated. If you had any modified logic in this4145# file, please create and move it to john-local.conf. The file simply can be renamed to4146# the new john-local.conf if you so choose.4147.include '$JOHN/john.local.conf'41484149# include john-local.conf (This file can be created by user, to override defaults in this john.conf file)4150.include '$JOHN/john-local.conf'41514152# include john-local.conf in local dir, it can override john.conf, john-local.conf (or any other conf file loaded)4153# This is disabled by default since it's a security risk in case JtR is ever run with untrusted current directory4154#.include './john-local.conf'41554156# End of john.conf file.4157# Keep this comment, and blank line above it, to make sure a john-local.conf4158# that does not end with \n is properly loaded.415941604161