7

I've found during a lot of recent pen-tests that companies will use passwords like

c0mp4ny@b(

for a company called "company abc"

Is there any quick and easy way to generate a list of passwords based on as many possible 'leet speak' letters?

So the input would be

company abc

and the ouput would be

c0mpanyabc

c0mpany4bc

C0mpany4bc1

etc....

Where permutations of caps, underscores, added num/special chars at the end etc are all generated?

4 Answers 4

2

The first tool in my toolbox for generating permuted wordlists is RSMangler. So far, I wasn't able to find a better tool.

It's written in Ruby, it's open source, super easy to modify and extend, has a ton of options, and it's licenced under CC BY-SA UK.

You may easily extend the leet_swap array. For example

leet_swap = {
  'a' => '@',
  'C' => '(',
}

It automatically add numbers before and after each string, it even gives the option to append some common words to your wordlist in the array common_words.

All the options are enabled by default, so when you set the option --common you're disabling the common words feature. Same goes for the other options.

I'd highly advise disabling the --perms option, as it creates an extremely exhaustive permutation list. When I say "extremely exhaustive" I'm not overstating it. My non-mutated wordlist was expanded to nearly 900GB wordlist.

0
4

I crafted an answer using Javascript, because it's what I am used to and no language is specified. I am confident that you can find/create an analog in whatever other language you please.

First off, I stole a function from This answer to create a cartesian product. The explanation of cartesian products is not really in the scope of this question, but suffice to say it combines arrays of possible characters into arrays of possible strings (very oversimplified).

OK, so ckozl's function is :

function cartProd(paramArray) {

  function addTo(curr, args) {

    var i, copy, 
        rest = args.slice(1),
        last = !rest.length,
        result = [];

    for (i = 0; i < args[0].length; i++) {

      copy = curr.slice();
      copy.push(args[0][i]);

      if (last) {
        result.push(copy);

      } else {
        result = result.concat(addTo(copy, rest));
      }
    }

    return result;
  }


  return addTo([], Array.prototype.slice.call(paramArray));
}

and mine is :

function findSubs(string) {
        //create a linked list of sub characters
        //expect lower case input
        subs={
                "p":["p","P"],
                "a":["a","A","4","@"],
                "s":["s","S","$","5"]
        }
        //create an (initially empty) array to store possible characters in each position
        result=[]
        for (var i=0;i<string.length;i++) {
                result[i]=subs[string.charAt(i)]; //Would be more robust if you added logic here to handle it not being a key in the subs object. 
        }
        /*
        so result might look like:
        [
                ["p","P"],
                ["a","A","4","@"],
                ["s","S","$","5"],
                ["s","S","$","5"]
        ]
        for an input of "pass"
        */
        return cartProd(result)
}

Honestly, ckzol's function does all the heavy lifting here. You would need to flesh out the subs array before use, and this does not handle adding characters at the end of the string (because it seems kind of arbitrary).

Also note I have ever so slightly modified the cartProd function, such that we can hand it an array of arrays as input params rather than multiple arrays overloading the arguments.

Edit: also note that the returned value is an array of arrays, so you would want to iterate through it and for each element e do e.join("").

Edit again: also note that you could easily extend this to apply other mutations to the password. For instance, if you wanted to add a number between 0 and 99 to the end of the string you could push an extra array onto the end of result, containing ["0","1","2",...,"99"]. You could include an empty element ("") in this array to also output possibilities not including the number suffix. The same logic could be used to add a prefix. Essentially you are building an array of arrays of possible characters in the result array, so you can include any mutations you can think of.

1
  • looks pretty good to me, i'll have a go at fleshing it out and expanding the 'alphabet' and let you know how it goes :)
    – NULLZ
    Commented May 9, 2013 at 6:43
0

I made a tool called PassGen that will do what you are talking about. You can take a look at it here.

The idea is that you can pass in a target word and generate a password list using common substitutions. If you feel like getting a little more advanced you can also use the tool to fire HTTP requests to see if any of the passwords work.

For your example you would enter sometning like:

python passgen.py -f companyabc

Be warned that the password lists can get large quickly. The above example generates 147456 passwords.

0

With l33tpasspro.rule, this hashcat command could generate these passwords c0mpanyabc, c0mpany4bc, C0mpany4bc1 for you:

hashcat64.exe -a 0 dict.txt -r purge_space.rule -r l33tpasspro.rule --stdout | sort | uniq | hashcat64.exe -r rules/hybrid/append_s_passthrough.rule -r rules/best64.rule --stdout

purge_space.rule (there's a space after the @ symbol):

@ 

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .