# Creating Wordlist from specific characters and numbers using Mentalist or similar program

I have locked myself out of my Win 10 Microsoft account by forgetting my password and need to get back into it. I have extracted the hash for the account.

I've been researching wordlists and hash cracking and think I've got a hang of the actual cracking process. I have been using hashcat.

I am struggling to create a custom wordlist to use. I've gotten ahold of JTR and a few other software that all claim to be the best at this but I can't find any documentation for my specific use case.

I know partial components of the password but I can't remember the order in which they are placed.

As an example, I know the password contains:

• yjb (in any combination of capital letters but in this order)
• 123456 (In all combinations and appended or prepended)
• qwertyasdfghzxcvb (single character appended or prepended to each addition of the above)
• Password length is between 4 and 9 chars

Examples of desired output:

234yJb56C | 12YjbC23 | 65432yJB123c | CyJb123 | yjBC5213

• Your requirement is so specific that no pre-built wordlist creator will be so efficient. You would need to create your own script. Alternatively, you do not have to expect optimal efficiency and use a wordlist creator that that gets you some efficiency. Nov 19 '21 at 9:51
• @schroeder Mask attack by hashcat may be really close... Nov 19 '21 at 12:22
• @vidarlo yeah, there will be very close options, but the yjb in any case combination and the reduced char set adds some complexity. Nov 19 '21 at 12:47
• Would it be something like. Creating a custom Charset using this pyscript that contains all know characters and use that to create a huge wordlist then remove all results that dont contain the yjb combination? Then just run the entire list of possibilities? Nov 19 '21 at 15:45

There isn't really an off-the-shelf way to do this, at least without a pretty complicated mask rule in hashcat, but it's trivial to write up some code to do it.

Here's some C# that very quickly builds a wordlist using the scheme you described:

interface IMutator
{
IEnumerable<string> Mutate(string input);
}

static class MutatorExtensions
{
public static IEnumerable<string> ChainMutator(this IEnumerable<string> input, IMutator m)
{
foreach (string si in input)
{
var output = m.Mutate(si);
foreach (string so in output)
{
yield return so;
}
}
}
}

class CapsMutator : IMutator
{
public IEnumerable<string> Mutate(string input)
{
if (input.Length > 64)
throw new ArgumentOutOfRangeException(nameof(input), "Input must be 64 characters long or less.");

UInt64 maskLimit = 1UL << input.Length;
char[] lowercase = input.ToLowerInvariant().ToCharArray();
char[] uppercase = input.ToUpperInvariant().ToCharArray();
char[] output = new char[input.Length];
{
for (int n = 0; n < input.Length; n++)
{
output[n] = ((mask & (1UL << n)) == 0) ? lowercase[n] : uppercase[n];
}
yield return new string(output);
}
}
}

class PrependAppendMutator : IMutator
{
public string CharacterSet { get; }
private char[] _characters;

public PrependAppendMutator(string characterSet)
{
CharacterSet = characterSet;
_characters = characterSet.ToCharArray();
}

public IEnumerable<string> Mutate(string input)
{
for (int i = 0; i < _characters.Length; i++)
{
yield return input + _characters[i];
yield return _characters[i] + input;
}
}
}

class RepeatMutator : IMutator
{
public IMutator Mutator { get; }
public int MinimumCount { get; }
public int MaximumCount { get; }

public RepeatMutator(IMutator mutator, int minCount, int maxCount)
{
Mutator = mutator;
MinimumCount = minCount;
MaximumCount = maxCount;
}

public IEnumerable<string> Mutate(string input)
{
for (int c = MinimumCount; c <= MaximumCount; c++)
{
var strings = new List<string>();
for (int i = 0; i < c; i++)
{
var nextStrings = new List<string>();
foreach (string s in strings)
{
}
strings = nextStrings;
}
foreach (string s in strings)
{
yield return s;
}
}
}
}

void Main()
{
MainAsync().GetAwaiter().GetResult();
}

