diff --git a/bin/install_tool b/bin/install_tool index 1c48574..09e639c 100755 --- a/bin/install_tool +++ b/bin/install_tool @@ -140,6 +140,25 @@ case ${TOOL} in tar zx -C ${DESTDIR} -f /tmp/mitmproxy.tar.gz rm /tmp/mitmproxy.tar.gz ;; + esp) + src="https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz" + download ${src} /tmp/esp32.tar.gz + mkdir -p ${DESTDIR} + tar zx -C ${DESTDIR} -f /tmp/esp32.tar.gz + rm /tmp/esp32.tar.gz + git clone --recursive https://github.com/espressif/esp-idf.git ${DESTDIR}/esp-idf + ;; + dex2jar) + src="https://github.com/pxb1988/dex2jar/releases/download/2.0/dex-tools-2.0.zip" + download ${src} /tmp/dex2jar.zip + tmpd=`mktemp -d` + unzip -d ${tmpd} /tmp/dex2jar.zip + mv ${tmpd}/* ${DESTDIR} + rm /tmp/dex2jar.zip + rm -rf ${tmpd} + rm ${DESTDIR}/*.bat + chmod +x ${DESTDIR}/*.sh + ;; *) echo "Unknown tool: ${TOOL}" >/dev/stderr exit 1 diff --git a/dotfiles/config/i3/config b/dotfiles/config/i3/config index 032b5d0..e9bb7db 100644 --- a/dotfiles/config/i3/config +++ b/dotfiles/config/i3/config @@ -87,6 +87,10 @@ bindsym $mod+Shift+8 move container to workspace 8 bindsym $mod+Shift+9 move container to workspace 9 bindsym $mod+Shift+0 move container to workspace 10 +# Move workspaces between monitors +bindsym $mod+Shift+greater move workspace to output right +bindsym $mod+Shift+less move workspace to output left + # reload the configuration file bindsym $mod+Shift+c reload # restart i3 inplace (preserves your layout/session, can be used to upgrade i3) @@ -126,9 +130,10 @@ bindsym $alt+Control+Left workspace prev # i3 lock exec --no-startup-id ~/bin/i3lock.sh & -bindsym $mod+l exec "i3lock -c 000000 -d && (sleep 2; xset dpms force off) &" +bindsym $mod+l exec \ + bash -c "i3lock -c 000000 -d && (sleep 2 && xset dpms force off) &" bindsym $alt+Control+l exec \ - "i3lock -c 000000 -d && (sleep 2; xset dpms force off) &" + bash -c "i3lock -c 000000 -d && (sleep 2 && xset dpms force off) &" # things to start quickly bindsym $mod+g exec /usr/bin/google-chrome-beta --password-store=gnome @@ -151,15 +156,15 @@ bindsym XF86MonBrightnessDown exec --no-startup-id xbacklight -dec 10 set $scrotformat %F-%T.png set $screendir ~/Pictures/Screenshots # whole screen -bindsym Print exec --no-startup-id \ +bindsym --release Print exec --no-startup-id \ mkdir -p $screendir && \ /usr/bin/scrot $screendir/$scrotformat # current window -bindsym Shift+Print exec --no-startup-id \ +bindsym --release Shift+Print exec --no-startup-id \ mkdir -p $screendir && \ /usr/bin/scrot -u $screendir/$scrotformat # selection -bindsym --release $alt+Print exec --no-startup-id \ +bindsym --release $alt+Sys_Req exec --no-startup-id \ mkdir -p $screendir && \ /usr/bin/scrot -s $screendir/$scrotformat diff --git a/dotfiles/john/john.conf b/dotfiles/john/john.conf index 18fe5fd..7ddf0de 100644 --- a/dotfiles/john/john.conf +++ b/dotfiles/john/john.conf @@ -1,17 +1,509 @@ # # This file is part of John the Ripper password cracker, -# Copyright (c) 1996-2006,2008-2010 by Solar Designer +# Copyright (c) 1996-2006,2008-2013 by Solar Designer +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted. +# +# There's ABSOLUTELY NO WARRANTY, express or implied. +# +# Please note that although this configuration file is under the cut-down BSD +# license above, many source files in John the Ripper are under GPLv2. +# For licensing terms for John the Ripper as a whole, see doc/LICENSE. +# +# ...with changes in the jumbo patch, by various authors # +# The [Options] section is for general options only. +# Note that MPI specific options have been moved +# to [Options.MPI] +# There is also a new section [Options.OpenCL] +# for OpenCL specific options +# Default settings for Markov mode have been moved +# to [Markov.Default], but you can define other +# Markov modes as well, see ../doc/MARKOV [Options] -# Wordlist file name, to be used in batch mode +# Default wordlist file name (including in batch mode) Wordlist = $JOHN/password.lst # Use idle cycles only Idle = Y # Crash recovery file saving delay in seconds -Save = 600 +Save = 60 # Beep when a password is found (who needs this anyway?) Beep = N +# if set to Y then dynamic format will always work with bare hashes. Normally +# dynamic only uses bare hashes if a single dynamic type is selected with +# the -format= (so -format=dynamic_0 would use valid bare hashes). +DynamicAlwaysUseBareHashes = N + +# Default Single mode rules +SingleRules = Single + +# Default batch mode Wordlist rules +BatchModeWordlistRules = Wordlist + +# Default wordlist mode rules when not in batch mode (if any) +# If this is set and you want to run once without rules, use --rules:none +#WordlistRules = Wordlist + +# Default loopback mode rules (if any) +# If this is set and you want to run once without rules, use --rules:none +LoopbackRules = Loopback + +# Default/batch mode Incremental mode +# Warning: changing these might currently break resume on existing sessions +DefaultIncremental = ASCII +#DefaultIncrementalUTF8 = UTF8 +DefaultIncrementalLM = LM_ASCII + +# Time formatting string used in status ETA. +# +# TimeFormat24 is used when ETA is within 24h, so it is possible to omit +# the date then if you like, and show seconds instead. +# +# %c means 'local' specific canonical form, such as: +# 05/06/11 18:10:34 +# +# Other examples +# %d/%m/%y %H:%M (day/mon/year hour:min) +# %m/%d/%y %H:%M (mon/day/year hour:min) +# %Y-%m-%d %H:%M (ISO 8601 style, 2011-05-06 18:10) +TimeFormat = %Y-%m-%d %H:%M +TimeFormat24 = %H:%M:%S + +# +# optional add a date timestamp in front of every logged line. +# the default is no timestamp logging. See the docs for +# strftime for more information: +# http://en.cppreference.com/w/c/chrono/strftime +# +# 2016-02-20T22:35:38+01:00 would be %Y-%m-%dT%H:%M:%S%z +# Feb 20 22:35:38 would be %b %d %H:%M:%S +#LogDateFormat = %Y-%m-%dT%H:%M:%S%z + +# if log date is being used, the time will default to local +# time. But if the next line is uncommented, it will output +# in UTC. Note, if LogDateFormat is not set, this option +# does nothing. +#LogDateFormatUTC = Y + +# if logging to stderr (--log-stderr command line switch used), +# then use date format when outputting to the stderr. +#LogDateStderrFormat = %b %d %H:%M:%S + +# Permissions to set for session.log file +# Default is 0600 +#LogFilePermissions = 0600 + +# Permissions to set for POT file +# Default is 0600 +#PotFilePermissions = 0600 + +# John exits if another user owns log or pot file because CHMOD fails, +# If this is set John prints a warning and continues +# Default is N +#IgnoreChmodErrors = N + +# Set this to N to disable use of memory-mapping in wordlist mode. +WordlistMemoryMap = Y + +# For single mode, load the full GECOS field (before splitting) as one +# additional candidate. Normal behavior is to only load individual words +# from that field. Enabling this can help when this field contains email +# addresses or other strings that are better used unsplit, but it increases +# the number of words tried so it may also slow things down. If enabling this +# you might want to bump SingleWordsPairMax too, below, to 10 or more. +PristineGecos = N + +# For single mode, ignore the login field. +# Normal behavior is to use the login field for single mode. +# Skipping the login field should only be enabled if previous single mode +# sessions did already make use of the login field, but no other information, +# and now you want to use other information, skip the login field, but still +# want the login field to be reported on successful cracks or with --show. +SingleSkipLogin = N + +# Over-ride SINGLE_WORDS_PAIR_MAX in params.h. This may slow down Single mode +# but it may also help cracking a few more candidates. Default in core John +# is 4 while the Jumbo default is 6. This limit is also automatically bumped +# by word seed options --single-seed and/or --single-wordlist if needed. +SingleWordsPairMax = 6 + +# Un-commenting this stops Single mode from re-testing guessed plaintexts +# with all other salts. +#SingleRetestGuessed = N + +# Protect the restore files (*.rec) from being overwritten. The default +# mode is "Disabled". This mode will provide no protection, but has been +# the default mode in JtR forever, so to not change behavior, that mode +# has been kept as default. You can change this to "Named" or "Always" +# If this option is changed to "Named", then any restore file created +# with a --session=xxxx will be protected from being overwritten. If +# the option is set to "Always", then all .rec files will be kept from +# being overwritten, even ${JOHN}/john.rec file +#SessionFileProtect = Named + +# Protect the log files (*.log) from being reused by new sessons. +# The default mode is "Disabled". That means, a nee session will just append +# to an existing log file. +# With "Named", a new session will not be allowed to append to an existing +# log file, except if the --session=NAME option hasn't been used. +# With "Always", not even the default log file ${JOHN}/john.log can be +# reused by a new session. +# (Of course, a restored session will always be allowed to append to an +# existing log file.) +# Unless you use the --nolog option, setting LogFileProtect will also +# prevent overwriting existing session files. +#LogFileProtect = Named + +# Emit a status line whenever a password is cracked (this is the same as +# passing the --crack-status option flag to john). NOTE: if this is set +# to true here, --crack-status will toggle it back to false. +CrackStatus = N + +# When printing status, show number of candidates tried (eg. 123456p). +# This is added to the "+ Cracked" line in the log as well (and that figure +# will be exact while the screen output will be a multiple of batch size). +StatusShowCandidates = N + +# Write cracked passwords to the log file (default is just the user name) +LogCrackedPasswords = N + +# Disable the dupe checking when loading hashes. For testing purposes only! +NoLoaderDupeCheck = N + +# Default encoding for input files (ie. login/GECOS fields) and wordlists +# etc. If this is not set here and --encoding is not used either, the default +# is ISO-8859-1 for Unicode conversions and 7-bit ASCII encoding is assumed +# for rules, e.g., uppercasing of letters other than a-z will not work at all! +DefaultEncoding = UTF-8 + +# Default --target-encoding for Microsoft hashes (LM, NETLM et al) when input +# encoding is UTF-8. CP850 would be a universal choice for covering most +# "Latin-1" countries. +DefaultMSCodepage = CP850 + +# Default internal legacy codepage to be used by mask mode and within the +# rules engine, when both input and target encodings are Unicode (eg. UTF-8 +# wordlist and NT hashes). In some cases this hits performance but lets us +# do things like Unicode case conversions. You can pick any supported +# legacy codepage that has as much support for the input data as possible, +# e.g., for "Latin-1" language passwords you can use ISO-8859-1, CP850 or +# CP1252 and it will hardly make any difference but in some cases, ISO-8859-1 +# is faster. Using "UTF-8" (which is not a legacy codepage!) will disable. +# +# The default is to NOT use any internal codepage. +#DefaultInternalCodepage = ISO-8859-1 + +# Warn if seeing UTF-8 when expecting some other encoding, or vice versa. +# This is disabled for ASCII or RAW encodings, for performance. +WarnEncoding = Y + +# Always report (to screen and log) cracked passwords as UTF-8, regardless of +# input encoding. This is recommended if you have your terminal set for UTF-8. +AlwaysReportUTF8 = Y + +# Always store Unicode (UTF-16) passwords as UTF-8 in john.pot, regardless +# of input encoding. This prevents john.pot from being filled with mixed +# and eventually unknown encodings. This is recommended if you have your +# terminal set for UTF-8 and/or you want to run --loopback for LM->NT +# including non-ASCII. +UnicodeStoreUTF8 = Y + +# Always report/store non-Unicode formats as UTF-8, regardless of input +# encoding. Note: The actual codepage that was used is not stored anywhere +# except in the log file. +# This is needed e.g. for --loopback to crack LM->NT including non-ASCII. +CPstoreUTF8 = Y + +# Default verbosity is 3, valid figures are 1-5 right now. +# 4-5 enables some extra output and diagnostics. +# 4 is same verbosity as "john proper" aka. non-jumbo. +# 3 mutes rules & incremental output in logs (LOTS of lines). +# 2 mutes some other diagnostics. +# 1 even mutes printing (to screen) of cracked passwords. +Verbosity = 3 + +# If set to Y, do not output, log or store cracked passwords verbatim. +# This implies a different default .pot database file "secure.pot" instead +# of "john.pot" but it can still be overridden using --pot=FILE. +# This also overrides other options, e.g. LogCrackedPasswords. +SecureMode = N + +# If set to Y, a session using --fork or MPI will signal to other nodes when +# it has written cracks to the pot file, so they will re-sync. Note that this +# may be delayed by buffers and the "Save" timer setting near top of this file. +ReloadAtCrack = N + +# If set to Y, a session using --fork or MPI will signal to other nodes when +# it has cracked all hashes (there's nothing more to do!). This is ignored +# when ReloadAtCrack = Y because it's redundant. +ReloadAtDone = Y + +# If set to Y, resync pot file when saving session. This does not involve any +# signalling, we just detect that someone else wrote to the pot file. +# This will sync with concurrent sessions even when not using --fork or MPI +# but it may be delayed by the "Save" timer setting near top of this file. +ReloadAtSave = Y + +# If this file exists, john will abort cleanly +AbortFile = /var/run/john/abort + +# While this file exists, john will pause +PauseFile = /var/run/john/pause + +# If set to true, the uid will be appended to user name on cracks +# With: password123 (Administrator:500) +# Without password123 (Administrator) +# This is disabled by --save-memory. +ShowUIDinCracks = N + +# This sets the "grace time" for --max-run-time=N. If john has not finished +# this long after the initial abort signal, it will send another one (similar +# to pressing ctrl-c a second time) which will stop john immediately and not +# wait further for an optimal resume point. +# Setting this to 0 means NO grace time - immediately abort. Setting it to +# a negative number means UNLIMITED grace time - never hard abort. +AbortGraceTime = 30 + +# This allows you to list a few words/names that will be used by single mode +# as if they were included in every GECOS field. Use sparingly! Please note +# that the example words are commented out, so the list is empty! +[List.Single:SeedWords] +#Pass +#Secret +#Test + +# This allows you to read extra pot files when loading hashes. Nothing will +# ever be written to these files, they are just read. Any directory in this +# list will be traversed and files in it with an extension of .pot will be +# read. However there will NOT be any recursion down further directory levels. +# Any entries that don't exist will be silently ignored. +[List.Extra:Potfiles] +#somefile.pot +#somedirectory +#$JOHN/my.pot + +[Options:MPI] +# Automagically disable OMP if MPI is used (set to N if +# you want to run one MPI process per multi-core host) +MPIOMPmutex = Y + +# Print a notice if disabling OMP (when MPIOMPmutex = Y) +# or when running OMP and MPI at the same time +MPIOMPverbose = Y + + +# These formats are disabled from all-formats --test runs, or auto-selection +# of format from an input file. Even when disabled, you can use them as long +# as you spell them out with the --format option. Or you can delete a line, +# comment it out, or change to 'N' +[Disabled:Formats] +#formatname = Y +.include '$JOHN/dynamic_disabled.conf' + +# Options that may affect both GPUs and other accelerators (eg. FPGA) +[Options:GPU] +# Show GPU temperature, fan and utilization along with normal status output +SensorsStatus = Y + +# If SensorsStatus is true, individual ones can be turned off +TempStatus = Y +UtilStatus = N +FanStatus = N + +# Abort session if GPU hits this temperature (in C) +AbortTemperature = 95 + + +[Options:OpenCL] +# Set default OpenCL device. Command line option will override this. +# If not set, we will search for a GPU or fall-back to the most +# powerful device. +#Device = 0 + +# Global max. single kernel invocation duration, in ms. Setting this low +# (eg. 10-100 ms) gives you a better responding desktop but lower performance. +# Setting it high (eg. 200-500 ms) will maximize performance but your desktop +# may lag. Really high values may trip watchdogs (eg. 5 seconds). Some versions +# of AMD Catalyst may hang if you go above 200 ms, and in general any good +# kernel will perform optimally at 100-200 ms anyway. +#Global_MaxDuration = 200 + +# Some formats vectorize their kernels in case the device says it's a good +# idea. Some devices give "improper" hints which means we vectorize but get +# a performance drop. If you have such a device, uncommenting the below +# will disable vectorizing globally. +# With this set to N (or commented out) you can force it per session with +# the --force-scalar command-line option instead. +#ForceScalar = Y + +# Global build options. Format-specific build options below may be +# concatenated to this. +GlobalBuildOpts = -cl-mad-enable + +# Initial local work-size for auto-tune (CPU devices excepted). +# 0 means let the OpenCL implementation pick a suitable value. +# 1 means query for "best multiple" (usually corresponds to "warp size"). +# Any other value (eg. 64) will be taken verbatim. +AutotuneLWS = 1 + +# Format-specific settings: + +# Uncomment the below for nvidia sm_30 and beyond. +# Please, check if it is really better. +#sha512crypt_BuildOpts = -cl-nv-maxrregcount=80 + +# Best configuration value to be used at runtime. +sha512crypt_Bonaire = -DUNROLL_LOOP=132104 + +# Example: Override auto-tune for RAR format. +#rar_LWS = 128 +#rar_GWS = 8192 + +[List.OpenCL:Drivers] +#Driver ; Description ; Recommendation +#AMD driver versions +938 , 2 ; 12.8 ; +1084, 4 ; 13.1 ; +1124, 2 ; 13.4 ; +1214, 3 ; 13.6 beta ; +1311, 2 ; 13.11 beta-1 ; +1348, 5 ; 13.12 ; +1445, 5 ; 14.4 (Mantle) ; +1526, 3 ; 14.6 beta (Mantle) ; +1573, 4 ; 14.9 (Mantle) ; VGL S +1642, 5 ; 14.12 (Omega) ; VGL S +1702, 3 ; 15.5 beta ; T +1729, 3 ; 15.5 ; +1800, 5 ; 15.7 ; VG* R +1800, 8 ; 15.7.1 ; VGW R +1800, 11; 15.9 ; VGL S +1912, 5 ; 15.12 ; +#NVIDIA driver versions +346, 0 ; ; N* R +319, 0 ; ; N* S +#End +0, 0 ; ; + +#Labels +# * -> all OS +# N -> NVIDIA +# G -> GCN +# V -> VLIW4 and VLIW5 +# W -> Windows +# L -> Linux +# R -> recommended +# S -> supported +# T -> not recommended: really bad software. I mean "trash". + +[PRINCE] +# Default wordlist file name. Will fall back to standard wordlist if not +# defined. +#Wordlist = $JOHN/password.lst + + +# Markov modes, see ../doc/MARKOV for more information +[Markov:Default] +# Default Markov mode settings +# +# Statsfile cannot be specified on the command line, so +# specifying it here is mandatory +Statsfile = $JOHN/stats +# MkvLvl and MkvMaxLen should also be specified here, as a fallback for +# --markov usage without specifying LEVEL and/or --max-length on the +# command line. +MkvLvl = 200 +MkvMaxLen = 12 +# MkvMinLvl and MkvMinLen should not be specified at all in [Markov:Default], +# or they should be equal to 0 (which is the default if not specified. +# MkvMinLvl and MkvMinLen can be used in other Markov mode sections +# except [Markov:Default] +; MkvMinLvl = 0 +; MkvMinLen = 0 + +# A user defined character class is named with a single digit, ie. 0..9. After +# the equal-sign, just list all characters that this class should match. You +# can specify ranges within brackets, much like pre-processor ranges in rules. +# BEWARE of encoding if using non-ASCII characters. If you put UTF-8 characters +# here, it will *not* work! You must use a singlebyte encoding and it should +# be the same here as you intend to use for your dictionary. +# You can however put characters here in \xA3 format (for codepoint 0xA3 - in +# many iso-8859 codepages that would mean a pound sign). This works in ranges +# too. Using \x00 is not supported though - it will not be parsed as null. +# +# This is a couple of example classes: +# ?0 matches (one version of) base64 characters +# ?1 matches hex digits +# ?2 matches the TAB character (never try to use \x00!) +[UserClasses] +0 = [a-zA-Z0-9/.] +1 = [0-9a-fA-F] +2 = \x09 + +[Mask] +# When iterating over length, emit a status line after each length is done +MaskLengthIterStatus = Y + +# Default mask for -mask if none is given. This is same as hashcat's default. +DefaultMask = ?1?2?2?2?2?2?2?3?3?3?3?d?d?d?d + +# Default mask for Hybrid mask mode if none is given. +DefaultHybridMask = ?w?d?d?d?d + +# Mask mode have custom placeholders ?1..?9 that look similar to user classes +# but are a different thing. They are merely defaults for the -1..-9 command +# line options. As delivered, they resemble hashcat's defaults. +1 = ?l?d?u +2 = ?l?d +3 = ?l?d*!$@_ +4 = +5 = +6 = +7 = +8 = +9 = + +# these are user defined character sets. There purpose is to allow custom salt +# values to be used within the salt_regen logic. These will be the characters +# to use for this character within the salt. So if we had a salt that was 4 +# characters, and 0-9a-m, we can easily do this by 0 = [0-9a-m] If this is used, +# the regen salt value would be ?0?0?0?0 and salts such as a47m 2kd5 would be valid. +[Regen_Salts_UserClasses] +1 = [1-9] + +# A "no rules" rule for super fast Single mode (use with --single=none) +[List.Rules:None] +: + +# A "drop all" rule for even faster Single mode (debugging :) +[List.Rules:Drop] +<1'0 + +# These are good rules on larger sites where a user ID may already be used, +# so a user simply appends numbers to create his loginID, but then uses the +# login name he wanted as basis for password. Just strip off digits and treat +# the base-word to some manipulation. These rules found from the 2015 A-M +# leak. Only adds 30-50 permutations and only applied to user names that have +# digits contained within them, and cracks quite a few. +# These are currently Jumbo-specific. +[List.Rules:JumboSingle] +/?d @?d >4 +/?d @?d M @?A Q >4 +/?d @?d >4 M [lc] Q +/?d @?d M @?A Q >4 M [lc] Q +@?D Q >4 +/?d @?d >3 <* $[0-9] Q +/?d @?d M >3 <* [lc] Q $[0-9] Q +/?d @?d >3 <- Az"12" Q +/?d @?d M >3 <- [lc] Q Az"12" +/?d @?d >3 Az"123" Q <+ +/?d @?d M >3 [lc] Q Az"123" <+ +/?d @?d >2 d Q <+ +/?d @?d >2 M [lc] Q d<+ +(?a )?d /?d 'p Xpz0 +)?a (?d /?a 'p Xpz0 + # "Single crack" mode rules [List.Rules:Single] @@ -23,27 +515,31 @@ Beep = N -s-c x** /?u l # These were not included in crackers I've seen, but are pretty efficient, # so I include them near the beginning ->6 '6 ->7 '7 l --c >6 '6 /?u l ->5 '5 +-<6 >6 '6 +-<7 >7 '7 l +-<6 -c >6 '6 /?u l +-<5 >5 '5 + +# Wedge the Jumbo-specific addons in here! +.include [List.Rules:JumboSingle] + # Weird order, eh? Can't do anything about it, the order is based on the # number of successful cracks... <* d r c -c <* (?a d c --c >5 '5 /?u l +-<5 -c >5 '5 /?u l -c u Q -c )?a r l -[:c] <* !?A \p1[lc] p -c <* c Q d --c >7 '7 /?u ->4 '4 l +-<7 -c >7 '7 /?u +-<4 >4 '4 l -c <+ (?l c r -c <+ )?l l Tm ->3 '3 --c >4 '4 /?u --c >3 '3 /?u l +-<3 >3 '3 +-<4 -c >4 '4 /?u +-<3 -c >3 '3 /?u l -c u Q r <* d M 'l f Q -c <* l Q d M 'l f Q @@ -169,35 +665,42 @@ l Q [RL] # The rest of two-digit suffix stuff, less common numbers... <- l Az"[63-5][0-9]" -c <- (?a c Az"[63-5][0-9]" -# Some three-digit numbers... +# Some multi-digit numbers... -[:c] (?a \p1[lc] Az"007" <+ -[:c] (?a \p1[lc] Az"123" <+ --[:c] (?a \p1[lc] Az"[1-9]\0\0" <+ +-[:c] (?a \p1[lc] Az"[0-9]\0\0" <+ +-[:c] (?a \p1[lc] Az"1234" <+ +-[:c] (?a \p1[lc] Az"[0-9]\0\0\0" <+ +-[:c] (?a \p1[lc] Az"12345" <+ +-[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0" <+ +-[:c] (?a \p1[lc] Az"123456" <+ +-[:c] (?a \p1[lc] Az"[0-9]\0\0\0\0\0" <+ # Some [birth] years... l Az"19[7-96-0]" <+ >- l Az"20[01]" <+ >- l Az"19[7-9][0-9]" <+ l Az"20[01][0-9]" <+ l Az"19[6-0][9-0]" <+ -# Uncomment the following lines if you're really crazy -;# Insert/overstrike some characters... -;!?A >[1-6] l i\0[a-z] -;!?A l o0[a-z] -;!?A >[1-7] l o\0[a-z] -;# Toggle case everywhere (up to length 8), assuming that certain case -;# combinations were already tried. -;-c T1 Q M T0 Q -;-c T2 Q M T[z0] T[z1] Q -;-c T3 Q M T[z0] T[z1] T[z2] Q -;-c T4 Q M T[z0] T[z1] T[z2] T[z3] Q -;-c T5 Q M T[z0] T[z1] T[z2] T[z3] T[z4] Q -;-c T6 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] Q -;-c T7 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] T[z6] Q -;# Very slow stuff... -;l Az"[1-90][0-9][0-9]" <+ -;-c (?a c Az"[1-90][0-9][0-9]" <+ -;<[\-9] l A\p[z0]"[a-z][a-z]" -;<- l ^[a-z] $[a-z] + +[List.Rules:Extra] +# Insert/overstrike some characters... +!?A >[1-6] l i\0[a-z] +!?A l o0[a-z] +!?A >[1-7] l o\0[a-z] +# Toggle case everywhere (up to length 8), assuming that certain case +# combinations were already tried. +-c T1 Q M T0 Q +-c T2 Q M T[z0] T[z1] Q +-c T3 Q M T[z0] T[z1] T[z2] Q +-c T4 Q M T[z0] T[z1] T[z2] T[z3] Q +-c T5 Q M T[z0] T[z1] T[z2] T[z3] T[z4] Q +-c T6 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] Q +-c T7 Q M T[z0] T[z1] T[z2] T[z3] T[z4] T[z5] T[z6] Q +# Very slow stuff... +l Az"[1-90][0-9][0-9]" <+ +-c (?a c Az"[1-90][0-9][0-9]" <+ +<[\-9] l A\p[z0]"[a-z][a-z]" +<- l ^[a-z] $[a-z] # Wordlist mode rules [List.Rules:Wordlist] @@ -256,7 +759,7 @@ l Az"19[6-0][9-0]" <+ # Case toggler for cracking MD4-based NTLM hashes (with the contributed patch) # given already cracked DES-based LM hashes. -# Rename this section to [List.Rules:Wordlist] to activate it. +# Use --rules=NT to use this [List.Rules:NT] : -c T0Q @@ -274,64 +777,236 @@ l Az"19[6-0][9-0]" <+ -c TCQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]T[zB] -c 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] +# Used for loopback. This rule will produce candidates "PASSWOR" and "D" for +# an input of "PASSWORD" (assuming LM, which has halves of length 7). +[List.Rules:Split] +: +-s x** + +# Some Office <=2003 files have passwords truncated at 15 +[List.Rules:OldOffice] +: +->F>F'F + +# Rules from Hash Runner 2014 +[List.Rules:o1] +o[0-9A-Z][ -~] + +[List.Rules:o2] +o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q + +[List.Rules:o3] +o[0-9][ -~] Q M o[0-9][ -~] Q M o[0-9][ -~] Q + +[List.Rules:o] +o[0-9A-Z][ -~] +o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q + +[List.Rules:i1] +i[0-9A-Z][ -~] + +[List.Rules:i2] +i[0-9A-E][ -~] i[0-9A-E][ -~] + +[List.Rules:i3] +i[0-9][ -~] i[0-9][ -~] i[0-9][ -~] + +[List.Rules:i] +i[0-9A-Z][ -~] +i[0-9A-E][ -~] i[0-9A-E][ -~] + +[List.Rules:oi] +o[0-9A-Z][ -~] +i[0-9A-Z][ -~] +o[0-9A-E][ -~] Q M o[0-9A-E][ -~] Q +i[0-9A-E][ -~] i[0-9A-E][ -~] + +# Default Loopback mode rules. +[List.Rules:Loopback] +.include [List.Rules:NT] +.include [List.Rules:Split] + +# For Single Mode against fast hashes +[List.Rules:Single-Extra] +.include [List.Rules:Single] +.include [List.Rules:Extra] +.include [List.Rules:OldOffice] + +# For Wordlist mode and very fast hashes +[List.Rules:Jumbo] +.include [List.Rules:Wordlist] +.include [List.Rules:Single] +.include [List.Rules:Extra] +.include [List.Rules:NT] +.include [List.Rules:OldOffice] + +# "Best64" rules +.include + +# KoreLogic rules +.include + +# Everything, including all KoreLogic rules. Only for very fast hashes +# and/or Single mode. +[List.Rules:All] +.include [List.Rules:Jumbo] +.include [List.Rules:best64] +.include [List.Rules:KoreLogic] + # Incremental modes -[Incremental:All] -File = $JOHN/all.chr + +# This is for one-off uses (make your own custom.chr) +[Incremental:Custom] +File = $JOHN/custom.chr MinLen = 0 -MaxLen = 8 + +# The theoretical CharCount is 211, we've got 196. +[Incremental:UTF8] +File = $JOHN/utf8.chr +MinLen = 0 +CharCount = 196 + +# This is CP1252, a super-set of ISO-8859-1. +# The theoretical CharCount is 219, we've got 203. +[Incremental:Latin1] +File = $JOHN/latin1.chr +MinLen = 0 +CharCount = 203 + +[Incremental:ASCII] +File = $JOHN/ascii.chr +MinLen = 0 +MaxLen = 13 CharCount = 95 +[Incremental:LM_ASCII] +File = $JOHN/lm_ascii.chr +MinLen = 0 +MaxLen = 7 +CharCount = 69 + +# This is CP858 (CP850 + Euro sign, superset of CP437). +# The theoretical CharCount is 209 minus lowercase, we've got 132. +[Incremental:LanMan] +File = $JOHN/lanman.chr +MinLen = 0 +MaxLen = 7 +CharCount = 132 + +# This is alnum (upper & lower case) as well as space. +[Incremental:Alnumspace] +File = $JOHN/alnumspace.chr +MinLen = 1 +MaxLen = 13 +CharCount = 63 + +[Incremental:Alnum] +File = $JOHN/alnum.chr +MinLen = 1 +MaxLen = 13 +CharCount = 62 + [Incremental:Alpha] File = $JOHN/alpha.chr MinLen = 1 -MaxLen = 8 +MaxLen = 13 +CharCount = 52 + +[Incremental:LowerNum] +File = $JOHN/lowernum.chr +MinLen = 1 +MaxLen = 13 +CharCount = 36 + +[Incremental:UpperNum] +File = $JOHN/uppernum.chr +MinLen = 1 +MaxLen = 13 +CharCount = 36 + +[Incremental:LowerSpace] +File = $JOHN/lowerspace.chr +MinLen = 1 +MaxLen = 13 +CharCount = 27 + +[Incremental:Lower] +File = $JOHN/lower.chr +MinLen = 1 +MaxLen = 13 +CharCount = 26 + +[Incremental:Upper] +File = $JOHN/upper.chr +MinLen = 1 +MaxLen = 13 CharCount = 26 [Incremental:Digits] File = $JOHN/digits.chr MinLen = 1 -MaxLen = 8 +MaxLen = 20 CharCount = 10 -[Incremental:Alnum] -File = $JOHN/alnum.chr -MinLen = 1 -MaxLen = 8 -CharCount = 36 - -[Incremental:LanMan] -File = $JOHN/lanman.chr -MinLen = 0 -MaxLen = 7 -CharCount = 69 - -[Incremental:All5] -File = $JOHN/ascii.chr -MinLen = 5 -MaxLen = 5 -CharCount = 95 - -# Some pre-defined word filters -[List.External:Filter_Alpha] +# Some pre-defined word filters as used to generate the supplied .chr files +[List.External:Filter_ASCII] void filter() { int i, c; i = 0; while (c = word[i++]) - if (c < 'a' || c > 'z') { + if (c < 0x20 || c > 0x7e || i > 13) { word = 0; return; } } -[List.External:Filter_Digits] +[List.External:Filter_LanMan] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i]) { + if (i >= 14) { // of up to 14 characters long + word = 0; return; + } + if (c >= 'a' && c <= 'z') // Convert to uppercase + word[i] &= 0xDF; + i++; + } + + word[7] = 0; // Truncate at 7 characters +} + +[List.External:Filter_LM_ASCII] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i]) { + if (c < 0x20 || c > 0x7e || // Require ASCII-only + i >= 14) { // of up to 14 characters long + word = 0; return; + } + if (c >= 'a' && c <= 'z') // Convert to uppercase + word[i] &= 0xDF; + i++; + } + + word[7] = 0; // Truncate at 7 characters +} + +[List.External:Filter_Alnumspace] void filter() { int i, c; i = 0; while (c = word[i++]) - if (c < '0' || c > '9') { + if (c != ' ' && (((c < '0' || c > '9') && + ((c &= 0xDF) < 'A' || c > 'Z'))) || i > 13) { word = 0; return; } } @@ -343,33 +1018,219 @@ void filter() i = 0; while (c = word[i++]) - if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) { + if (((c < '0' || c > '9') && ((c &= 0xDF) < 'A' || c > 'Z')) || + i > 13) { word = 0; return; } } -[List.External:Filter_LanMan] +[List.External:Filter_Alpha] void filter() { int i, c; - word[7] = 0; // Truncate at 7 characters - - i = 0; // Convert to uppercase - while (c = word[i]) { - if (c >= 'a' && c <= 'z') word[i] &= 0xDF; - i++; + i = 0; + while (c = word[i++]) + if ((c &= 0xDF) < 'A' || c > 'Z' || i > 13) { + word = 0; return; } } +[List.External:Filter_LowerNum] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if (((c < 'a' || c > 'z') && (c < '0' || c > '9')) || i > 13) { + word = 0; return; + } +} + +[List.External:Filter_UpperNum] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if (((c < 'A' || c > 'Z') && (c < '0' || c > '9')) || i > 13) { + word = 0; return; + } +} + +[List.External:Filter_LowerSpace] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if (((c < 'a' || c > 'z') && c != ' ') || i > 13) { + word = 0; return; + } +} + +[List.External:Filter_Lower] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if (c < 'a' || c > 'z' || i > 13) { + word = 0; return; + } +} + +[List.External:Filter_Upper] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if (c < 'A' || c > 'Z' || i > 13) { + word = 0; return; + } +} + +[List.External:Filter_Digits] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if (c < '0' || c > '9' || i > 20) { + word = 0; return; + } +} + +[List.External:Filter_No_Cap_or_Symbols] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) { + return; + } + word = 0; return; +} + + +# Reject words that are illegal UTF-8 +# We obviously let pure ASCII through too +[List.External:Filter_UTF8] +void filter() +{ + int s, a, p; + + p = 0; + while (s = word[p++] & 0xff) { + if (s > 0x7f) { + if (s < 0xc2 || s > 0xf7) { // illegal single-byte + word = 0; return; + } + // two-byte c2..df + a = word[p++] & 0xff; + if (a < 0x80 || a > 0xbf) { + word = 0; return; + } + if (s > 0xdf) { // three-byte e0..ef + if (s == 0xe0 && a < 0xa0) { + word = 0; return; + } + if (s == 0xed && a > 0x9f) { + word = 0; return; + } + if (s == 0xf0 && a < 0x90) { + word = 0; return; + } + if (s == 0xf4 && a > 0x8f) { + word = 0; return; + } + a = word[p++] & 0xff; + if (a < 0x80 || a > 0xbf) { + word = 0; return; + } + if (s > 0xef) { // four-byte f0..f7 + a = word[p++] & 0xff; + if (a < 0x80 || a > 0xbf) { + word = 0; return; + } + } + } + } + } +} + +# Reject words that are LEGAL UTF-8 (also rejects pure ASCII) +[List.External:Filter_non-UTF8] +void filter() +{ + int s, a, p; + + p = 0; + while (s = word[p++] & 0xff) { + if (s > 0x7f) { + if (s < 0xc2 || s > 0xf7) { // illegal single-byte + return; + } + // two-byte c2..df + a = word[p++] & 0xff; + if (a < 0x80 || a > 0xbf) { + return; + } + if (s > 0xdf) { // three-byte e0..ef + if (s == 0xe0 && a < 0xa0) { + return; + } + if (s == 0xed && a > 0x9f) { + return; + } + if (s == 0xf0 && a < 0x90) { + return; + } + if (s == 0xf4 && a > 0x8f) { + return; + } + a = word[p++] & 0xff; + if (a < 0x80 || a > 0xbf) { + return; + } + if (s > 0xef) { // four-byte f0..f7 + a = word[p++] & 0xff; + if (a < 0x80 || a > 0xbf) { + return; + } + } + } + } + } + word = 0; +} + # A simple cracker for LM hashes [List.External:LanMan] int length; // Current length +int maxlength; void init() { + if (req_minlen) + length = req_minlen; + else + length = 1; + if (req_maxlen) + maxlength = req_maxlen; + else // the format's limit + maxlength = cipher_limit; word[0] = 'A' - 1; // Start with "A" - word[length = 1] = 0; + word[length] = 0; } void generate() @@ -381,7 +1242,8 @@ void generate() if (i) // Overflow here, any more positions? word[i--] = 'A'; // Yes, move to the left, and repeat else // No - if (length < 7) { + + if (length < maxlength) { word[i = ++length] = 0; // Switch to the next length while (i--) word[i] = 'A'; @@ -398,7 +1260,10 @@ void restore() } # Simple and well-commented, yet useful external mode example -[List.External:Double] +# NOTE, this has now been 'split' up into a base extern, 'base', and then +# multiple External:double functions. It still has same code as original +# double, but now can be easily expanded. +[List.External_base:Double] /* * This cracking mode tries all the possible duplicated lowercase alphabetic * "words" of up to 8 characters long. Since word halves are the same, it @@ -406,16 +1271,20 @@ void restore() */ /* Global variables: current length and word */ -int length, current[9]; +/* make this 'long' enough for other externs that include this one */ +/* (up to 125 bytes long) */ -/* Called at startup to initialize the global variables */ -void init() -{ - int i; +int length, current[126], max; - i = length = 2; // Start with 4 character long words - while (i--) current[i] = 'a'; // Set our half-word to "aa" -} +/* this new 'type' variable, is used to tell double what character set to + * use. It can use the original (alpha). If type is 0 (i.e. unset), then + * a-z (alpha) character set is used. If type is '0' (a zero ascii byte) + * then alnum charset is used, a-z0-9. If type is a space char, then all + * charset is used [space - tilde] or [ -~]. This required setting the + * type var in the init() of alnum or all doubles (it can be left unset + * in the alpha versions). It also requires some if logic in generate. + * other than that, it works the same, with almost no performance hit */ +int type; /* Generates a new word */ void generate() @@ -429,19 +1298,48 @@ void generate() /* Generate a new word */ i = length - 1; // Start from the last character - while (++current[i] > 'z') // Try to increase it - if (i) // Overflow here, any more positions? - current[i--] = 'a'; // Yes, move to the left, and repeat - else { // No - current = 0; // Request a length switch - break; // Break out of the loop + if (type == 0) { + /* alpha */ + while (++current[i] > 'z') // Try to increase it + if (i) // Overflow here, any more positions? + current[i--] = 'a'; // Yes, move to the left, and repeat + else { // No + current = 0; // Request a length switch + break; // Break out of the loop + } + } else if (type == '0') { + /* alnum */ + if (current[i] == 'z') current[i] = '0'-1; + while (++current[i] == '9') { // Try to increase it + if (i) // Overflow here, any more positions? + current[i--] = 'a'; // Yes, move to the left, and repeat + else { // No + current = 0; // Request a length switch + break; // Break out of the loop + } + if (current[i] == 'z') current[i] = '0'-1; + } + } else if (type == ' ') { + /* all */ + while (++current[i] > '~') { // Try to increase it + if (i) // Overflow here, any more positions? + current[i--] = ' '; // Yes, move to the left, and repeat + else { // No + current = 0; // Request a length switch + break; // Break out of the loop + } + } } + /* else ????? wtf?? */ /* Switch to the next length, unless we were generating 8 character long * words already. */ - if (!current && length < 4) { + if (!current && length < max) { i = ++length; - while (i--) current[i] = 'a'; + if (type == 0 || type == '0') + while (i--) current[i] = 'a'; + else if (type == ' ') + while (i--) current[i] = ' '; } } @@ -458,30 +1356,72 @@ void restore() length = i >> 1; } -# Trivial parallel processing example -[List.External:Parallel] -/* - * This word filter makes John process some of the words only, for running - * multiple instances on different CPUs. It can be used with any cracking - * mode except for "single crack". Note: this is not a good solution, but - * is just an example of what can be done with word filters. - */ - -int node, total; // This node's number, and node count -int number; // Current word number +[List.External:Double] +.include [List.External_base:Double] +/* Called at startup to initialize the global variables */ void init() { - node = 1; total = 2; // Node 1 of 2, change as appropriate - number = node - 1; // Speedup the filter a bit + int i; + + if (req_minlen) + i = length = (req_minlen + 1) / 2; + else + i = length = 2; // Start with 4 character long words + while (i--) current[i] = 'a'; // Set our half-word to "aa" + if (req_maxlen) + max = (req_maxlen + 1) / 2; + else if (length > 4) + max = length; + else + max = 4; } -void filter() +[List.External:Double_alnum] +.include [List.External_base:Double] + +/* Called at startup to initialize the global variables */ +void init() { - if (number++ % total) // Word for a different node? - word = 0; // Yes, skip it + int i; + + if (req_minlen) + i = length = (req_minlen + 1) / 2; + else + i = length = 2; // Start with 4 character long words + while (i--) current[i] = 'a'; // Set our half-word to "aa" + if (req_maxlen) + max = (req_maxlen + 1) / 2; + else if (length > 4) + max = length; + else + max = 4; + + type = '0'; } +[List.External:Double_all] +.include [List.External_base:Double] +void init() +{ + int i; + + if (req_minlen) + i = length = (req_minlen + 1) / 2; + else + i = length = 2; // Start with 4 character long words + while (i--) current[i] = ' '; // Set our half-word to " " + if (req_maxlen) + max = (req_maxlen + 1) / 2; + else if (length > 4) + max = length; + else + max = 4; + + type = ' '; +} + + # Strip 0.5 ("Secure Tool for Recalling Important Passwords") cracker, # based on analysis done by Thomas Roessler and Ian Goldberg. This will # crack passwords you may have generated with Strip; other uses of Strip @@ -497,8 +1437,14 @@ void init() /* Password lengths to try; Strip can generate passwords of 4 to 16 * characters, but traditional crypt(3) hashes are limited to 8. */ - minlength = 4; // 4 - maxlength = 8; // 16 + minlength = req_minlen; + if (minlength < 4) + minlength = 4; + if (req_maxlen) + maxlength = req_maxlen; + else // the format's limit + maxlength = cipher_limit; + if (maxlength >16) maxlength = 16; /* Password types to try (Numeric, Alpha-Num, Alpha-Num w/ Meta). */ mintype = 0; // 0 @@ -558,12 +1504,539 @@ void generate() word[i] = 0; } +# A variation of KnownForce configured to try all the 385641000 possible +# auto-generated passwords of DokuWiki versions up to at least 2013-05-10. +[List.External:DokuWiki] +int last; // Last character position, zero-based +int lastofs; // Last character position offset into charset[] +int lastid; // Current character index in the last position +int id[0x7f]; // Current character indices for other positions +int charset[0x7f00]; // Character sets, 0x100 elements for each position + +void init() +{ + int A[26], C[26], V[26]; + int length; + int pos, ofs, i, c; + + i = 0; while (i < 26) { A[i] = C[i] = 1; V[i++] = 0; } + i = 'a' - 'a'; C[i] = 0; V[i] = 1; + i = 'e' - 'a'; C[i] = 0; V[i] = 1; + i = 'i' - 'a'; C[i] = 0; V[i] = 1; + i = 'o' - 'a'; C[i] = 0; V[i] = 1; + i = 'u' - 'a'; C[i] = 0; V[i] = 1; + i = 'q' - 'a'; A[i] = C[i] = 0; + i = 'x' - 'a'; A[i] = C[i] = 0; + i = 'y' - 'a'; A[i] = C[i] = 0; + + length = 8; + +/* This defines the character sets for different character positions */ + pos = 0; + while (pos < 6) { + ofs = pos++ << 8; + i = 0; + c = 'a' - 1; + while (++c <= 'z') + if (C[c - 'a']) + charset[ofs + i++] = c; + charset[ofs + i] = 0; + ofs = pos++ << 8; + i = 0; + c = 'a' - 1; + while (++c <= 'z') + if (V[c - 'a']) + charset[ofs + i++] = c; + charset[ofs + i] = 0; + ofs = pos++ << 8; + i = 0; + c = 'a' - 1; + while (++c <= 'z') + if (A[c - 'a']) + charset[ofs + i++] = c; + charset[ofs + i] = 0; + } + c = '1'; + while (pos < length) { + ofs = pos++ << 8; + i = 0; + while (c <= '9') + charset[ofs + i++] = c++; + charset[ofs + i] = 0; + c = '0'; + } + + last = length - 1; + pos = -1; + while (++pos <= last) + word[pos] = charset[id[pos] = pos << 8]; + lastid = (lastofs = last << 8) - 1; + word[pos] = 0; +} + +void generate() +{ + int pos; + +/* Handle the typical case specially */ + if (word[last] = charset[++lastid]) return; + + word[pos = last] = charset[lastid = lastofs]; + while (pos--) { // Have a preceding position? + if (word[pos] = charset[++id[pos]]) return; + word[pos] = charset[id[pos] = pos << 8]; + } + + word = 0; // We're done +} + +void restore() +{ + int i, c; + +/* Calculate the current length and infer the character indices */ + last = 0; + while (c = word[last]) { + i = lastofs = last << 8; + while (charset[i] != c && charset[i]) i++; + if (!charset[i]) i = lastofs; // Not found + id[last++] = i; + } + lastid = id[--last]; +} + +/* + * This takes advantage of CVE-2013-2120 to find seeds that KDE Paste applet + * uses to generate passwords. + * + * This software is Copyright (c) Michael Samuel , + * and it is hereby released to the general public under the following terms: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + */ +[List.External:KDEPaste] +int charset[95]; +int charset_length, password_length, endTime, startTime, msec; + +void init() +{ + password_length = 8; /* Change this to match config */ + endTime = session_start_time; + startTime = 1343743200; /* Aug 1 2012 - Change this as necessary */ + + msec = 1; /* msec is never 0 - it would crash the applet */ + + charset_length = 0; + int c; + + /* Comment out classes that you don't need, but keep the order the same */ + /* Lowers */ + c = 'a'; while (c <= 'z') charset[charset_length++] = c++; + + /* Uppers */ + c = 'A'; while (c <= 'Z') charset[charset_length++] = c++; + + /* Numbers */ + c = '0'; while (c <= '9') charset[charset_length++] = c++; + charset[charset_length++] = '0'; /* Yep, it's there twice */ + + /* Symbols */ + c = '!'; while (c <= '/') charset[charset_length++] = c++; + c = ':'; while (c <= '@') charset[charset_length++] = c++; + c = '['; while (c <= '`') charset[charset_length++] = c++; + c = '{'; while (c <= '~') charset[charset_length++] = c++; +} + +void generate() +{ + int i, rand_seed, rand_result; + + /* Terminate once we've generated for all * + * of the time range (Plus a bit more...) */ + if (endTime + 1000 < startTime) { + word = 0; + return; + } + + /* Skip msecs that would generate dupes */ + while (endTime % msec != 0) { + if (++msec > 999) { + endTime--; + msec = 1; + } + } + + rand_seed = endTime / msec; + + i = 0; + while (i < password_length) { + /* this works like rand_r() from eglibc */ + rand_seed = rand_seed * 1103515245 + 12345; + rand_result = (rand_seed >> 16) & 2047; + + rand_seed = rand_seed * 1103515245 + 12345; + rand_result <<= 10; + rand_result ^= (rand_seed >> 16) & 1023; + + rand_seed = rand_seed * 1103515245 + 12345; + rand_result <<= 10; + rand_result ^= (rand_seed >> 16) & 1023; + + word[i++] = charset[rand_result % charset_length]; + } + word[i] = 0; + + if (++msec > 999) { + endTime--; + msec = 1; + } +} + +void restore() +{ + int i, rand_seed, rand_result; + + i = 0; + + /* Very crude restore, just dry-run until we hit last word */ + while (i != password_length) { + + while (endTime % msec != 0) { + if (++msec > 999) { + endTime--; + msec = 1; + } + } + + rand_seed = endTime / msec; + + i = 0; + while (i < password_length) { + /* this works like rand_r() from eglibc */ + rand_seed = rand_seed * 1103515245 + 12345; + rand_result = (rand_seed >> 16) & 2047; + + rand_seed = rand_seed * 1103515245 + 12345; + rand_result <<= 10; + rand_result ^= (rand_seed >> 16) & 1023; + + rand_seed = rand_seed * 1103515245 + 12345; + rand_result <<= 10; + rand_result ^= (rand_seed >> 16) & 1023; + + if (charset[rand_result % charset_length] != word[i++]) + break; + } + + if (++msec > 999) { + endTime--; + msec = 1; + } + } +} + +/* Awesome Password Generator RNG replay + * Written by Michael Samuel + * Public Domain. + * + * This takes advantage of a subtle bug, where a crypto RNG is used to + * seed the C# System.Random() class, which takes a 32-bit input, but + * converts negative numbers into non-negative numbers, resulting in + * only 31 bits of security. + * + * This only implements "easy to type" being *unticked*, and numbers, + * lowers, uppers and symbols being ticked, in random password mode. + * Changing the password length is easy, anything else is left as an + * exercise to the reader. + * + * Running Awesome Password Generator (1.3.2 or lower) in Mono is still + * vulnerable, but uses a different RNG, so this mode isn't compatible. + */ + +/* Awesome Password Generator 1.3.2 does a two-pass run, selecting which + * charset each position will have, then picking the character. This + * leads to heavy bias, and is fixed in 1.4.0 (along with many other + * fixes). If you have been using Awesome Password Generator, you should + * upgrade immediately and change your passwords. + */ +[List.External:AwesomePasswordGenerator] +int numbers[10]; +int lowers[26]; +int uppers[26]; +int symbols[32]; + +/* Since we don't have a double datatype, I simply pre-calculated the + * transition numbers calculating the scale formula: + * (double)randNum * 4.656612873077393e-10 * {4/10/26/32} + */ +int boundaries_charclass[4]; +int boundaries_numbers[10]; +int boundaries_letters[26]; +int boundaries_symbols[32]; + +/* This is the bug we're exploiting - the seed for the RNG is 32 bits + * from the crypto rng. The non-crypto RNG converts negative numbers + * into non-negative numbers, so there's only 2^31 possible seeds. + */ +int seed; + +int password_length; + +void init() +{ + password_length = 16; /* Change this to match config */ + + int c, i; + + c = '0'; i = 0; while (c <= '9') numbers[i++] = c++; + c = 'a'; i = 0; while (c <= 'z') lowers[i++] = c++; + c = 'A'; i = 0; while (c <= 'Z') uppers[i++] = c++; + + /* Symbols */ + i = 0; + symbols[i++] = '!'; symbols[i++] = '@'; symbols[i++] = '#'; symbols[i++] = '$'; + symbols[i++] = '%'; symbols[i++] = '^'; symbols[i++] = '&'; symbols[i++] = '*'; + symbols[i++] = '('; symbols[i++] = ')'; symbols[i++] = '~'; symbols[i++] = '-'; + symbols[i++] = '_'; symbols[i++] = '='; symbols[i++] = '+'; symbols[i++] = '\\'; + symbols[i++] = '|'; symbols[i++] = '/'; symbols[i++] = '['; symbols[i++] = ']'; + symbols[i++] = '{'; symbols[i++] = '}'; symbols[i++] = ';'; symbols[i++] = ':'; + symbols[i++] = '`'; symbols[i++] = '\''; symbols[i++] = '"'; symbols[i++] = ','; + symbols[i++] = '.'; symbols[i++] = '<'; symbols[i++] = '>'; symbols[i++] = '?'; + + i = 0; + boundaries_charclass[i++] = 536870912; boundaries_charclass[i++] = 1073741824; + boundaries_charclass[i++] = 1610612736; boundaries_charclass[i++] = 2147483647; + + i = 0; + boundaries_numbers[i++] = 214748365; boundaries_numbers[i++] = 429496730; + boundaries_numbers[i++] = 644245095; boundaries_numbers[i++] = 858993460; + boundaries_numbers[i++] = 1073741824; boundaries_numbers[i++] = 1288490189; + boundaries_numbers[i++] = 1503238554; boundaries_numbers[i++] = 1717986919; + boundaries_numbers[i++] = 1932735284; boundaries_numbers[i++] = 2147483647; + + i = 0; + boundaries_letters[i++] = 82595525; boundaries_letters[i++] = 165191050; + boundaries_letters[i++] = 247786575; boundaries_letters[i++] = 330382100; + boundaries_letters[i++] = 412977625; boundaries_letters[i++] = 495573150; + boundaries_letters[i++] = 578168675; boundaries_letters[i++] = 660764200; + boundaries_letters[i++] = 743359725; boundaries_letters[i++] = 825955250; + boundaries_letters[i++] = 908550775; boundaries_letters[i++] = 991146300; + boundaries_letters[i++] = 1073741824; boundaries_letters[i++] = 1156337349; + boundaries_letters[i++] = 1238932874; boundaries_letters[i++] = 1321528399; + boundaries_letters[i++] = 1404123924; boundaries_letters[i++] = 1486719449; + boundaries_letters[i++] = 1569314974; boundaries_letters[i++] = 1651910499; + boundaries_letters[i++] = 1734506024; boundaries_letters[i++] = 1817101549; + boundaries_letters[i++] = 1899697074; boundaries_letters[i++] = 1982292599; + boundaries_letters[i++] = 2064888124; boundaries_letters[i++] = 2147483647; + + i = 0; + boundaries_symbols[i++] = 67108864; boundaries_symbols[i++] = 134217728; + boundaries_symbols[i++] = 201326592; boundaries_symbols[i++] = 268435456; + boundaries_symbols[i++] = 335544320; boundaries_symbols[i++] = 402653184; + boundaries_symbols[i++] = 469762048; boundaries_symbols[i++] = 536870912; + boundaries_symbols[i++] = 603979776; boundaries_symbols[i++] = 671088640; + boundaries_symbols[i++] = 738197504; boundaries_symbols[i++] = 805306368; + boundaries_symbols[i++] = 872415232; boundaries_symbols[i++] = 939524096; + boundaries_symbols[i++] = 1006632960; boundaries_symbols[i++] = 1073741824; + boundaries_symbols[i++] = 1140850688; boundaries_symbols[i++] = 1207959552; + boundaries_symbols[i++] = 1275068416; boundaries_symbols[i++] = 1342177280; + boundaries_symbols[i++] = 1409286144; boundaries_symbols[i++] = 1476395008; + boundaries_symbols[i++] = 1543503872; boundaries_symbols[i++] = 1610612736; + boundaries_symbols[i++] = 1677721600; boundaries_symbols[i++] = 1744830464; + boundaries_symbols[i++] = 1811939328; boundaries_symbols[i++] = 1879048192; + boundaries_symbols[i++] = 1946157056; boundaries_symbols[i++] = 2013265920; + boundaries_symbols[i++] = 2080374784; boundaries_symbols[i++] = 2147483647; + + seed = 0; +} + +void generate() +{ + int i, j, s, next, nextp, val, bucket, randnum, used_charsets; + int seedarray[56]; + + /* BEGIN System.Random(seed) */ + if(seed < 0) { + /* Only bother with non-negative integers */ + word = 0; + return; + } + + s = 161803398 - seed++; + seedarray[55] = s; + i = val = 1; + + while(i < 55) { + bucket = 21 * i % 55; + seedarray[bucket] = val; + val = s - val; + if(val < 0) val += 2147483647; + s = seedarray[bucket]; + i++; + } + + i = 1; + while(i < 5) { + j = 1; + while(j < 56) { + seedarray[j] -= seedarray[1 + (j + 30) % 55]; + if(seedarray[j] < 0) seedarray[j] += 2147483647; + j++; + } + i++; + } + next = 0; + nextp = 21; + /* END System.Random(seed) */ + + used_charsets = 0; + while(used_charsets != 15) { + i = 0; + while(i < password_length) { + /* BEGIN Random.Sample() */ + if (++next >= 56) next = 1; + if (++nextp >= 56) nextp = 1; + randnum = seedarray[next] - seedarray[nextp]; + if (randnum == 2147483647) randnum--; + if (randnum < 0) randnum += 2147483647; + seedarray[next] = randnum; + /* END Random.Sample() */ + + j = 0; + while(boundaries_charclass[j] < randnum) j++; + + word[i] = j; /* Temporarily store in word[] */ + used_charsets |= (1 << j); + i++; + } + } + + i = 0; + while(i < password_length) { + /* BEGIN Random.Sample() */ + if (++next >= 56) next = 1; + if (++nextp >= 56) nextp = 1; + randnum = seedarray[next] - seedarray[nextp]; + if (randnum == 2147483647) randnum--; + if (randnum < 0) randnum += 2147483647; + seedarray[next] = randnum; + /* END Random.Sample() */ + j = 0; + + if(word[i] == 0) { + while(boundaries_letters[j] < randnum) j++; + word[i++] = lowers[j]; + } else if (word[i] == 1) { + while(boundaries_letters[j] < randnum) j++; + word[i++] = uppers[j]; + } else if (word[i] == 2) { + while(boundaries_numbers[j] < randnum) j++; + word[i++] = numbers[j]; + } else { /* if (word[i] == 3) */ + while(boundaries_symbols[j] < randnum) j++; + word[i++] = symbols[j]; + } + } + word[i] = 0; +} + + +void restore() +{ + int i, j, s, next, nextp, val, bucket, randnum, used_charsets; + int seedarray[56]; + int candidate[32]; /* This needs to be at-least as big as password-length */ + + seed = 0; + + while(seed > 0) { + /* BEGIN System.Random(seed) */ + s = 161803398 - seed++; + seedarray[55] = s; + i = val = 1; + + while(i < 55) { + bucket = 21 * i % 55; + seedarray[bucket] = val; + val = s - val; + if(val < 0) val += 2147483647; + s = seedarray[bucket]; + i++; + } + + i = 1; + while(i < 5) { + j = 1; + while(j < 56) { + seedarray[j] -= seedarray[1 + (j + 30) % 55]; + if(seedarray[j] < 0) seedarray[j] += 2147483647; + j++; + } + i++; + } + next = 0; + nextp = 21; + /* END System.Random(seed) */ + + used_charsets = 0; + while(used_charsets != 15) { + i = 0; + while(i < password_length) { + /* BEGIN Random.Sample() */ + if (++next >= 56) next = 1; + if (++nextp >= 56) nextp = 1; + randnum = seedarray[next] - seedarray[nextp]; + if (randnum == 2147483647) randnum--; + if (randnum < 0) randnum += 2147483647; + seedarray[next] = randnum; + /* END Random.Sample() */ + + j = 0; + while(boundaries_charclass[j] < randnum) j++; + + candidate[i] = j; + used_charsets |= (1 << j); + i++; + } + } + + i = 0; + while(i < password_length) { + /* BEGIN Random.Sample() */ + if (++next >= 56) next = 1; + if (++nextp >= 56) nextp = 1; + randnum = seedarray[next] - seedarray[nextp]; + if (randnum == 2147483647) randnum--; + if (randnum < 0) randnum += 2147483647; + seedarray[next] = randnum; + /* END Random.Sample() */ + j = 0; + + if(candidate[i] == 0) { + while(boundaries_letters[j] < randnum) j++; + if(lowers[j] != word[i++]) break; + } else if (candidate[i] == 1) { + while(boundaries_letters[j] < randnum) j++; + if(uppers[j] != word[i++]) break; + } else if (candidate[i] == 2) { + while(boundaries_numbers[j] < randnum) j++; + if(numbers[j] != word[i++]) break; + } else { /* if (word[i] == 3) */ + while(boundaries_symbols[j] < randnum) j++; + if(symbols[j] != word[i++]) break; + } + } + if(i == password_length) return; + } +} + # Try sequences of adjacent keys on a keyboard as candidate passwords [List.External:Keyboard] int maxlength, length; // Maximum password length to try, current length int fuzz; // The desired "fuzz factor", either 0 or 1 int id[15]; // Current character indices for each position -int m[0x400], mc[0x80]; // The keys matrix, counts of adjacent keys +int m[0x800]; // The keys matrix +int mc[0x100]; // Counts of adjacent keys int f[0x40], fc; // Characters for the first position, their count void init() @@ -572,15 +2045,19 @@ void init() int i, j, c, p; int k[0x40]; - minlength = 1; // Initial password length to try - maxlength = 15; // Maximum password length to try, up to 15 - fuzz = 1; // "Fuzz factor", set to 0 for much quicker runs + // Initial password length to try + if (req_minlen) + minlength = req_minlen; + else + minlength = 1; + if (req_maxlen) + maxlength = req_maxlen; + else + maxlength = cipher_limit; // the format's limit + fuzz = 1; // "Fuzz factor", set to 0 for much quicker runs /* * This defines the keyboard layout, by default for a QWERTY keyboard. - * Please note that the sizes of m[] and mc[] arrays assume 7-bit - * characters and will need to be doubled for 8-bit characters such as - * umlauts. */ i = 0; while (i < 0x40) k[i++] = 0; k[0] = '`'; @@ -597,7 +2074,7 @@ void init() k[0x35] = 'b'; k[0x36] = 'n'; k[0x37] = 'm'; k[0x38] = ','; k[0x39] = '.'; k[0x3a] = '/'; - i = 0; while (i < 0x80) mc[i++] = 0; + i = 0; while (i < 0x100) mc[i++] = 0; fc = 0; /* rows */ @@ -605,7 +2082,7 @@ void init() i = 0; while (i < 0x40) { p = c; - c = k[i++]; + c = k[i++] & 0xff; if (!c) continue; f[fc++] = c; if (!p) continue; @@ -617,19 +2094,20 @@ void init() /* columns */ i = 0; while (i < 0x30) { - p = k[i++]; + p = k[i++] & 0xff; if (!p) continue; j = 1 - fuzz; while (j <= 1 + fuzz) { - c = k[i + 0x10 - j++]; + c = k[i + 0x10 - j++] & 0xff; if (!c) continue; m[(c << 3) + mc[c]++] = p; m[(p << 3) + mc[p]++] = c; } } - id[0] = 0; - length = minlength; + length = 0; + while (length < minlength) + id[length++] = 0; } void generate() @@ -661,7 +2139,8 @@ void restore() /* Calculate the length */ length = 0; - while (word[length]) length++; + while (word[length]) + id[length++] = 0; /* Infer the first character index */ i = -1; @@ -675,6 +2154,64 @@ void restore() /* This sample can be enhanced to infer the rest of the indices here */ } +# Simplest (fastest?) possible dumb exhaustive search, demonstrating a +# mode that does not need any special restore() handling. +# Defaults to printable ASCII. +[List.External:DumbDumb] +int maxlength; // Maximum password length to try +int startchar, endchar; // Range of characters (inclusive) + +void init() +{ + int i; + + startchar = ' '; // Start with space + endchar = '~'; // End with tilde + + // Create first word, honoring --min-len + if (!(i = req_minlen)) + i++; + word[i] = 0; + while (i--) + word[i] = startchar; + word[0] = startchar - 1; + + if (req_maxlen) + maxlength = req_maxlen; // --max-len + else + maxlength = cipher_limit; // format's limit +} + +void generate() +{ + int i; + + if (++word <= endchar) + return; + + i = 0; + + while (word[i] > endchar) { + word[i++] = startchar; + if (!word[i]) { + word[i] = startchar; + word[i + 1] = 0; + } else + word[i]++; + } + + if (i >= maxlength) + word = 0; +} + +/* + * This mode will resume correctly without any restore handing. + * The empty function just confirms to John that everything is in order. + */ +void restore() +{ +} + # Generic implementation of "dumb" exhaustive search, given a range of lengths # and an arbitrary charset. This is pre-configured to try 8-bit characters # against LM hashes, which is only reasonable to do for very short password @@ -691,8 +2228,15 @@ void init() int minlength; int i, c; - minlength = 1; // Initial password length to try, must be at least 1 - maxlength = 7; // Must be at least same as minlength + // Initial password length to try, must be at least 1 + if (req_minlen) + minlength = req_minlen; + else + minlength = 1; + if (req_maxlen) + maxlength = req_maxlen; + else + maxlength = cipher_limit; // the format's limit /* * This defines the character set. @@ -794,12 +2338,22 @@ int charset[0x7f00]; // Character sets, 0x100 elements for each position void init() { - int length; + int length, maxlength; int pos, ofs, i, c; - length = 8; // Password length to try + if (req_minlen) + length = req_minlen; + else + length = 8; // Password length to try (NOTE: other [eg. shorter] + // lengths will not be tried!) + if (req_maxlen) + maxlength = req_maxlen; + else + maxlength = cipher_limit; // the format's limit /* This defines the character sets for different character positions */ + if (length > maxlength) + length = maxlength; pos = 0; while (pos < 4) { ofs = pos++ << 8; @@ -859,985 +2413,1234 @@ void restore() } lastid = id[--last]; } -#################################################################### -# KoreLogic Custom John the Ripper Rules: -#################################################################### - -# Use this rule with 2EVERYTHING.dic or 3EVERYTHING.dic -[List.Rules:KoreLogicRulesPrependSeason] -A0"[Ss$][uU][mM][mM][eE3][rR]" -A0"[Ww][iI|][nN][tT+][eE3][rR]" -A0"[Ff][aA][lL][lL]" -A0"[Ss][pP][rR][iI][nN][gG]" -A0"[Aa][uU][tT][uU][mM][nN]" - -# Use this rule with 2EVERYTHING.dic or 3EVERYTHING.dic -[List.Rules:KoreLogicRulesAppendSeason] -<* Az"[Ss$][uU][mM][mM][eE3][rR]" -<* Az"[Ww][iI|][nN][tT+][eE3][rR]" -<* Az"[Ff][aA][lL][lL]" -<* Az"[Ss][pP][rR][iI][nN][gG]" -<* Az"[Aa][uU][tT][uU][mM][nN]" - -[List.Rules:KoreLogicRulesPrependHello] -A0"[hH][eE][lL][lL][oO0]" - -[List.Rules:KoreLogicRulesPrependYears] -A0"20[0-1][0-9]" -A0"19[3-9][0-9]" - -# Notice: Your wordlist should likely be all lowercase - or you are wasting work -[List.Rules:KoreLogicRulesAppendYears] --[c:] \p[c:] Az"19[0-9][0-9]" <+ --[c:] \p[c:] Az"20[01][0-9]" <+ - -# Notice how we -# 1) do caps first b/c they are more common in 'complex' environments -# 2) Do !$@#%. first b/c they are the most common special chars -[List.Rules:KoreLogicRulesAppendCurrentYearSpecial] --[c:] \p[c:] Az"201[0-9][!$@#%.]" <+ --[c:] \p[c:] Azq201[0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -[List.Rules:KoreLogicRulesAppend4Num] --[c:] \p[c:] Az"[0-9][0-9][0-9][0-9]" <+ - -[List.Rules:KoreLogicRulesAppend5Num] --[c:] \p[c:] Az"[0-9][0-9][0-9][0-9][0-9]" <+ - -[List.Rules:KoreLogicRulesAppend6Num] --[c:] \p[c:] Az"[0-9][0-9][0-9][0-9][0-9][0-9]" <+ - -[List.Rules:KoreLogicRulesAppendSpecial3num] --[c:] \p[c:] Az"[!$@#%.][0-9][0-9][0-9]" <+ --[c:] \p[c:] Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9][0-9]q <+ - -[List.Rules:KoreLogicRulesAppendSpecial4num] --[c:] \p[c:] Az"[!$@#%.][0-9][0-9][0-9][0-9]" <+ --[c:] \p[c:] Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9][0-9][0-9]q <+ - -[List.Rules:KoreLogicRulesPrependCAPCAPAppendSpecial] -A0"[A-Z][A-Z]" <* $[!$@#%.] -A0"[A-Z][A-Z]" <* $[^&()_+\-={}|[\]\\;'":,/<>?`~*] - -[List.Rules:KoreLogicRulesPrependNumNumAppendSpecial] --[c:] \p[c:] A0"[0-9][0-9]" <* $[!$@#%.] --[c:] \p[c:] A0"[0-9][0-9]" <* $[^&()_+\-={}|[\]\\;'":,/<>?`~*] - -[List.Rules:KoreLogicRulesPrependNumNum] --[c:] \p[c:] A0"[0-9][0-9]" - -[List.Rules:KoreLogicRulesPrependNumNumNum] --[c:] \p[c:] A0"[0-9][0-9][0-9]" - -[List.Rules:KoreLogicRulesPrependNumNumNumNum] --[c:] \p[c:] A0"[0-9][0-9][0-9][0-9]" - -[List.Rules:KoreLogicRulesPrependNumNumSpecial] --[c:] \p[c:] A0"[0-9][0-9][!$@#%.]" --[c:] \p[c:] A0q[0-9][0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -[List.Rules:KoreLogicRulesPrepend2NumbersAppend2Numbers] --[c:] \p[c:] A0"[0-9][0-9]" <- Az"[0-9][0-9]" - -[List.Rules:KoreLogicRulesPrependSpecialSpecial] --[c:] \p[c:] A0q[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -[List.Rules:KoreLogicRulesAppendSpecialNumberNumber] --[c:] \p[c:] Az"[!$@#%.][0-9][0-9]" <+ --[c:] \p[c:] Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9]q <+ - -[List.Rules:KoreLogicRulesAppendSpecialNumberNumberNumber] --[c:] \p[c:] Az"[!$@#%.][0-9][0-9][0-9]" <+ --[c:] \p[c:] Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9][0-9]q <+ - -[List.Rules:KoreLogicRulesPrependSpecialSpecialAppendNumber] --[c:] \p[c:] A0"[!$@#%.][!$@#%.]" <* $[0-9] --[c:] \p[c:] A0q[^&()_+\-={}|[\]\\;'":,/<>?`~*][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <* $[0-9] - -[List.Rules:KoreLogicRulesPrependSpecialSpecialAppendNumbersNumber] --[c:] \p[c:] A0"[!$@#%.][!$@#%.]" <- Az"[0-9][0-9]" --[c:] \p[c:] A0q[^&()_+\-={}|[\]\\;'":,/<>?`~*][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <- Az"[0-9][0-9]" - -[List.Rules:KoreLogicRulesPrependSpecialSpecialAppendNumbersNumberNumber] --[c:] \p[c:] A0"[!$@#%.][!$@#%.]" Az"[0-9][0-9][0-9]" <+ --[c:] \p[c:] A0q[^&()_+\-={}|[\]\\;'":,/<>?`~*][^&()_+\-={}|[\]\\;'":,/<>?`~*]q Az"[0-9][0-9][0-9]" <+ - -[List.Rules:KoreLogicRulesAppend2Letters] -<- Az"[a-z][a-z]" --c <- Az"[A-Z][A-Z]" --c <- Az"[a-z][A-Z]" --c <- Az"[A-Z][a-z]" - -[List.Rules:KoreLogicRulesPrepend4NumAppendSpecial] --[c:] \p[c:] A0"[0-9][0-9][0-9][0-9]" <- $[!$@#%.] --[c:] \p[c:] A0"[0-9][0-9][0-9][0-9]" <- Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -[List.Rules:KoreLogicRulesAppend4NumSpecial] --[c:] \p[c:] Az"[0-9][0-9][0-9][0-9][!$@#%.]" <+ --[c:] \p[c:] Azq[0-9][0-9][0-9][0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -[List.Rules:KoreLogicRulesAppend3NumSpecial] --[c:] \p[c:] Az"[0-9][0-9][0-9][!$@#%.]" <+ --[c:] \p[c:] Azq[0-9][0-9][0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -[List.Rules:KoreLogicRulesAppend2NumSpecial] --[c:] \p[c:] Az"[0-9][0-9][!$@#%.]" <+ --[c:] \p[c:] Azq[0-9][0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -# Append numbers - but limit the total length. -[List.Rules:KoreLogicRulesAddJustNumbers] --[c:] <* >1 \p[c:] $[0-9] --[c:] <* >1 \p[c:] ^[0-9] --[c:] <- >1 \p[c:] Az"[0-9][0-9]" --[c:] <- >1 \p[c:] A0"[0-9][0-9]" --[c:] >1 \p[c:] Az"[0-9][0-9][0-9]" <+ --[c:] >1 \p[c:] Az"[0-9][0-9][0-9][0-9]" <+ - -[List.Rules:KoreLogicRulesDevProdTestUAT] --\r[::cc] <* A\p\r[0l0l]"dev" \p\r[::TT]\p\r[::0l] --\r[::cc] <* A\p\r[0l0l]"uat" \p\r[::TT]\p\r[::0l] --\r[::cc] <* A\p\r[0l0l]"prod" \p\r[::TT]\p\r[::0l] --\r[::cc] <* A\p\r[0l0l]"test" \p\r[::TT]\p\r[::0l] - -[List.Rules:KoreLogicRulesPrependAndAppendSpecial] --[c:] <- \p[c:] ^[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] - -[List.Rules:KoreLogicRulesAppendJustNumbers] --[c:] <* \p[c:] $[0-9] --[c:] <- \p[c:] Az"[0-9][0-9]" --[c:] \p[c:] Az"[0-9][0-9][0-9]" <+ --[c:] \p[c:] Az"[0-9][0-9][0-9][0-9]" <+ - -[List.Rules:KoreLogicRulesAppendNumbers_and_Specials_Simple] -# cap first letter then add a 0 2 6 9 ! * to the end --[c:] <* \p[c:] $[0-9!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] -# cap first letter then add a special char - THEN a number !0 %9 !9 etc --[c:] <- \p[c:] Azq[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9]q -# Cap the first letter - then add 0? 0! 5_ .. 9! -## add NUMBER then SPECIAL 1! .. 9? --[c:] <- \p[c:] Azq[0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q -## Add Number Number Special --[c:] \p[c:] Azq[0-9][0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ -## Add Special Number Number --[c:] \p[c:] Azq[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9]q <+ -# Add 100! ... 999! to the end --[c:] \p[c:] Azq[0-9][0-9][0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -[List.Rules:KoreLogicRulesAppendJustSpecials] --[c:] <* \p[c:] $[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] --[c:] <- \p[c:] Azq[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -[List.Rules:KoreLogicRulesMonthsFullPreface] --[:c] A0"\p[jJ]anuary" --[:c] A0"\p[fF]ebruary" --[:c] A0"\p[mM]arch" --[:c] A0"\p[aA]pril" --[:c] A0"\p[mM]ay" --[:c] A0"\p[jJ]uner" --[:c] A0"\p[jJ]uly" --[:c] A0"\p[aA]ugust" --[:c] A0"\p[sS]eptember" --[:c] A0"\p[oO]ctober" --[:c] A0"\p[nN]ovember" --[:c] A0"\p[dD]ecember" - -[List.Rules:KoreLogicRulesAddShortMonthsEverywhere] -<* >\r[00123456789] A\p[z0-9]"[jJ][aA][nN]" -<* >\r[00123456789] A\p[z0-9]"[fF][eE][bB]" -<* >\r[00123456789] A\p[z0-9]"[mM][aA][rRyY]" -<* >\r[00123456789] A\p[z0-9]"[aA][pP][rR]" -<* >\r[00123456789] A\p[z0-9]"[jJ][uU][nNlL]" -<* >\r[00123456789] A\p[z0-9]"[aA][uU][gG]" -<* >\r[00123456789] A\p[z0-9]"[sS][eE][pP]" -<* >\r[00123456789] A\p[z0-9]"[oO][cC][tT]" -<* >\r[00123456789] A\p[z0-9]"[nN][oO][vV]" -<* >\r[00123456789] A\p[z0-9]"[dD][eE][cC]" - -[List.Rules:KoreLogicRulesPrepend4LetterMonths] -## Preface each dictionary with Janu janu Febr febr --[:c] A0"\p[jJ]anu" --[:c] A0"\p[fF]ebr" --[:c] A0"\p[mM]arc" --[:c] A0"\p[aA]pr" --[:c] A0"\p[mM]ay" --[:c] A0"\p[jJ]une" --[:c] A0"\p[jJ]uly" --[:c] A0"\p[Aa]ugu" --[:c] A0"\p[sS]ept" --[:c] A0"\p[oO]cto" --[:c] A0"\p[nN]ove" --[:c] A0"\p[Dd]ece" - -# this will add the string '2010' at all places in the word: -# USE this with a 4 or 5 char dictionary file with ALL characters -# soo abcde will become -# 2010abcde a2010bcde ab2010cde acd2010de abcd2010e abcde2010 -[List.Rules:KoreLogicRulesAdd2010Everywhere] -<* >\r[00123456789] A\p[z0-9]"201[0-9]" - -[List.Rules:KoreLogicRulesPrependDaysWeek] -A0"[Mm][oO0][nN][dD][aA4@][yY]" -A0"[Tt][uU][eE3][sS$][dD][aA4@][yY]" -A0"[Ww][eE3][dD][nN][eE3][sS$][dD][aA4@][yY]" -A0"[Tt][hH][uU][rR][sS$][dD][aA4@][yY]" -A0"[Ff][rR][iI1!][dD][aA4@][yY]" -A0"[Ss][aA4@][tT+][uU][rR][dD][aA4@][yY]" -A0"[Ss][uU][nN][dD][aA4@][yY]" - -[List.Rules:KoreLogicRulesAdd1234_Everywhere] -<* >\r[00123456789] A\p[z0-9]"1234" - -[List.Rules:KoreLogicRulesAppendMonthDay] --[:c] <* Az"\p[jJ]anuary" --[:c] Az"\p[jJ]anuary[0-9]" <+ --[:c] Az"\p[jJ]anuary[0-9][0-9]" <+ --[:c] <* Az"\p[fF]ebruary" --[:c] Az"\p[fF]ebruary[0-9]" <+ --[:c] Az"\p[fF]ebruary[0-9][0-9]" <+ --[:c] <* Az"\p[mM]arch" --[:c] Az"\p[mM]arch[0-9]" <+ --[:c] Az"\p[mM]arch[0-9][0-9]" <+ --[:c] <* Az"\p[aA]pril" --[:c] Az"\p[aA]pril[0-9]" <+ --[:c] Az"\p[aA]pril[0-9][0-9]" <+ --[:c] <* Az"\p[mM]ay" --[:c] Az"\p[mM]ay[0-9]" <+ --[:c] Az"\p[mM]ay[0-9][0-9]" <+ --[:c] <* Az"\p[jJ]une" --[:c] Az"\p[jJ]une[0-9]" <+ -# There was a typo in Kore's original revision of this rule --[:c] Az"\p[jJ]une[0-9][0-9]" <+ --[:c] <* Az"\p[jJ]uly" --[:c] Az"\p[jJ]uly[0-9]" <+ --[:c] Az"\p[jJ]uly[0-9][0-9]" <+ --[:c] <* Az"\p[aA]ugust" --[:c] Az"\p[aA]ugust[0-9]" <+ --[:c] Az"\p[aA]ugust[0-9][0-9]" <+ --[:c] <* Az"\p[sS]eptember" --[:c] Az"\p[sS]eptember[0-9]" <+ -# There was a typo in Kore's original revision of this rule --[:c] Az"\p[sS]eptember[0-9][0-9]" <+ --[:c] <* Az"\p[oO]ctober" --[:c] Az"\p[oO]ctober[0-9]" <+ --[:c] Az"\p[oO]ctober[0-9][0-9]" <+ --[:c] <* Az"\p[nN]ovember" --[:c] Az"\p[nN]ovember[0-9]" <+ --[:c] Az"\p[nN]ovember[0-9][0-9]" <+ --[:c] <* Az"\p[dD]ecember" --[:c] Az"\p[dD]ecember[0-9]" <+ --[:c] Az"\p[dD]ecember[0-9][0-9]" <+ - -[List.Rules:KoreLogicRulesAppendMonthCurrentYear] --[:c] <* Az"\p[jJ]an201[0-9]" --[:c] <* Az"\p[fF]eb201[0-9]" --[:c] <* Az"\p[mM]ar201[0-9]" --[:c] <* Az"\p[aA]pr201[0-9]" --[:c] <* Az"\p[mM]ay201[0-9]" --[:c] <* Az"\p[jJ]un201[0-9]" --[:c] <* Az"\p[jJ]ul201[0-9]" --[:c] <* Az"\p[Aa]ug201[0-9]" --[:c] <* Az"\p[sS]ep201[0-9]" --[:c] <* Az"\p[oO]ct201[0-9]" --[:c] <* Az"\p[nN]ov201[0-9]" --[:c] <* Az"\p[Dd]ec201[0-9]" - -[List.Rules:KoreLogicRulesReplaceNumbers2Special] -/[1-90] s\0\p[!@#$%^&*()] -/1 /[2-90] s1! s\0\p[@#$%^&*()] -/2 /[3-90] s2@ s\0\p[#$%^&*()] -/3 /[4-90] s3# s\0\p[$%^&*()] -/4 /[5-90] s4$ s\0\p[%^&*()] -/5 /[6-90] s5% s\0\p[^&*()] -/6 /[7-90] s6^ s\0\p[&*()] -/7 /[890] s7& s\0\p[*()] -/8 /[90] s8* s\0\p[()] -/9 /0 s9( s0) - -[List.Rules:KoreLogicRulesReplaceNumbers] -/0 s0[1-9] -/1 s1[02-9] -/2 s2[013-9] -/3 s3[0-24-9] -/4 s4[0-35-9] -/5 s5[0-46-9] -/6 s6[0-57-9] -/7 s7[0-68-9] -/8 s8[0-79] -/9 s9[0-8] -# 10 lines above can be replaced with just one: -# /[0-9] s\0[0-9] Q -# but it's slower (generates, then rejects some duplicates). - -# This is a lamer/faster version of --rules:nt -[List.Rules:KoreLogicRulesReplaceLettersCaps] --c /[a-z] s\0\p[A-Z] - -[List.Rules:KoreLogicRulesAddDotCom] --[c:] <- \p[c:] Az".com" --[c:] <- \p[c:] Az".net" --[c:] <- \p[c:] Az".org" - -[List.Rules:KoreLogicRulesAppendCap-Num_or_Special-Twice] --[c:] \p[c:] Az"[A-Z][0-9][0-9]" <+ --[c:] \p[c:] Azq[A-Z][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9]q <+ --[c:] \p[c:] Azq[A-Z][0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ --[c:] \p[c:] Azq[A-Z][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -[List.Rules:KoreLogicRulesAppendSpecialLowerLower] --[c:] \p[c:] AzQ[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][a-z][a-z]Q <+ - -[List.Rules:KoreLogicRulesAppendJustSpecials3Times] --[c:] \p[c:] Az"[!$@#%.][!$@#%.][!$@#%.]" <+ --[c:] \p[c:] Azq[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -[List.Rules:KoreLogicRulesPrependJustSpecials] --[c:] \p[c:] ^[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] --[c:] \p[c:] A0q[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -[List.Rules:KoreLogicRulesAppend1_AddSpecialEverywhere] --[c:] >4 <- \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $1 --[c:] >[5-8] <- \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $1 - -[List.Rules:KoreLogicRulesPrependNumNum_AppendNumSpecial] --[c:] \p[c:] A0"[0-9][0-9]" Azq[0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -[List.Rules:KoreLogicRulesAppendNum_AddSpecialEverywhere] -# This should probably use $[02-9] since we try $1 in -# KoreLogicRulesAppend1_AddSpecialEverywhere --[c:] >4 <- \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $[0-9] --[c:] >[5-8] <- \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $[0-9] - -[List.Rules:KoreLogicRulesAppendNumNum_AddSpecialEverywhere] --[c:] >4 \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"[0-9][0-9]" <+ --[c:] >[5-8] \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"[0-9][0-9]" <+ - -[List.Rules:KoreLogicRulesAppendNumNumNum_AddSpecialEverywhere] --[c:] >4 \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"[0-9][0-9][0-9]" <+ --[c:] >[5-8] \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"[0-9][0-9][0-9]" <+ - -[List.Rules:KoreLogicRulesAppendYears_AddSpecialEverywhere] --[c:] >4 \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"19[4-9][0-9]" <+ --[c:] >4 \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"20[0-1][0-9]" <+ --[c:] >[5-8] \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"19[4-9][0-9]" <+ --[c:] >[5-8] \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"20[0-1][0-9]" <+ - -# This rule needs work actually --- you have to 'sort -u' its output rick -# /a = reject if it doesnt have an 'a' -# the [:c] does waste some effort - and generate dupes. This is wasteful, -# but I want to keep it in b/c the original crack/JtR rules use it. -[List.Rules:KoreLogicRulesL33t] --[:c] /\r[aaAAbBeEiiiIIIllll] s\0\r\p[@44@88331!|1!|17|!] \p1[:M] \p1[:c] \p1[:Q] -# The following line differs from Kore's erroneous 4 lines: --[:c] /\r[LLLL] s\0\r\p[17|!] \p1[:M] \p1[:c] \p1[:Q] -#/Lsl1[:c] -#/Lsl7[:c] -#/Lsl|[:c] -#/Lsl![:c] --[:c] /\r[oOssSStT1111003344557788] s\0\r\p[00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Full set (same as above, but on one line): -#-[:c] /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT1111003344557788] s\0\r\p[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Double substitutions start here. -# Compared to Kore's, we check for both chars first, then replace both. -# This produces different results from Kore's, which would replace all -# instances of the first char before checking for the second. -# Kore's behavior may be restored by moving "sa[@4]" to be right after "/a" -# on the line below, and ditto for further lines. --[:c] /a /\r[AAbBeEiiiIIIllllLLLLoOssSStT1111003344557788] sa[@4] s\2\r\p2[4@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Kore had these (probably unintentionally, so we don't duplicate them): -#/asa4/4s4a[:c] -#/asa4/4s4A[:c] --[:c] /A /\r[aabBeEiiiIIIllllLLLLoOssSStT1111003344557788] sA4 s\0\r\p[@488331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Kore also had these, but (intentionally?) missed sb8 on this set (after sA4) -#/AsA4/4s4a[:c] -#/AsA4/4s4A[:c] --[:c] /b /\r[aaAABeEiiiIIIllllLLLLoOssSStT1111003344557788] sb8 s\0\r\p[@44@8331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /B /\r[aaAAbeEiiiIIIllllLLLLoOssSStT1111003344557788] sB8 s\0\r\p[@44@8331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /e /\r[aaAAbBEiiiIIIllllLLLLoOssSStT1111003344557788] se3 s\0\r\p[@44@8831!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /E /\r[aaAAbBeiiiIIIllllLLLLoOssSStT1111003344557788] sE3 s\0\r\p[@44@8831!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /i /\r[aaAAbBeEIIIllllLLLLoOssSStT1111003344557788] si[1!|] s\2\r\p2[@44@88331!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /I /\r[aaAAbBeEiiillllLLLLoOssSStT1111003344557788] sI[1!|] s\2\r\p2[@44@88331!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Kore's rules only included sl[17|], but not sl! --[:c] /l /\r[aaAAbBeEiiiIIILLLLoOssSStT1111003344557788] sl[17|!] s\2\r\p2[@44@88331|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# All "/L" rules (171 lines) were buggy --[:c] /L /\r[aaAAbBeEiiiIIIlllloOssSStT1111003344557788] sl[17|!] s\2\r\p2[@44@88331|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /o /\r[aaAAbBeEiiiIIIllllLLLLOssSStT1111003344557788] so0 s\0\r\p[@44@88331!|1!|17|!17|!0$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /O /\r[aaAAbBeEiiiIIIllllLLLLossSStT1111003344557788] sO0 s\0\r\p[@44@88331!|1!|17|!17|!0$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /s /\r[aaAAbBeEiiiIIIllllLLLLoOSStT1111003344557788] ss[$5] s\2\r\p2[@44@88331!|1!|17|!17|!00$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /S /\r[aaAAbBeEiiiIIIllllLLLLoOsstT1111003344557788] sS[$5] s\2\r\p2[@44@88331!|1!|17|!17|!00$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /t /\r[aaAAbBeEiiiIIIllllLLLLoOssSST1111003344557788] st+ s\0\r\p[@44@88331!|1!|17|!17|!00$5$5+!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /T /\r[aaAAbBeEiiiIIIllllLLLLoOssSSt1111003344557788] sT+ s\0\r\p[@44@88331!|1!|17|!17|!00$5$5+!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /1 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT003344557788] s1[!iI|] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /0 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11113344557788] s0[oO] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|eEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /3 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110044557788] s3[eE] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -#-[:c] /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT1111003344557788] s\0\r\p[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /4 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110033557788] s4[aA] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /5 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110033447788] s5[sS] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /7 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110033445588] s7[lL] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /8 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110033445577] s8[bB] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlL] \p1[:M] \p1[:c] \p1[:Q] -# These are some popular triple/quad l33t rules --[:c] /a /e /[los] sa4 se3 s\0\p[10$] \p1[:M] \p1[:c] \p1[:Q] --[:c] /[ae] /l /[os] s\2\p2[43] sl1 s\3\p3[0$] \p1[:M] \p1[:c] \p1[:Q] --[:c] /[ae] /o /s s\2\p2[43] so0 ss$ \p1[:M] \p1[:c] \p1[:Q] --[:c] /l /o /s sl1 so0 ss$ \p1[:M] \p1[:c] \p1[:Q] --[:c] /a /e /l /[os] sa4 se3 sl1 s\0\p[0$] \p1[:M] \p1[:c] \p1[:Q] --[:c] /a /[el] /o /s sa4 s\0\p[31] so0 ss$ \p1[:M] \p1[:c] \p1[:Q] --[:c] /e /l /o /s se3 sl1 so0 ss$ \p1[:M] \p1[:c] \p1[:Q] --[:c] /a /e /l /o /s sa4 se3 sl1 so0 ss$ \p1[:M] \p1[:c] \p1[:Q] - -[List.Rules:KoreLogicRulesReplaceSpecial2Special] -# Kore's rules were missing "*" -/! s![@#$%^&*()\-=_+\\|;:'",./?><] -/@ s@[!#$%^&*()\-=_+\\|;:'",./?><] -/# s#[!@$%^&*()\-=_+\\|;:'",./?><] -/$ s$[!@#%^&*()\-=_+\\|;:'",./?><] -/% s%[!@#$^&*()\-=_+\\|;:'",./?><] -/^ s^[!@#$%&*()\-=_+\\|;:'",./?><] -/& s&[!@#$%^*()\-=_+\\|;:'",./?><] -/( s([!@#$%^&*)\-=_+\\|;:'",./?><] -/) s([!@#$%^&*(\-=_+\\|;:'",./?><] -# Kore's ruleset erroneously had: -#/-s-- -/- s-[!@#$%^&*()=_+\\|;:'",./?><] -/= s=[!@#$%^&*()\-_+\\|;:'",./?><] -/_ s_[!@#$%^&*()\-=+\\|;:'",./?><] -/+ s+[!@#$%^&*()\-=_\\|;:'",./?><] -# Kore's rules did not replace backslash -/\\ s\\[!@#$%^&*()\-=_+|;:'",./?><] -/| s|[!@#$%^&*()\-=_+\\;:'",./?><] -/; s;[!@#$%^&*()\-=_+\\|:'",./?><] -/: s:[!@#$%^&*()\-=_+\\|;'",./?><] -/' s'[!@#$%^&*()\-=_+\\|;:",./?><] -/" s"[!@#$%^&*()\-=_+\\|;:',./?><] -/, s,[!@#$%^&*()\-=_+\\|;:'"./?><] -/. s.[!@#$%^&*()\-=_+\\|;:'",/?><] -// s/[!@#$%^&*()\-=_+\\|;:'",.?><] -/> s>[!@#$%^&*()\-=_+\\|;:'",./?<] -/< s<[!@#$%^&*()\-=_+\\|;:'",./?>] - -[List.Rules:KoreLogicRulesReplaceLetters] -/a sa[b-z] -/b sb[ac-z] -/c sc[abd-z] -/d sd[a-ce-z] -/e se[a-df-z] -/f sf[a-eg-z] -/g sg[a-fh-z] -/h sh[a-gi-z] -/i si[a-hj-z] -/j sj[a-ik-z] -/k sk[a-jl-z] -/l sl[a-km-z] -/m sm[a-ln-z] -/n sn[a-mo-z] -/o so[a-np-z] -/p sp[a-oq-z] -/q sq[a-pr-z] -/r sr[a-qs-z] -/s ss[a-rt-z] -/t st[a-su-z] -/u su[a-tv-z] -/v sv[a-uw-z] -/w sw[a-vx-z] -/x sx[a-wyz] -/y sy[a-xz] -# Kore's ruleset was truncated after "/zszr" -/z sz[a-y] --c /[a-z] s\0[A-Z] - -#################################################################### - -[List.Rules:KoreLogicRules] - -;[List.Rules:KoreLogicRulesPrependNumNum] --[c:] \p[c:] A0"[0-9][0-9]" - -;[List.Rules:KoreLogicRulesPrependYears] -A0"20[0-1][0-9]" -A0"19[3-9][0-9]" - -# Notice: Your wordlist should likely be all lowercase - or you are wasting work -;[List.Rules:KoreLogicRulesAppendYears] --[c:] \p[c:] Az"19[0-9][0-9]" <+ --[c:] \p[c:] Az"20[01][0-9]" <+ - -;[List.Rules:KoreLogicRulesPrependNumNumNum] --[c:] \p[c:] A0"[0-9][0-9][0-9]" - -;[List.Rules:KoreLogicRulesMonthsFullPreface] --[:c] A0"\p[jJ]anuary" --[:c] A0"\p[fF]ebruary" --[:c] A0"\p[mM]arch" --[:c] A0"\p[aA]pril" --[:c] A0"\p[mM]ay" --[:c] A0"\p[jJ]uner" --[:c] A0"\p[jJ]uly" --[:c] A0"\p[aA]ugust" --[:c] A0"\p[sS]eptember" --[:c] A0"\p[oO]ctober" --[:c] A0"\p[nN]ovember" --[:c] A0"\p[dD]ecember" - -;[List.Rules:KoreLogicRulesPrepend4LetterMonths] -## Preface each dictionary with Janu janu Febr febr --[:c] A0"\p[jJ]anu" --[:c] A0"\p[fF]ebr" --[:c] A0"\p[mM]arc" --[:c] A0"\p[aA]pr" --[:c] A0"\p[mM]ay" --[:c] A0"\p[jJ]une" --[:c] A0"\p[jJ]uly" --[:c] A0"\p[Aa]ugu" --[:c] A0"\p[sS]ept" --[:c] A0"\p[oO]cto" --[:c] A0"\p[nN]ove" --[:c] A0"\p[Dd]ece" - -# Use this rule with 2EVERYTHING.dic or 3EVERYTHING.dic -;[List.Rules:KoreLogicRulesPrependSeason] -A0"[Ss$][uU][mM][mM][eE3][rR]" -A0"[Ww][iI|][nN][tT+][eE3][rR]" -A0"[Ff][aA][lL][lL]" -A0"[Ss][pP][rR][iI][nN][gG]" -A0"[Aa][uU][tT][uU][mM][nN]" - -# Use this rule with 2EVERYTHING.dic or 3EVERYTHING.dic -;[List.Rules:KoreLogicRulesAppendSeason] -<* Az"[Ss$][uU][mM][mM][eE3][rR]" -<* Az"[Ww][iI|][nN][tT+][eE3][rR]" -<* Az"[Ff][aA][lL][lL]" -<* Az"[Ss][pP][rR][iI][nN][gG]" -<* Az"[Aa][uU][tT][uU][mM][nN]" - -;[List.Rules:KoreLogicRulesPrependHello] -A0"[hH][eE][lL][lL][oO0]" - -# Notice how we -# 1) do caps first b/c they are more common in 'complex' environments -# 2) Do !$@#%. first b/c they are the most common special chars -;[List.Rules:KoreLogicRulesAppendCurrentYearSpecial] --[c:] \p[c:] Az"201[0-9][!$@#%.]" <+ --[c:] \p[c:] Azq201[0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -;[List.Rules:KoreLogicRulesPrependSpecialSpecial] --[c:] \p[c:] A0q[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -;[List.Rules:KoreLogicRulesAppend2Letters] -<- Az"[a-z][a-z]" --c <- Az"[A-Z][A-Z]" --c <- Az"[a-z][A-Z]" --c <- Az"[A-Z][a-z]" - -# Append numbers - but limit the total length. -;[List.Rules:KoreLogicRulesAddJustNumbers] --[c:] <* >1 \p[c:] $[0-9] --[c:] <* >1 \p[c:] ^[0-9] --[c:] <- >1 \p[c:] Az"[0-9][0-9]" --[c:] <- >1 \p[c:] A0"[0-9][0-9]" --[c:] >1 \p[c:] Az"[0-9][0-9][0-9]" <+ -# Redundant with KoreLogicRulesAppend4Num -;-[c:] >1 \p[c:] Az"[0-9][0-9][0-9][0-9]" <+ - -;[List.Rules:KoreLogicRulesDevProdTestUAT] --\r[::cc] <* A\p\r[0l0l]"dev" \p\r[::TT]\p\r[::0l] --\r[::cc] <* A\p\r[0l0l]"uat" \p\r[::TT]\p\r[::0l] --\r[::cc] <* A\p\r[0l0l]"prod" \p\r[::TT]\p\r[::0l] --\r[::cc] <* A\p\r[0l0l]"test" \p\r[::TT]\p\r[::0l] - -;[List.Rules:KoreLogicRulesPrependAndAppendSpecial] --[c:] <- \p[c:] ^[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] - -# Redundant with KoreLogicRulesAddJustNumbers and KoreLogicRulesAppend4Num -;[List.Rules:KoreLogicRulesAppendJustNumbers] -;-[c:] <* \p[c:] $[0-9] -;-[c:] <- \p[c:] Az"[0-9][0-9]" -;-[c:] \p[c:] Az"[0-9][0-9][0-9]" <+ -;-[c:] \p[c:] Az"[0-9][0-9][0-9][0-9]" <+ - -;[List.Rules:KoreLogicRulesAppendNumbers_and_Specials_Simple] -# cap first letter then add a 0 2 6 9 ! * to the end --[c:] <* \p[c:] $[0-9!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] -# cap first letter then add a special char - THEN a number !0 %9 !9 etc --[c:] <- \p[c:] Azq[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9]q -# Cap the first letter - then add 0? 0! 5_ .. 9! -## add NUMBER then SPECIAL 1! .. 9? --[c:] <- \p[c:] Azq[0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q -## Add Number Number Special -;-[c:] \p[c:] Azq[0-9][0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ -## Add Special Number Number -;-[c:] \p[c:] Azq[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9]q <+ -# Add 100! ... 999! to the end -;-[c:] \p[c:] Azq[0-9][0-9][0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -;[List.Rules:KoreLogicRulesAppendJustSpecials] --[c:] <* \p[c:] $[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] --[c:] <- \p[c:] Azq[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -;[List.Rules:KoreLogicRulesAddShortMonthsEverywhere] -<* >\r[00123456789] A\p[z0-9]"[jJ][aA][nN]" -<* >\r[00123456789] A\p[z0-9]"[fF][eE][bB]" -<* >\r[00123456789] A\p[z0-9]"[mM][aA][rRyY]" -<* >\r[00123456789] A\p[z0-9]"[aA][pP][rR]" -<* >\r[00123456789] A\p[z0-9]"[jJ][uU][nNlL]" -<* >\r[00123456789] A\p[z0-9]"[aA][uU][gG]" -<* >\r[00123456789] A\p[z0-9]"[sS][eE][pP]" -<* >\r[00123456789] A\p[z0-9]"[oO][cC][tT]" -<* >\r[00123456789] A\p[z0-9]"[nN][oO][vV]" -<* >\r[00123456789] A\p[z0-9]"[dD][eE][cC]" - -# this will add the string '2010' at all places in the word: -# USE this with a 4 or 5 char dictionary file with ALL characters -# soo abcde will become -# 2010abcde a2010bcde ab2010cde acd2010de abcd2010e abcde2010 -;[List.Rules:KoreLogicRulesAdd2010Everywhere] -<* >\r[00123456789] A\p[z0-9]"201[0-9]" - -;[List.Rules:KoreLogicRulesAdd1234_Everywhere] -<* >\r[00123456789] A\p[z0-9]"1234" - -;[List.Rules:KoreLogicRulesAppendMonthDay] --[:c] <* Az"\p[jJ]anuary" --[:c] Az"\p[jJ]anuary[0-9]" <+ --[:c] Az"\p[jJ]anuary[0-9][0-9]" <+ --[:c] <* Az"\p[fF]ebruary" --[:c] Az"\p[fF]ebruary[0-9]" <+ --[:c] Az"\p[fF]ebruary[0-9][0-9]" <+ --[:c] <* Az"\p[mM]arch" --[:c] Az"\p[mM]arch[0-9]" <+ --[:c] Az"\p[mM]arch[0-9][0-9]" <+ --[:c] <* Az"\p[aA]pril" --[:c] Az"\p[aA]pril[0-9]" <+ --[:c] Az"\p[aA]pril[0-9][0-9]" <+ --[:c] <* Az"\p[mM]ay" --[:c] Az"\p[mM]ay[0-9]" <+ --[:c] Az"\p[mM]ay[0-9][0-9]" <+ --[:c] <* Az"\p[jJ]une" --[:c] Az"\p[jJ]une[0-9]" <+ -# There was a typo in Kore's original revision of this rule --[:c] Az"\p[jJ]une[0-9][0-9]" <+ --[:c] <* Az"\p[jJ]uly" --[:c] Az"\p[jJ]uly[0-9]" <+ --[:c] Az"\p[jJ]uly[0-9][0-9]" <+ --[:c] <* Az"\p[aA]ugust" --[:c] Az"\p[aA]ugust[0-9]" <+ --[:c] Az"\p[aA]ugust[0-9][0-9]" <+ --[:c] <* Az"\p[sS]eptember" --[:c] Az"\p[sS]eptember[0-9]" <+ -# There was a typo in Kore's original revision of this rule --[:c] Az"\p[sS]eptember[0-9][0-9]" <+ --[:c] <* Az"\p[oO]ctober" --[:c] Az"\p[oO]ctober[0-9]" <+ --[:c] Az"\p[oO]ctober[0-9][0-9]" <+ --[:c] <* Az"\p[nN]ovember" --[:c] Az"\p[nN]ovember[0-9]" <+ --[:c] Az"\p[nN]ovember[0-9][0-9]" <+ --[:c] <* Az"\p[dD]ecember" --[:c] Az"\p[dD]ecember[0-9]" <+ --[:c] Az"\p[dD]ecember[0-9][0-9]" <+ - -;[List.Rules:KoreLogicRulesAppendMonthCurrentYear] --[:c] <* Az"\p[jJ]an201[0-9]" --[:c] <* Az"\p[fF]eb201[0-9]" --[:c] <* Az"\p[mM]ar201[0-9]" --[:c] <* Az"\p[aA]pr201[0-9]" --[:c] <* Az"\p[mM]ay201[0-9]" --[:c] <* Az"\p[jJ]un201[0-9]" --[:c] <* Az"\p[jJ]ul201[0-9]" --[:c] <* Az"\p[Aa]ug201[0-9]" --[:c] <* Az"\p[sS]ep201[0-9]" --[:c] <* Az"\p[oO]ct201[0-9]" --[:c] <* Az"\p[nN]ov201[0-9]" --[:c] <* Az"\p[Dd]ec201[0-9]" - -;[List.Rules:KoreLogicRulesReplaceNumbers2Special] -/[1-90] s\0\p[!@#$%^&*()] -/1 /[2-90] s1! s\0\p[@#$%^&*()] -/2 /[3-90] s2@ s\0\p[#$%^&*()] -/3 /[4-90] s3# s\0\p[$%^&*()] -/4 /[5-90] s4$ s\0\p[%^&*()] -/5 /[6-90] s5% s\0\p[^&*()] -/6 /[7-90] s6^ s\0\p[&*()] -/7 /[890] s7& s\0\p[*()] -/8 /[90] s8* s\0\p[()] -/9 /0 s9( s0) - -;[List.Rules:KoreLogicRulesReplaceNumbers] -/0 s0[1-9] -/1 s1[02-9] -/2 s2[013-9] -/3 s3[0-24-9] -/4 s4[0-35-9] -/5 s5[0-46-9] -/6 s6[0-57-9] -/7 s7[0-68-9] -/8 s8[0-79] -/9 s9[0-8] -# 10 lines above can be replaced with just one: -# /[0-9] s\0[0-9] Q -# but it's slower (generates, then rejects some duplicates). - -# This is a lamer/faster version of --rules:nt -;[List.Rules:KoreLogicRulesReplaceLettersCaps] --c /[a-z] s\0\p[A-Z] - -;[List.Rules:KoreLogicRulesAddDotCom] --[c:] <- \p[c:] Az".com" --[c:] <- \p[c:] Az".net" --[c:] <- \p[c:] Az".org" - -;[List.Rules:KoreLogicRulesPrependJustSpecials] --[c:] \p[c:] ^[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] --[c:] \p[c:] A0q[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -;[List.Rules:KoreLogicRulesAppend1_AddSpecialEverywhere] --[c:] >4 <- \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $1 --[c:] >[5-8] <- \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $1 - -;[List.Rules:KoreLogicRulesAppendNum_AddSpecialEverywhere] -# This should probably use $[02-9] since we try $1 in -# KoreLogicRulesAppend1_AddSpecialEverywhere --[c:] >4 <- \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $[0-9] --[c:] >[5-8] <- \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] $[0-9] - -;[List.Rules:KoreLogicRulesAppendNumNum_AddSpecialEverywhere] --[c:] >4 \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"[0-9][0-9]" <+ --[c:] >[5-8] \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"[0-9][0-9]" <+ - -;[List.Rules:KoreLogicRulesAppendNumNumNum_AddSpecialEverywhere] --[c:] >4 \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"[0-9][0-9][0-9]" <+ --[c:] >[5-8] \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"[0-9][0-9][0-9]" <+ - -;[List.Rules:KoreLogicRulesAppendYears_AddSpecialEverywhere] --[c:] >4 \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"19[4-9][0-9]" <+ --[c:] >4 \p[c:] i[0-5][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"20[0-1][0-9]" <+ --[c:] >[5-8] \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"19[4-9][0-9]" <+ --[c:] >[5-8] \p1[c:] i\p2[6-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*] Az"20[0-1][0-9]" <+ - -# This rule needs work actually --- you have to 'sort -u' its output rick -# /a = reject if it doesnt have an 'a' -# the [:c] does waste some effort - and generate dupes. This is wasteful, -# but I want to keep it in b/c the original crack/JtR rules use it. -;[List.Rules:KoreLogicRulesL33t] --[:c] /\r[aaAAbBeEiiiIIIllll] s\0\r\p[@44@88331!|1!|17|!] \p1[:M] \p1[:c] \p1[:Q] -# The following line differs from Kore's erroneous 4 lines: --[:c] /\r[LLLL] s\0\r\p[17|!] \p1[:M] \p1[:c] \p1[:Q] -#/Lsl1[:c] -#/Lsl7[:c] -#/Lsl|[:c] -#/Lsl![:c] --[:c] /\r[oOssSStT1111003344557788] s\0\r\p[00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Full set (same as above, but on one line): -#-[:c] /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT1111003344557788] s\0\r\p[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Double substitutions start here. -# Compared to Kore's, we check for both chars first, then replace both. -# This produces different results from Kore's, which would replace all -# instances of the first char before checking for the second. -# Kore's behavior may be restored by moving "sa[@4]" to be right after "/a" -# on the line below, and ditto for further lines. --[:c] /a /\r[AAbBeEiiiIIIllllLLLLoOssSStT1111003344557788] sa[@4] s\2\r\p2[4@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Kore had these (probably unintentionally, so we don't duplicate them): -#/asa4/4s4a[:c] -#/asa4/4s4A[:c] --[:c] /A /\r[aabBeEiiiIIIllllLLLLoOssSStT1111003344557788] sA4 s\0\r\p[@488331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Kore also had these, but (intentionally?) missed sb8 on this set (after sA4) -#/AsA4/4s4a[:c] -#/AsA4/4s4A[:c] --[:c] /b /\r[aaAABeEiiiIIIllllLLLLoOssSStT1111003344557788] sb8 s\0\r\p[@44@8331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /B /\r[aaAAbeEiiiIIIllllLLLLoOssSStT1111003344557788] sB8 s\0\r\p[@44@8331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /e /\r[aaAAbBEiiiIIIllllLLLLoOssSStT1111003344557788] se3 s\0\r\p[@44@8831!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /E /\r[aaAAbBeiiiIIIllllLLLLoOssSStT1111003344557788] sE3 s\0\r\p[@44@8831!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /i /\r[aaAAbBeEIIIllllLLLLoOssSStT1111003344557788] si[1!|] s\2\r\p2[@44@88331!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /I /\r[aaAAbBeEiiillllLLLLoOssSStT1111003344557788] sI[1!|] s\2\r\p2[@44@88331!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# Kore's rules only included sl[17|], but not sl! --[:c] /l /\r[aaAAbBeEiiiIIILLLLoOssSStT1111003344557788] sl[17|!] s\2\r\p2[@44@88331|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -# All "/L" rules (171 lines) were buggy --[:c] /L /\r[aaAAbBeEiiiIIIlllloOssSStT1111003344557788] sl[17|!] s\2\r\p2[@44@88331|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /o /\r[aaAAbBeEiiiIIIllllLLLLOssSStT1111003344557788] so0 s\0\r\p[@44@88331!|1!|17|!17|!0$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /O /\r[aaAAbBeEiiiIIIllllLLLLossSStT1111003344557788] sO0 s\0\r\p[@44@88331!|1!|17|!17|!0$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /s /\r[aaAAbBeEiiiIIIllllLLLLoOSStT1111003344557788] ss[$5] s\2\r\p2[@44@88331!|1!|17|!17|!00$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /S /\r[aaAAbBeEiiiIIIllllLLLLoOsstT1111003344557788] sS[$5] s\2\r\p2[@44@88331!|1!|17|!17|!00$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /t /\r[aaAAbBeEiiiIIIllllLLLLoOssSST1111003344557788] st+ s\0\r\p[@44@88331!|1!|17|!17|!00$5$5+!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /T /\r[aaAAbBeEiiiIIIllllLLLLoOssSSt1111003344557788] sT+ s\0\r\p[@44@88331!|1!|17|!17|!00$5$5+!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /1 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT003344557788] s1[!iI|] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /0 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11113344557788] s0[oO] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|eEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /3 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110044557788] s3[eE] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] -#-[:c] /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT1111003344557788] s\0\r\p[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /4 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110033557788] s4[aA] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEsSlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /5 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110033447788] s5[sS] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAlLbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /7 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110033445588] s7[lL] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSbB] \p1[:M] \p1[:c] \p1[:Q] --[:c] /8 /\r[aaAAbBeEiiiIIIllllLLLLoOssSStT11110033445577] s8[bB] s\2\r\p2[@44@88331!|1!|17|!17|!00$5$5++!iI|oOeEaAsSlL] \p1[:M] \p1[:c] \p1[:Q] -# These are some popular triple/quad l33t rules --[:c] /a /e /[los] sa4 se3 s\0\p[10$] \p1[:M] \p1[:c] \p1[:Q] --[:c] /[ae] /l /[os] s\2\p2[43] sl1 s\3\p3[0$] \p1[:M] \p1[:c] \p1[:Q] --[:c] /[ae] /o /s s\2\p2[43] so0 ss$ \p1[:M] \p1[:c] \p1[:Q] --[:c] /l /o /s sl1 so0 ss$ \p1[:M] \p1[:c] \p1[:Q] --[:c] /a /e /l /[os] sa4 se3 sl1 s\0\p[0$] \p1[:M] \p1[:c] \p1[:Q] --[:c] /a /[el] /o /s sa4 s\0\p[31] so0 ss$ \p1[:M] \p1[:c] \p1[:Q] --[:c] /e /l /o /s se3 sl1 so0 ss$ \p1[:M] \p1[:c] \p1[:Q] --[:c] /a /e /l /o /s sa4 se3 sl1 so0 ss$ \p1[:M] \p1[:c] \p1[:Q] - -;[List.Rules:KoreLogicRulesReplaceSpecial2Special] -# Kore's rules were missing "*" -/! s![@#$%^&*()\-=_+\\|;:'",./?><] -/@ s@[!#$%^&*()\-=_+\\|;:'",./?><] -/# s#[!@$%^&*()\-=_+\\|;:'",./?><] -/$ s$[!@#%^&*()\-=_+\\|;:'",./?><] -/% s%[!@#$^&*()\-=_+\\|;:'",./?><] -/^ s^[!@#$%&*()\-=_+\\|;:'",./?><] -/& s&[!@#$%^*()\-=_+\\|;:'",./?><] -/( s([!@#$%^&*)\-=_+\\|;:'",./?><] -/) s([!@#$%^&*(\-=_+\\|;:'",./?><] -# Kore's ruleset erroneously had: -#/-s-- -/- s-[!@#$%^&*()=_+\\|;:'",./?><] -/= s=[!@#$%^&*()\-_+\\|;:'",./?><] -/_ s_[!@#$%^&*()\-=+\\|;:'",./?><] -/+ s+[!@#$%^&*()\-=_\\|;:'",./?><] -# Kore's rules did not replace backslash -/\\ s\\[!@#$%^&*()\-=_+|;:'",./?><] -/| s|[!@#$%^&*()\-=_+\\;:'",./?><] -/; s;[!@#$%^&*()\-=_+\\|:'",./?><] -/: s:[!@#$%^&*()\-=_+\\|;'",./?><] -/' s'[!@#$%^&*()\-=_+\\|;:",./?><] -/" s"[!@#$%^&*()\-=_+\\|;:',./?><] -/, s,[!@#$%^&*()\-=_+\\|;:'"./?><] -/. s.[!@#$%^&*()\-=_+\\|;:'",/?><] -// s/[!@#$%^&*()\-=_+\\|;:'",.?><] -/> s>[!@#$%^&*()\-=_+\\|;:'",./?<] -/< s<[!@#$%^&*()\-=_+\\|;:'",./?>] - -;[List.Rules:KoreLogicRulesReplaceLetters] -/a sa[b-z] -/b sb[ac-z] -/c sc[abd-z] -/d sd[a-ce-z] -/e se[a-df-z] -/f sf[a-eg-z] -/g sg[a-fh-z] -/h sh[a-gi-z] -/i si[a-hj-z] -/j sj[a-ik-z] -/k sk[a-jl-z] -/l sl[a-km-z] -/m sm[a-ln-z] -/n sn[a-mo-z] -/o so[a-np-z] -/p sp[a-oq-z] -/q sq[a-pr-z] -/r sr[a-qs-z] -/s ss[a-rt-z] -/t st[a-su-z] -/u su[a-tv-z] -/v sv[a-uw-z] -/w sw[a-vx-z] -/x sx[a-wyz] -/y sy[a-xz] -# Kore's ruleset was truncated after "/zszr" -/z sz[a-y] --c /[a-z] s\0[A-Z] - -;[List.Rules:KoreLogicRulesAppendSpecialNumberNumber] --[c:] \p[c:] Az"[!$@#%.][0-9][0-9]" <+ --[c:] \p[c:] Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9]q <+ - -;[List.Rules:KoreLogicRulesPrependNumNumAppendSpecial] --[c:] \p[c:] A0"[0-9][0-9]" <* $[!$@#%.] --[c:] \p[c:] A0"[0-9][0-9]" <* $[^&()_+\-={}|[\]\\;'":,/<>?`~*] - -;[List.Rules:KoreLogicRulesPrependNumNumSpecial] --[c:] \p[c:] A0"[0-9][0-9][!$@#%.]" --[c:] \p[c:] A0q[0-9][0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -;[List.Rules:KoreLogicRulesAppend2NumSpecial] --[c:] \p[c:] Az"[0-9][0-9][!$@#%.]" <+ --[c:] \p[c:] Azq[0-9][0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -;[List.Rules:KoreLogicRulesPrependDaysWeek] -A0"[Mm][oO0][nN][dD][aA4@][yY]" -A0"[Tt][uU][eE3][sS$][dD][aA4@][yY]" -A0"[Ww][eE3][dD][nN][eE3][sS$][dD][aA4@][yY]" -A0"[Tt][hH][uU][rR][sS$][dD][aA4@][yY]" -A0"[Ff][rR][iI1!][dD][aA4@][yY]" -A0"[Ss][aA4@][tT+][uU][rR][dD][aA4@][yY]" -A0"[Ss][uU][nN][dD][aA4@][yY]" - -;[List.Rules:KoreLogicRulesAppendNumbers_and_Specials_Simple-3] -## Add Number Number Special --[c:] \p[c:] Azq[0-9][0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ -## Add Special Number Number --[c:] \p[c:] Azq[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9]q <+ - -;[List.Rules:KoreLogicRulesPrependSpecialSpecialAppendNumber] --[c:] \p[c:] A0"[!$@#%.][!$@#%.]" <* $[0-9] --[c:] \p[c:] A0q[^&()_+\-={}|[\]\\;'":,/<>?`~*][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <* $[0-9] - -;[List.Rules:KoreLogicRulesAppend4Num] --[c:] \p[c:] Az"[0-9][0-9][0-9][0-9]" <+ - -;[List.Rules:KoreLogicRulesPrependNumNumNumNum] --[c:] \p[c:] A0"[0-9][0-9][0-9][0-9]" - -;[List.Rules:KoreLogicRulesPrepend2NumbersAppend2Numbers] --[c:] \p[c:] A0"[0-9][0-9]" <- Az"[0-9][0-9]" - -;[List.Rules:KoreLogicRulesPrependCAPCAPAppendSpecial] -A0"[A-Z][A-Z]" <* $[!$@#%.] -A0"[A-Z][A-Z]" <* $[^&()_+\-={}|[\]\\;'":,/<>?`~*] - -;[List.Rules:KoreLogicRulesAppendSpecialLowerLower] --[c:] \p[c:] AzQ[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][a-z][a-z]Q <+ - -# The last line of KoreLogicRulesAppendNumbers_and_Specials_Simple -;[List.Rules:KoreLogicRulesAppendNumbers_and_Specials_Simple-4] -# Add 100! ... 999! to the end --[c:] \p[c:] Azq[0-9][0-9][0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -;[List.Rules:KoreLogicRulesAppendSpecial3num] --[c:] \p[c:] Az"[!$@#%.][0-9][0-9][0-9]" <+ --[c:] \p[c:] Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9][0-9]q <+ - -;[List.Rules:KoreLogicRulesAppendSpecialNumberNumberNumber] --[c:] \p[c:] Az"[!$@#%.][0-9][0-9][0-9]" <+ --[c:] \p[c:] Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9][0-9]q <+ - -;[List.Rules:KoreLogicRulesAppend3NumSpecial] --[c:] \p[c:] Az"[0-9][0-9][0-9][!$@#%.]" <+ --[c:] \p[c:] Azq[0-9][0-9][0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -;[List.Rules:KoreLogicRulesPrependNumNum_AppendNumSpecial] --[c:] \p[c:] A0"[0-9][0-9]" Azq[0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -;[List.Rules:KoreLogicRulesAppendJustSpecials3Times] --[c:] \p[c:] Az"[!$@#%.][!$@#%.][!$@#%.]" <+ --[c:] \p[c:] Azq[!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -;[List.Rules:KoreLogicRulesAppendCap-Num_or_Special-Twice] --[c:] \p[c:] Az"[A-Z][0-9][0-9]" <+ --[c:] \p[c:] Azq[A-Z][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9]q <+ --[c:] \p[c:] Azq[A-Z][0-9][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ --[c:] \p[c:] Azq[A-Z][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*][!$@#%.^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ - -;[List.Rules:KoreLogicRulesPrependSpecialSpecialAppendNumbersNumber] --[c:] \p[c:] A0"[!$@#%.][!$@#%.]" <- Az"[0-9][0-9]" --[c:] \p[c:] A0q[^&()_+\-={}|[\]\\;'":,/<>?`~*][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <- Az"[0-9][0-9]" - -;[List.Rules:KoreLogicRulesAppend5Num] --[c:] \p[c:] Az"[0-9][0-9][0-9][0-9][0-9]" <+ - -;[List.Rules:KoreLogicRulesAppendSpecial4num] --[c:] \p[c:] Az"[!$@#%.][0-9][0-9][0-9][0-9]" <+ --[c:] \p[c:] Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*][0-9][0-9][0-9][0-9]q <+ - -;[List.Rules:KoreLogicRulesPrepend4NumAppendSpecial] --[c:] \p[c:] A0"[0-9][0-9][0-9][0-9]" <- $[!$@#%.] --[c:] \p[c:] A0"[0-9][0-9][0-9][0-9]" <- Azq[^&()_+\-={}|[\]\\;'":,/<>?`~*]q - -;[List.Rules:KoreLogicRulesAppend4NumSpecial] --[c:] \p[c:] Az"[0-9][0-9][0-9][0-9][!$@#%.]" <+ --[c:] \p[c:] Azq[0-9][0-9][0-9][0-9][^&()_+\-={}|[\]\\;'":,/<>?`~*]q <+ -;[List.Rules:KoreLogicRulesPrependSpecialSpecialAppendNumbersNumberNumber] --[c:] \p[c:] A0"[!$@#%.][!$@#%.]" Az"[0-9][0-9][0-9]" <+ --[c:] \p[c:] A0q[^&()_+\-={}|[\]\\;'":,/<>?`~*][^&()_+\-={}|[\]\\;'":,/<>?`~*]q Az"[0-9][0-9][0-9]" <+ - -;[List.Rules:KoreLogicRulesAppend6Num] --[c:] \p[c:] Az"[0-9][0-9][0-9][0-9][0-9][0-9]" <+ +# A variation of KnownForce configured to try likely date and time strings. +[List.External:DateTime] +int last; // Last character position, zero-based +int lastofs; // Last character position offset into charset[] +int lastid; // Current character index in the last position +int id[0x7f]; // Current character indices for other positions +int charset[0x7f00]; // Character sets, 0x100 elements for each position + +void init() +{ + int length; + int pos, ofs, i, c; + + length = 8; // Must be one of: 4, 5, 7, 8 + +/* This defines the character sets for different character positions */ + pos = 0; + while (pos < length - 6) { + ofs = pos++ << 8; + i = 0; + c = '0'; + while (c <= '9') + charset[ofs + i++] = c++; + charset[ofs + i] = 0; + } + if (pos) { + ofs = pos++ << 8; + charset[ofs] = '/'; + charset[ofs + 1] = '.'; + charset[ofs + 2] = ':'; + charset[ofs + 3] = 0; + } + while (pos < length - 3) { + ofs = pos++ << 8; + i = 0; + c = '0'; + while (c <= '9') + charset[ofs + i++] = c++; + charset[ofs + i] = 0; + } + ofs = pos++ << 8; + charset[ofs] = '/'; + charset[ofs + 1] = '.'; + charset[ofs + 2] = ':'; + charset[ofs + 3] = 0; + while (pos < length) { + ofs = pos++ << 8; + i = 0; + c = '0'; + while (c <= '9') + charset[ofs + i++] = c++; + charset[ofs + i] = 0; + } + + last = length - 1; + pos = -1; + while (++pos <= last) + word[pos] = charset[id[pos] = pos << 8]; + lastid = (lastofs = last << 8) - 1; + word[pos] = 0; +} + +void generate() +{ + int pos; + +/* Handle the typical case specially */ + if (word[last] = charset[++lastid]) return; + + word[pos = last] = charset[lastid = lastofs]; + while (pos--) { // Have a preceding position? + if (word[pos] = charset[++id[pos]]) return; + word[pos] = charset[id[pos] = pos << 8]; + } + + word = 0; // We're done +} + +void restore() +{ + int i, c; + +/* Calculate the current length and infer the character indices */ + last = 0; + while (c = word[last]) { + i = lastofs = last << 8; + while (charset[i] != c && charset[i]) i++; + if (!charset[i]) i = lastofs; // Not found + id[last++] = i; + } + lastid = id[--last]; +} + +# Try strings of repeated characters. +# +# This is the code which is common for all [List.External:Repeats*] +# sections which include this External_base section. +# The generate() function will limit the maximum length of generated +# candidates to either the format's limit (maximum password length) +# or to the limit specified with --stdout=LENGTH (Default: 125), +# thus avoiding duplicate candidates for formats with limited maximum +# passwortd length. +# The comparison of the current length and the limit is only done +# after switching to a new length. +# So, if the minimum length specified already exceeds this limit, +# then all the candidates for the minimum length will be generated +# nevertheless. +[List.External_base:Repeats] +int minlength, maxlength, minc, maxc, length, c; + +void generate() +{ + int i; + + i = 0; + while (i < length) + word[i++] = c; + word[i] = 0; + + if (c++ < maxc) + return; + + c = minc; + + if (++length > maxlength) + c = 0; // Will NUL out the next "word" and thus terminate +} + +# Try strings of repeated characters (range: space - 0xff). +[List.External:Repeats] +.include [List.External_base:Repeats] +void init() +{ + if (req_minlen) + minlength = req_minlen; + else + minlength = 1; + if (req_maxlen) + maxlength = req_maxlen; + else + maxlength = cipher_limit; // the format's limit + minc = 0x20; + maxc = 0xff; + + length = minlength; c = minc; +} + +# Try strings of repeated digits (range: '0' - '9'). +[List.External:Repeats_digits] +.include [List.External_base:Repeats] +void init() +{ + if (req_minlen) + minlength = req_minlen; + else + minlength = 1; + if (req_maxlen) + maxlength = req_maxlen; + else + maxlength = cipher_limit; // the format's limit + minc = '0'; + maxc = '9'; + + length = minlength; c = minc; +} + +# Try strings of repeated lowercase letters (range: 'a' - 'z'). +[List.External:Repeats_lowercase] +.include [List.External_base:Repeats] +void init() +{ + if (req_minlen) + minlength = req_minlen; + else + minlength = 1; + if (req_maxlen) + maxlength = req_maxlen; + else + maxlength = cipher_limit; // the format's limit + minc = 'a'; + maxc = 'z'; + + length = minlength; c = minc; +} + +# Try strings of repeated printable ASCII characters +# (range: ' ' - '~'). +[List.External:Repeats_printable_ASCII] +.include [List.External_base:Repeats] +void init() +{ + if (req_minlen) + minlength = req_minlen; + else + minlength = 1; + if (req_maxlen) + maxlength = req_maxlen; + else + maxlength = cipher_limit; // the format's limit + minc = ' '; + maxc = '~'; + + length = minlength; c = minc; +} + +# Try character sequences ("0123456", "acegikmoqs", "ZYXWVU", etc.). +# +# The generate() function will limit the maximum length of generated +# candidates to either the format's limit (maximum password length) +# or to the limit specified with --stdout=LENGTH (Default: 125), +# thus avoiding duplicate candidates for formats with limited maximum +# passwortd length. +# The comparison of the current length and the limit is only done +# after switching to a new length. +# So, if the minimum length specified already exceeds this limit, +# then all the candidates for the minimum length will be generated +# nevertheless. +# External modes reusing this External_base mode should only need to +# adjust the init() function. +# In the init() function, a minimum length which is > 1 should be +# specified. +# Otherwise, the generated candidates will not depend on the increment +# specified. +# For length = 1, the candidates will be the same as for external mode +# Repeats with length 1. +# Actually, Repeats is a special case of Sequence, using increment = 0. +# External modes reusing this External_base mode should also make sure +# that the number of different characters (specified as a range from "from" +# to "to") is not smaller than the minimum length ("minlength"), +# if the start increment "inc" is 1. +# For a start increment > 1, the number of different characters in the +# range "from" - "to" must be greater than or equal to +# (1 + ("minlength" - 1) * "inc"). +# Otherwise you might get unexpected results. +# The range of characters to be used for the sequences needs to be +# specified by adjusting the "from" and "to" variables. +# To generate sequences which decrement characters ("987654"), +# "from" must be > "to". +# Otherwise, the generated sequences will increment characters ("abcdef"). +# +# Variables to be used and the generate() function are common +# for all sections which include this External_base section. +[List.External_base:Sequence] +/* + * See the [List.External:Sequence_0-9] section to learn more about + * the meaning of these variables which can be adjusted to define + * new external modes based on an existing one: + */ +int minlength, from, to, maxlength, inc, direction; + +/* + * The value of these variables shouldn't be changed when copying + * an existing external mode: + */ +int length, first; + +void generate() +{ + int i; + + i = 0; + + while (i < length) { + word[i] = first + (i * inc * direction); + ++i; + } + word[i] = 0; + + // start the next sequence of the same length + // with the next character + first = first + direction; + + // But check that a sequence of the current length + // is still possible (without leaving the range of + // characters allowed + if ((direction > 0 && first + (length - 1) * inc > to) || + (direction < 0 && first - (length - 1) * inc < to)) { + // No more sequence is possible. Reset start character + first = from; + // Now try the next length. + // But just in case an individual External mode reusing + // this External_base mode did specify a maxlength + // which is larger than the one supported by the format + // or by --stdout=LENGTH, make sure no more candidates + // are generated. + // Checking this just once per length per increment + // doen't really hurt performance. + if (maxlength > cipher_limit) + maxlength = cipher_limit; + + // For a similar reason, the maximum length of a + // sequence is limited by the number of different + // characters and by the increment. + // The larger the increment, the smaller + // the maximum possible length for a given + // character range. + while (inc * (maxlength - 1) > direction * (to - from)) + --maxlength; + + if (++length > maxlength) { + // The maximum length for this increment has been reached. + // Restart at minimum length with the next possible + // increment + ++inc; + // Unfortunately, we have to check again + // if the maximum length needs to be reduced + // for the new increment + while (inc * (maxlength - 1) > direction * (to - from)) + --maxlength; + + length = minlength; + } + if (maxlength < minlength) + // With the current increment, we can't even generate + // sequences of the minimum required length. + // So we need to stop here. + // This will make sure that no more candidiates + // will be generated: + first = 0; + } +} + +# Try sequences of digits (range: '0' - '9'). +# +# Aditional comments can be found in the +# section [List.External_base:Sequence] +# +# This external mode is thoroughly commented, +# to make it easier to copy and adjust it as needed. +[List.External:Sequence_0-9] +.include [List.External_base:Sequence] +void init() +{ + // Adjust the following 4 variables if you want to define + // a different external mode. + + // This is the start character for the generated sequence + // if "from" is smaller than "to", the increment from + // first to second character ... will be positive ("0123456789"). + // Otherwise, it will be negative ("987654321"). + from = '0'; + to = '9'; + + // minimum length of the sequence + // make sure it is not larger than the number of different characters + // in the range between "from" and "to" specified above + minlength = 2; + + // start increment for generating the sequence, usually 1 + // if it is larger than 1, you need even more characters + // in the range between "from" and "to" + // Don't specify a negative value here. + // If you want to generate sequences like "zyxwvu" or "86420", + // adjust "from" and "to" so that "from" is larger than "to". + // (A start increment of 0 is also possible, in that case the first + // sequences will be candidates which just repeat the same character.) + inc = 1; + + // For copied external modes, no further changes should be required + // in the statements following this comment + + length = minlength; + first = from; + + if (from <= to) { + maxlength = to - from + 1; + direction = 1; + } else { + // We have to create sequences which decrement the previous character + maxlength = from - to + 1; + direction = -1; + } +} + +# Try sequence of lower case letters (range: 'a' - 'z'). +# This external mode is not very well documented. +# Refer to [List.External:Sequence_0-9] for more detailed information. +[List.External:Sequence_a-z] +.include [List.External_base:Sequence] +void init() +{ + from = 'a'; + to = 'z'; + minlength = 2; + inc = 1; + + length = minlength; + first = from; + + if (from <= to) { + maxlength = to - from + 1; + direction = 1; + } else { + maxlength = from - to + 1; + direction = -1; + } +} + +# Try sequence of lower case letters (range: 'a' - 'z'), but reversed +# ("zxywvu"). +# This external mode is not very well documented. +# Refer to [List.External:Sequence_0-9] for more detailed information. +[List.External:Sequence_z-a] +.include [List.External_base:Sequence] +void init() +{ + from = 'z'; + to = 'a'; + minlength = 2; + inc = 1; + + length = minlength; + first = from; + + if (from <= to) { + maxlength = to - from + 1; + direction = 1; + } else { + maxlength = from - to + 1; + direction = -1; + } +} + +# Try sequence of printable ASCII characters (range: ' ' - '~'). +# This external mode is not very well documented. +# Refer to [List.External:Sequence_0-9] for more detailed information. +[List.External:Sequence_printable_ascii] +.include [List.External_base:Sequence] +void init() +{ + from = ' '; + to = '~'; + minlength = 2; + inc = 1; + + length = minlength; + first = from; + + if (from <= to) { + maxlength = to - from + 1; + direction = 1; + } else { + maxlength = from - to + 1; + direction = -1; + } +} + +# Try sequence of printable ASCII characters (range: ' ' - '~'), +# but decrementing characters ("fedcba") instead of incrementing. +# This external mode is not very well documented. +# Refer to [List.External:Sequence_0-9] for more detailed information. +[List.External:Sequence_reversed_ascii] +.include [List.External_base:Sequence] +void init() +{ + from = '~'; + to = ' '; + minlength = 2; + inc = 1; + + length = minlength; + first = from; + + if (from <= to) { + maxlength = to - from + 1; + direction = 1; + } else { + maxlength = from - to + 1; + direction = -1; + } +} + +# Try sequence of characters (range: space - 0xff). +# This external mode is not very well documented. +# Refer to [List.External:Sequence_0-9] for more detailed information. +[List.External:Sequence] +.include [List.External_base:Sequence] +void init() +{ + from = ' '; + to = 0xff; + minlength = 2; + inc = 1; + + length = minlength; + first = from; + + if (from <= to) { + maxlength = to - from + 1; + direction = 1; + } else { + maxlength = from - to + 1; + direction = -1; + } +} + + +# Generate candidate passwords from many small subsets of characters from a +# much larger full character set. This will test for passwords containing too +# few different characters. As currently implemented, this code will produce +# some duplicates, although their number is relatively small when the maximum +# number of different characters (the maxdiff setting) is significantly lower +# than the maximum length (the maxlength setting). Nevertheless, you may want +# to pass the resulting candidate passwords through "unique" if you intend to +# test them against hashes that are salted and/or of a slow to compute type. +[List.External:Subsets] +int minlength; // Minimum password length to try +int maxlength; // Maximum password length to try +int startdiff; // Initial number of characters in a subset to try +int maxdiff; // Maximum number of characters in a subset to try +int last; // Last character position, zero-based +int lastid; // Character index in the last position +int id[0x7f]; // Current character indices for other positions +int subset[0x100], c0; // Current subset +int subcount; // Number of characters in the current subset +int subid[0x100]; // Indices into charset[] of characters in subset[] +int charset[0x100]; // Full character set +int charcount; // Number of characters in the full charset + +void init() +{ + int i, c; + + // Minimum password length to try, must be at least 1 + if (req_minlen) + minlength = req_minlen; + else + minlength = 1; + + // Maximum password length to try, must be at least same as minlength + // This external mode's default maximum length can be adjusted + // using --max-length= on the command line + if (req_maxlen) + maxlength = req_maxlen; + else + maxlength = 8; + + // "cipher_limit" is the variable which contains the format's + // maximum password length + if (maxlength > cipher_limit) + maxlength = cipher_limit; + + startdiff = 1; // Initial number of different characters to try + maxdiff = 3; // Maximum number of different characters to try + +/* This defines the character set */ + i = 0; + c = 0x20; + while (c <= 0x7e) + charset[i++] = c++; + + if (maxdiff > (charcount = i)) + maxdiff = i; + if (maxdiff > maxlength) + maxdiff = maxlength; + +/* + * Initialize the variables such that generate() gets to its "next subset" + * code, which will initialize everything for real. + */ + subcount = (i = startdiff) - 1; + while (i--) + subid[i] = charcount; + subset[0] = c0 = 0; + last = maxlength - 1; + lastid = -1; +} + +void generate() +{ + int i; + +/* Handle the typical case specially */ + if (word[last] = subset[++lastid]) return; + + lastid = 0; + word[i = last] = c0; + while (i--) { // Have a preceding position? + if (word[i] = subset[++id[i]]) return; + id[i] = 0; + word[i] = c0; + } + + if (++last < maxlength) { // Next length? + id[last] = lastid = 0; + word[last] = c0; + word[last + 1] = 0; + return; + } + +/* Next subset */ + if (subcount) { + int j; + i = subcount - 1; + j = charcount; + while (++subid[i] >= j) { + if (i--) { + j--; + continue; + } + subid[i = 0] = 0; + subset[++subcount] = 0; + break; + } + } else { + subid[i = 0] = 0; + subset[++subcount] = 0; + } + subset[i] = charset[subid[i]]; + while (++i < subcount) + subset[i] = charset[subid[i] = subid[i - 1] + 1]; + + if (subcount > maxdiff) { + word = 0; // Done + return; + } + +/* + * We won't be able to fully use the subset if the length is smaller than the + * character count. We assume that we've tried all smaller subsets before, so + * we don't bother with such short lengths. + */ + if (minlength < subcount) + last = subcount - 1; + else + last = minlength - 1; + c0 = subset[0]; + i = 0; + while (i <= last) { + id[i] = 0; + word[i++] = c0; + } + lastid = 0; + word[i] = 0; +} + +# Simple password policy matching: require at least one digit. +[List.External:AtLeast1-Simple] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if (c >= '0' && c <= '9') + return; // Found at least one suitable character, good + + word = 0; // No suitable characters found, skip this "word" +} + +# The same password policy implemented in a more efficient and more generic +# fashion (easy to expand to include other "sufficient" characters as well). +[List.External:AtLeast1-Generic] +int mask[0x100]; + +void init() +{ + int c; + + mask[0] = 0; // Terminate the loop in filter() on NUL + c = 1; + while (c < 0x100) + mask[c++] = 1; // Continue looping in filter() on most chars + + c = '0'; + while (c <= '9') + mask[c++] = 0; // Terminate the loop in filter() on digits +} + +void filter() +{ + int i; + + i = -1; + while (mask[word[++i]]) + continue; + if (word[i]) + return; // Found at least one suitable character, good + + word = 0; // No suitable characters found, skip this "word" +} + +# An efficient and fairly generic password policy matcher. The policy to match +# is specified in the check at the end of filter() and in mask[]. For example, +# lowercase and uppercase letters may be treated the same by initializing the +# corresponding mask[] elements to the same value, then adjusting the value to +# check "seen" for accordingly. +[List.External:Policy] +int mask[0x100]; + +void init() +{ + int c; + + mask[0] = 0x100; + c = 1; + while (c < 0x100) + mask[c++] = 0x200; + + c = 'a'; + while (c <= 'z') + mask[c++] = 1; + c = 'A'; + while (c <= 'Z') + mask[c++] = 2; + c = '0'; + while (c <= '9') + mask[c++] = 4; +} + +void filter() +{ + int i, seen; + +/* + * This loop ends when we see NUL (sets 0x100) or a disallowed character + * (sets 0x200). + */ + i = -1; seen = 0; + while ((seen |= mask[word[++i]]) < 0x100) + continue; + +/* + * We should have seen at least one character of each type (which "add up" + * to 7) and then a NUL (adds 0x100), but not any other characters (would + * add 0x200). The length must be 8. + */ + if (seen != 0x107 || i != 8) + word = 0; // Does not conform to policy +} + +# Append the Luhn algorithm digit to arbitrary all-digit strings. Optimized +# for speed, not for size nor simplicity. The primary optimization trick is to +# compute the length and four sums in parallel (in two SIMD'ish variables). +# Then whether the length is even or odd determines which two of the four sums +# are actually used. Checks for non-digits and for NUL are packed into the +# SIMD'ish bitmasks as well. +[List.External:AppendLuhn] +int map1[0x100], map2[0x1fff]; + +void init() +{ + int i; + + map1[0] = ~0x7fffffff; + i = 1; + while (i < 0x100) + map1[i++] = ~0x7effffff; + i = -1; + while (++i < 10) + map1['0' + i] = i + ((i * 2 % 10 + i / 5) << 12); + i = -1; + while (++i < 0x1fff) { + if (i % 10) + map2[i] = '9' + 1 - i % 10; + else + map2[i] = '0'; + } +} + +void filter() +{ + int i, o, e; + + i = o = e = 0; + while ((o += map1[word[i++]]) >= 0) { + if ((e += map1[word[i++]]) >= 0) + continue; + if (e & 0x01000000) + return; // Not all-digit, leave unmodified + word[i--] = 0; + word[i] = map2[(e & 0xfff) + (o >> 12)]; + return; + } + if (o & 0x01000000) + return; // Not all-digit, leave unmodified + word[i--] = 0; + word[i] = map2[(o & 0xfff) + (e >> 12)]; +} + +# Trivial Rotate function, which rotates letters in a word +# by a given number of places (like 13 in case of ROT13). +# Words which don't contain any letters (and thus wouldn't be changed +# by this filter) are skipped, because these unchanged words probably +# should have been tried before trying a mangled version. +[List.External_base:Filter_Rotate] + +int rot; // The number of places to rotate each letter in a word + +void filter() +{ + int i, j, c; + + i = 0; + j = 0; // j counts the number of changed characters + + while (c = word[i]) { + if (c >= 'a' && c <= 'z') { + c = c - 26 + rot; + if (c < 'a') c += 26; + word[i] = c; + j++; + } else if (c >= 'A' && c <= 'Z' ) { + c = c - 26 + rot; + if (c < 'A') c += 26; + word[i] = c; + j++; + } + i++; + } + if (j == 0) + // Nothing changed. Reject this word. + word = 0; +} + +# ROT13 Example +[List.External:Filter_ROT13] +.include [List.External_base:Filter_Rotate] +void init() +{ + // Just in case someone wants to "rotate" by other values, + // adjust the value of the rot variable + // (may be in a copied external mode): + // 13: "abcABCxyzXYZ" -> "nopNOPklmKLM" + // 1: "abcABCxyzXYZ" -> "bcdBCDyzaYZA" + // 25: "abcABCxyzXYZ" -> "zabZABwxyWXY" + // -1: "abcABCxyzXYZ" -> "zabZABwxyWXY" + // and so on + // Allowed range: -25 <= rot <= -1, or 1 <= rot <= 25 + rot = 13; + + // Don't change the following statement. + // It is supposed to "sanitize" the value to be in the + // range + rot = (rot + 26) % 26; +} + +# Trivial parallel processing example (obsoleted by the "--node" option) +[List.External:Parallel] +/* + * This word filter makes John process some of the words only, for running + * multiple instances on different CPUs. It can be used with any cracking + * mode except for "single crack". Note: this is not a good solution, but + * is just an example of what can be done with word filters. + */ + +int node, total; // This node's number, and node count +int number; // Current word number + +void init() +{ + node = 1; total = 2; // Node 1 of 2, change as appropriate + number = node - 1; // Speedup the filter a bit +} + +void filter() +{ + if (number++ % total) // Word for a different node? + word = 0; // Yes, skip it +} + +# Interrupt the cracking session after "max" words tried +[List.External:AutoAbort] +int max; // Maximum number of words to try +int number; // Current word number + +void init() +{ + max = 1000; + number = 0; +} + +void filter() +{ + if (++number > max) + abort = 1; // Interrupt the cracking session +} + +# Print the status line after every "interval" words tried +[List.External:AutoStatus] +int interval; // How often to print the status +int number; // Current word number + +void init() +{ + interval = 1000; + number = 0; +} + +void filter() +{ + if (number++ % interval) + return; + status = 1; // Print the status line +} + +# +# Reference example hybrid-mode external. same as jtr-rule: $[0-9]$[0-9] +# this format is to be used similar to a filter, in that it requires some +# other word generator (markov, wordlist, etc). However, this type external +# will get new() called with each word, and then have next() called, until +# the word[0]=0 is seen (meaning all candidates for the base word have been +# generated. Prior to new() or restore(), word[] is the 'base' word. +# if the script is able to properly resume, then it should set the global +# variable hybrid_total to the count of candidates that will be generated +# for this word (in new() / restore(), then in the body of restore() there +# is a global variable set 'hybrid_resume' that was the prior number of +# canidates generated for this base-word. Resume should start at the NEXT +# If the script is not able to easily resume, then simply do NOT set the +# global hybrid_total to anything either function. JtR will 'still' resume +# propery, but it will do so by calling new()/next()/next().../next() until +# back to the proper resume location. +# +# script changed to append a _ character before the number, each time within +# the next() function. Done this way to better validate that -restore within +# jtr is working properly. +# +[List.External:Hybrid_example] +/* static vars for the script */ +int cnt, length, total; + +void init() +{ + /* in this simple example, we always generate 100 candidates per word */ + total = 100;/* this is a VERY simple example */ +} + +/* new word */ +void new() +{ + /* get the word length) */ + length = 0; while (word[length++]) ; --length; + + /* + * If this was a more complex script, we would compute total candidates + * at this location, if we can. If we can not compute total candidates + * then it is likely we can not resume 'easily', so if that is the + * case, we would simply set hybrid_total to -1, or do nothing, since + * do_external_hybrid_crack() sets it to -1 before calling this function. + */ + hybrid_total = total; + + /* Reset or counter for THIS word. */ + cnt = 0; + + /* + * word will be too long to be used, or too short to be used. If so + * then set hybrid_total to 0 and this entire word will be skipped. + */ + if (req_minlen > length - 2 || (req_maxlen && req_maxlen < length + 2)) + hybrid_total = 0; +} + +void next() +{ + /* in this simple script, if cnt is 100, this word is DONE */ + if (cnt == 100) { + word[0] = 0; + return; + } + + /* set word[] to the next candidate */ + word[length++] = '_'; + word[length ] = '0' + cnt / 10; + word[length+1] = '0' + cnt % 10; + word[length+2] = 0; + ++cnt; +} + +/* Called when restoring an interrupted session */ +void restore() +{ + int i; + + length = 0; while (word[length++]) ; --length; + + /* for this simple script, simply setting cnt resumes */ + cnt = hybrid_resume + 1; if (cnt > 100) cnt=100; + i = 0; + while (i++ < cnt) word[length++] = '_'; + word[length] = 0; + + /* tell john that we have properly 'resumed', by setting a 'proper' total */ + hybrid_total = total; +} + +# External hybrid 'leet code +[List.External:Leet] +/* + * 1337 language in this script: + * a -> a4@ + * b -> b8 + * e -> e3 + * g -> g9 + * i -> i1! + * l -> l1 + * o -> o0 + * s -> s$5 + * t -> t7 + */ + +int rotor[626]; /* max length input is 125 bytes [125*5+1]; */ +int rotors[125]; +int rotor_ptr[125]; +int rotor_idx[125]; +int rotor_cnt[125]; +int current_word_count; +int max_mangle; /* controls how many bytes we run through our 'leet' code */ +int max_mangle_letters; +int original_word; /* if set to 1 then we start with original word. If 0, then start with first mangled word */ + +void init() +{ + /* note, 3^10 is 59k so aaaaaaaaaa will produce that many words! */ + max_mangle_letters = 10; /* only mangle 10 characters max */ + max_mangle = 4000; /* Stop building new letters if our count goes over this value */ + original_word = 0; +} + +/* new word */ +void new() +{ + int rotor_off, idx, wlen; + idx = rotor_off = wlen = 0; + hybrid_total = 1; + while (word[wlen++]) ; --wlen; + if (req_minlen > wlen || (req_maxlen && req_maxlen < wlen )) { + hybrid_total = 0; + return; + } + wlen = 0; + while (word[wlen] && idx < max_mangle_letters && hybrid_total < max_mangle) { + rotor_cnt[wlen] = rotor_idx[wlen] = 0; + rotor_ptr[wlen] = rotor_off; + if (word[wlen] == 'a') { + rotor[rotor_off++] = 'a'; + rotor[rotor_off++] = '4'; + rotor[rotor_off++] = '@'; + } + else if (word[wlen] == 'b') { + rotor[rotor_off++] = 'b'; + rotor[rotor_off++] = '8'; + } + else if (word[wlen] == 'e') { + rotor[rotor_off++] = 'e'; + rotor[rotor_off++] = '3'; + } + else if (word[wlen] == 'g') { + rotor[rotor_off++] = 'g'; + rotor[rotor_off++] = '9'; + } + else if (word[wlen] == 'i') { + rotor[rotor_off++] = 'i'; + rotor[rotor_off++] = '1'; + rotor[rotor_off++] = '!'; + } + else if (word[wlen] == 'l') { + rotor[rotor_off++] = 'l'; + rotor[rotor_off++] = '1'; + } + else if (word[wlen] == 'o') { + rotor[rotor_off++] = 'o'; + rotor[rotor_off++] = '0'; + } + else if (word[wlen] == 's') { + rotor[rotor_off++] = 's'; + rotor[rotor_off++] = '$'; + rotor[rotor_off++] = '5'; + } + else if (word[wlen] == 't') { + rotor[rotor_off++] = 't'; + rotor[rotor_off++] = '7'; + } + if (rotor_off > rotor_ptr[wlen]) { + rotor_cnt[wlen] = rotor_off-rotor_ptr[wlen]; + hybrid_total *= rotor_cnt[wlen]; + rotors[idx++] = wlen; + } + ++wlen; + } + /* hybrid_total+666 is our indicator that this is the original word */ + if (original_word) + current_word_count = hybrid_total+666; + else { + current_word_count = 1; /* skip the 'original' word */ + } +} + +/* next iteration of this word word */ +void next() +{ + int idx, idx2; + if (current_word_count >= hybrid_total) { + if (current_word_count == hybrid_total+666) { + /* first word (starting word) we leave alone */ + /* by making it > hybrid_total, we avoid a 2nd if statement */ + current_word_count = 1; + return; + } + word[0] = 0; + return; + } + idx = rotors[idx2=0]; + while (++rotor_idx[idx] >= rotor_cnt[idx]) { + rotor_idx[idx] = 0; + word[idx] = rotor[ rotor_ptr[idx] ]; + idx = rotors[++idx2]; + } + word[idx] = rotor[ rotor_ptr[idx]+rotor_idx[idx] ]; + ++current_word_count; +} +/* restore() not needed. john properly restores fast enough without it */ + +# External hybrid CaSE mutation code +[List.External:Case] + +int rotor[251]; /* max length input is 125 bytes [125*5+1]; */ +int rotors[125]; +int rotor_ptr[125]; +int rotor_idx[125]; +int rotor_cnt[125]; +int current_word_count; +int max_mangle; /* controls how many bytes we run through our 'leet' code */ +int original_word; /* if set to 1 then we start with original word. If 0, then start with first mangled word */ + +void init() +{ + max_mangle = 20; /* only mangle 20 characters max (2^20 is 1 million) */ + original_word = 1; /* for case mangle, unless the data is 100% lower case, we really can not skip the original word */ +} + +/* new word */ +void new() +{ + int rotor_off, idx, wlen, ch; + idx = rotor_off = wlen = 0; + hybrid_total = 1; + while (word[wlen++]) ; --wlen; + if (req_minlen > wlen || (req_maxlen && req_maxlen < wlen )) { + hybrid_total = 0; + return; + } + wlen = 0; + while (word[wlen] && idx < max_mangle) { + rotor_cnt[wlen] = rotor_idx[wlen] = 0; + rotor_ptr[wlen] = rotor_off; + ch = word[wlen]; + if (ch >= 'A' && ch <= 'Z') { + ch += 0x20; + word[wlen] = ch; + rotor[rotor_off++] = ch; + rotor[rotor_off++] = ch-0x20; + } + if (ch >= 'a' && ch <= 'z') { + rotor[rotor_off++] = ch; + rotor[rotor_off++] = ch-0x20; + rotor_cnt[wlen] = 2; + hybrid_total *= 2; + rotors[idx++] = wlen; + } + ++wlen; + } + /* hybrid_total+666 is our indicator that this is the original word */ + if (original_word) + current_word_count = hybrid_total+666; + else { + current_word_count = 1; /* skip the 'original' word */ + } +} + +/* next iteration of this word word */ +void next() +{ + int idx, idx2; + if (current_word_count >= hybrid_total) { + if (current_word_count == hybrid_total+666) { + /* first word (starting word) we leave alone */ + /* by making it > hybrid_total, we avoid a 2nd if statement */ + current_word_count = 1; + return; + } + word[0] = 0; + return; + } + idx = rotors[idx2=0]; + while (++rotor_idx[idx] >= rotor_cnt[idx]) { + rotor_idx[idx] = 0; + word[idx] = rotor[ rotor_ptr[idx] ]; + idx = rotors[++idx2]; + } + word[idx] = rotor[ rotor_ptr[idx]+rotor_idx[idx] ]; + ++current_word_count; +} +/* restore() not needed. john properly restores fast enough without it */ + +# Alternate hybrid external 'leet' mode (HybridLeet) +.include + +# dumb-force UTF-16, in an external file +.include + +# dumb-force UTF-32, in an external file +.include + +# repeats UTF-16, in an external file +.include + +# repeats UTF-32, in an external file +.include + +# Dynamic ($dynamic_n$) scripting code, in an external file +.include + +# Regex alphabets +.include + +# NOTE, this file (john.local.conf) is deprecated. If you had any modified logic in this +# file, please create and move it to john-local.conf. The file simply can be renamed to +# the new john-local.conf if you so choose. +.include '$JOHN/john.local.conf' + +# include john-local.conf (This file can be created by user, to override defaults in this john.conf file) +.include '$JOHN/john-local.conf' + +# include john-local.conf in local dir, it can override john.conf, john-local.conf (or any other conf file loaded) +.include './john-local.conf' + +# End of john.conf file. +# Keep this comment, and blank line above it, to make sure a john-local.conf +# that does not end with \n is properly loaded. diff --git a/dotfiles/vimrc b/dotfiles/vimrc index 50ca7e3..7a559a4 100644 --- a/dotfiles/vimrc +++ b/dotfiles/vimrc @@ -8,6 +8,7 @@ if filereadable(glob("~/.vim/bundle/Vundle.vim/README.md")) call vundle#begin() Plugin 'gmarik/Vundle.vim' Plugin 'nvie/vim-flake8' + Plugin 'tell-k/vim-autopep8' Plugin 'tpope/vim-fugitive' Plugin 'mileszs/ack.vim' Plugin 'tpope/vim-unimpaired' @@ -18,6 +19,7 @@ if filereadable(glob("~/.vim/bundle/Vundle.vim/README.md")) Plugin 'altercation/vim-colors-solarized' Plugin 'vimoutliner/vimoutliner' Plugin 'PotatoesMaster/i3-vim-syntax' + Plugin 'Matt-Deacalion/vim-systemd-syntax' call vundle#end() endif diff --git a/dotfiles/zsh_custom/plugins/jekyll/jekyll.plugin.zsh b/dotfiles/zsh_custom/plugins/jekyll/jekyll.plugin.zsh index 05c791b..ad86862 100644 --- a/dotfiles/zsh_custom/plugins/jekyll/jekyll.plugin.zsh +++ b/dotfiles/zsh_custom/plugins/jekyll/jekyll.plugin.zsh @@ -1,4 +1,14 @@ -JEKYLL_DIR=${JEKYLL_DIR:-${HOME}/Projects/blog} +function _jekyll_locate_dir { + if [[ -n "${JEKYLL_DIR}" && -f "${JEKYLL_DIR}" ]] ; then + echo ${JEKYLL_DIR} + elif test -f `pwd`/_config.yml ; then + pwd + elif test -f ${HOME}/Projects/blog/_config.yml ; then + echo ${HOME}/Projects/blog + else + echo "Jekyll instance not found!" >&2 + fi +} function _jekyll_set_date { local FILENAME @@ -11,20 +21,24 @@ function _jekyll_set_date { function _jekyll_find_post { local files local fname + local jekyll_dir + + jekyll_dir="${3}" + if [ -f "${1}" ] ; then printf -- "${1}" return 0 fi - if [ -f "${JEKYLL_DIR}/_posts/${1}" ] ; then - printf -- "${JEKYLL_DIR}/_posts/${1}" + if [ -f "${jekyll_dir}/_posts/${1}" ] ; then + printf -- "${jekyll_dir}/_posts/${1}" return 0 fi - if [ -f "${JEKYLL_DIR}/_drafts/${1}" ] ; then - printf -- "${JEKYLL_DIR}/_drafts/${1}" + if [ -f "${jekyll_dir}/_drafts/${1}" ] ; then + printf -- "${jekyll_dir}/_drafts/${1}" return 0 fi fname=${2:-${1}} - files=(${JEKYLL_DIR}/_posts/*${fname}* ${JEKYLL_DIR}/_drafts/*${fname}*) + files=(${jekyll_dir}/_posts/*${fname}* ${jekyll_dir}/_drafts/*${fname}*) if [ ${#files} -eq "0" ] ; then echo "No post found for ${fname}" >&2 return 1 @@ -45,6 +59,13 @@ function jekyll { local FILENAME local DATE local NEWNAME + local JEKYLL_DIR + + JEKYLL_DIR=`_jekyll_locate_dir` + + if [ -z "${JEKYLL_DIR}" ] ; then + return 1 + fi JTEMPLATE="---\n" JTEMPLATE+="layout: post\n" @@ -106,7 +127,7 @@ function jekyll { echo "slug is required." return 1 fi - FILENAME=$(_jekyll_find_post "${TITLE}" "${SLUG}") + FILENAME=$(_jekyll_find_post "${TITLE}" "${SLUG}" "${JEKYLL_DIR}") if [ $? -ne 0 ] ; then return fi diff --git a/dotfiles/zshrc b/dotfiles/zshrc index 901faa7..0799dca 100644 --- a/dotfiles/zshrc +++ b/dotfiles/zshrc @@ -62,3 +62,12 @@ fi # Load any local settings if [ -e $HOME/.zshrc.local ] ; then source $HOME/.zshrc.local ; fi + +function start_esp { + if [ ! -d ${HOME}/tools/esp ] ; then + echo "ESP not installed!" >/dev/stderr + return 1 + fi + export PATH="${PATH}:${HOME}/tools/esp/xtensa-esp32-elf/bin" + export IDF_PATH="${HOME}/tools/esp/esp-idf" +} diff --git a/packages b/packages index d622fb2..292f3ad 100644 --- a/packages +++ b/packages @@ -36,6 +36,7 @@ python-scapy python-virtualenv python-yara python3 +python3-pip python3-virtualenv radare2 scapy diff --git a/packages.kali b/packages.kali index 4602c8e..23653ba 100644 --- a/packages.kali +++ b/packages.kali @@ -1 +1,2 @@ volatility +bettercap