it's actually not that easy to make policies/"rules" like this.
Furthermore, there are infinite many possibilities that an user might want differently and more flexible etc.
I think most of these complicated combinations with special "rules" need to somehow be implemented with a standalone script.
Of course it wouldn't be impossible to generate some basic list (and maybe combine them etc) and afterwards filter them with some "grep-like" tools etc... but this isn't actually that easy even with those tools (unix tools grep/sed/awk etc)...
There are just too many things that could be slightly modified and ... most importantly the length matters a lot... for instance from your text above it seems that you only have a few words and symbols etc... but even there the number of combination of each one with each other is very large (even if filtered a little bit)... but ... one other thing:
The number of symbols in between the words that you did not mention a lot contribute also very, very much to a very large keyspace and total number of combinations... for instance the 3 symbols ")+(" if we combine 1 to 3 random symbols in between each and every word, we already get a huge amount of possibilities. It's a lot !
That said, you could just use your prefered programming language (python, perl, php, maybe even javascript/nodejs etc, but the latter one maybe not recommended ?) and try to implement the logic for the combinatorics (combining a huge list with another list a flexible amount of time, with and without repetitions etc) and the policy/filtering...
To get you started, I quickly came up with this (maybe not too fast and clean, but still quite nicely working) perl script, that does the combination of words and symbols etc:
Code:
#!/usr/bin/env perl
# Author: philsmd
# Date: June 2020
# License: public domain, credits go to philsmd and hashcat
use warnings;
use strict;
#
# Constants and lists
#
my $FIRST = "JohnDoe";
my @NEEDED = ("JaneDoe", "22222", "33333", "44444");
my @SYMBOLS = ("+", "-", "&", "(", ")");
my $SYMBOL_MIN = 0;
my $SYMBOL_MAX = 3;
#
# Helper functions
#
sub combo
{
my $lis = shift; # list/array
my $len = shift; # recursion level and number of combinations (length)
my $rep = shift; # repetition allowed (can a single item repeat or no duplicates)
return if ($len == 0); # first exit condition
my @arr = ();
if ($len == 1) # second exit condition
{
foreach my $l (@$lis)
{
my @items = ($l);
push (@arr, \@items);
}
return \@arr;
}
my $combos = combo ($lis, $len - 1, $rep);
foreach my $l (@$lis)
{
foreach my $item (@$combos)
{
my @items = ($l);
foreach my $x (@$item)
{
push (@items, $x);
}
my $items_len = scalar (@items);
if ($rep == 0) # don't add $items that have non-unique entries
{
my $skip = 0;
for (my $i = 0; $i < $items_len; $i++)
{
for (my $j = $i + 1; $j < $items_len; $j++)
{
if ($items[$i] eq $items[$j])
{
$skip = 1;
last;
}
}
last if ($skip == 1);
}
next if ($skip == 1);
}
push (@arr, \@items);
}
}
return \@arr;
}
#
# Start
#
# combine all needed words (exactly 4 words)
my $combo_needed = combo (\@NEEDED, 4, 0);
# start with less symbols between the words and add more later on:
for (my $symbol_len = $SYMBOL_MIN; $symbol_len <= $SYMBOL_MAX; $symbol_len++)
{
my @combo_symbols = ();
if ($SYMBOL_MIN == 0) # special case if zero-length string is allowed !
{
push (@combo_symbols, "");
}
my $s = combo (\@SYMBOLS, $symbol_len, 1);
foreach my $item (@$s)
{
push (@combo_symbols, join ('', @$item));
}
# $FIRST + 4 combinations of $needed, without repeat
foreach my $item (@$combo_needed)
{
my $t1 = @$item[0]; # 1 needed word
my $t2 = @$item[1]; # 2 needed word
my $t3 = @$item[2]; # 3 needed word
my $t4 = @$item[3]; # 4 needed word
foreach my $s1 (@combo_symbols)
{
foreach my $s2 (@combo_symbols)
{
foreach my $s3 (@combo_symbols)
{
foreach my $s4 (@combo_symbols)
{
# $FIRST + sym + word1 + sym + word2 + sym + word3 + sym + word4
print $FIRST . $s1 . $t1 . $s2 . $t2 . $s3 . $t3 . $s4 . $t4 . "\n";
}
}
}
}
}
}
you could run it like this:
At the beginning of the file you will see several "settings" to configure the words, symbols and symbol lengths between the single words. It's probably not that good to add much more words or symbols, because the keyspace is already very huge this way...
You could probably pipe the output of the script to hashcat, but this depends a lot on the hash type.
Of course the script is just meant to help you to see how difficult it could be to implement such filters and how huge a keyspace would increase (exponentially) with increasing number of symbols/words etc
It's difficult to have a very generalized tool that is able to do all this stuff with a few command line options (or user interface clicks), because there are just way too many possibilities. The rules could say anything, even something like there must be 2 occurrences of "x", but "y" can only occur AFTER x and must be present at least twice, but not more then 3 times etc etc etc
I think the best option in such complicated situations is to just try to implement these poclicies in a simple script and afterwards improve it and add more filters etc