0

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

schroeder
  • 123,438
  • 55
  • 284
  • 319
Patho
  • 5
  • 1
  • 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. – schroeder Nov 19 '21 at 09:51
  • @schroeder Mask attack by hashcat may be *really* close... – vidarlo Nov 19 '21 at 12:22
  • 1
    @vidarlo yeah, there will be very close options, but the `yjb` in any case combination and the reduced char set adds some complexity. – schroeder Nov 19 '21 at 12:47
  • Would it be something like. Creating a custom Charset [using this pyscript](https://security.stackexchange.com/questions/149110/creating-a-wordlist-knowing-parameters/149114#149114) 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? – Patho Nov 19 '21 at 15:45

1 Answers1

1

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 (UInt64 mask = 0; mask < maskLimit; mask++)
        {
            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>();
            strings.Add(input);
            for (int i = 0; i < c; i++)
            {
                var nextStrings = new List<string>();
                foreach (string s in strings)
                {
                    nextStrings.AddRange(Mutator.Mutate(s));
                }
                strings = nextStrings;
            }
            foreach (string s in strings)
            {
                yield return s;
            }
        }
    }
}

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

async Task MainAsync()
{
    // 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.

Polynomial
  • 132,208
  • 43
  • 298
  • 379
  • 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. – Patho Nov 20 '21 at 00: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. – Polynomial Nov 20 '21 at 00:58
  • And don't forget to set the correct file path in `MainAsync()`. – Polynomial Nov 20 '21 at 00: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? – Patho Nov 20 '21 at 02:30
  • Yes to both, that's exactly how you'd do that. – Polynomial Nov 20 '21 at 16:58
  • 1
    Just returning to say thank you. This was very helpfull. Though im still having [issues](https://security.stackexchange.com/questions/257342/pwdump8-8-2-correct-hash-for-microsoft-account-win10?noredirect=1#comment530267_257342) cracking the hash. This has helped wonders in getting closer to it. – Patho Nov 21 '21 at 21:32
  • @Patho No problem. I've added an answer to that question too. Don't forget to accept this as an answer if it was useful :) – Polynomial Nov 21 '21 at 23:50