{
// mutates a string into any combination of lower/upper
var capsMutator = new CapsMutator();
// adds any character from the given set to the start or end of the string
var numericMutator = new PrependAppendMutator("123456");
// repeats the numeric mutator 1-5 times (5 chosen because yjb + alpha = 4 chars, and password length limit is 9)
var numericRepeatMutator = new RepeatMutator(numericMutator, 1, 5);
// adds any character from the given set to the start or end of the string
var alphaMutator = new PrependAppendMutator("qwertyasdfghzxcvb");

// two mutator chains: one for the letter on the outside (yjB123x), one for the letter on the inside (yjBx123)
var letterOnOutsideList = capsMutator.Mutate("yjb").ChainMutator(numericRepeatMutator).ChainMutator(alphaMutator);
var letterOnInsideList = capsMutator.Mutate("yjb").ChainMutator(alphaMutator).ChainMutator(numericRepeatMutator);

// write all the words
using (var sw = new StreamWriter(@"X:\path\to\wordlist.txt"))
{
foreach (string word in letterOnOutsideList)
{
await sw.WriteLineAsync(word);
}
foreach (string word in letterOnInsideList)
{
await sw.WriteLineAsync(word);
}
// ensure everything was written
sw.Flush();
}
Console.WriteLine("Done!");
}


You can run this in LinqPad.

This takes around 25 seconds to execute on my system, and produces a 1.5GB wordlist containing around 147 million lines. The shortest password is 5 characters, not 4, because you can trivially bruteforce the 4-character space anyway and it simplifies the code.

If you're cracking the password on a GPU, I'd recommend removing the caps mutator from the wordlist generation, i.e. change the mutator chain definitions to:

var letterOnOutsideList = numericRepeatMutator.Mutate("yjb").ChainMutator(alphaMutator);
var letterOnInsideList = numericRepeatMutator.Mutate("yjb").ChainMutator(alphaMutator);


You can then use the built-in rule functionality in hashcat to do the caps mutation for you. This reduces the wordlist build time to just 2-3 seconds, producing a much more manageable 196MB wordlist with 18 million lines. This also results in a faster cracking rate because it's faster to get the GPU to produce the caps mutations than it is to transfer them from system memory to GPU memory.

If you want to modify the rules, the code should be pretty explanatory.

As an addendum, I highly recommend practicing building little programs like this. This took me about 10 minutes to write, including testing, which is far less time than it would've taken me to read through the hashcat docs and come up with a mask attack string and mutator ruleset that did what I wanted. It's not uncommon to run into situations where using the standard/ideal tool for the job isn't actually the best use of your time, especially if it's one you only occasionally use. Don't be afraid to take the quick and hacky solution for one-off cases like this.

• Thanks for the reply. Do you have any good learning materials for learning to create smaller programs from scratch? I am have trouble trying to run your example in LINQ. Probably my lack of knowledge of C# method and class arrangement. Nov 20 '21 at 0:15
• Ah, I forgot you'll need to add System.Threading.Tasks to the namespace imports. Go to Query -> References and Properties -> Additional Namespace Imports and paste System.Threading.Tasks in there. Then it should just run, assuming the language is set to "C# Program" at the top of the main window. Nov 20 '21 at 0:58
• And don't forget to set the correct file path in MainAsync(). Nov 20 '21 at 0:59
• Thanks again you've been a massive help. I find i trip over myself when trying to take actions and your answer was clear and simple. If i have it correct for the single character addition. (alphamutator) If i wanted there to also be Uppercase and lowercase. Would i simply add those Uppercase chars to the var alphaMutator? Or do i need to run that through a CapsMutator. and If i wanted to remove the single character addition from the final result i would remove alphaMutator from the outside and inside list mutator chains? Nov 20 '21 at 2:30
• Just returning to say thank you. This was very helpfull. Though im still having issues cracking the hash. This has helped wonders in getting closer to it. Nov 21 '21 at 21:32