Skip to content

Commit 575e311

Browse files
committed
add extracting wifi passwords tutorial
1 parent 95496ee commit 575e311

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ This is a repository of all the tutorials of [The Python Code](https://www.thepy
3333
- [How to Use Shodan API in Python](https://www.thepythoncode.com/article/using-shodan-api-in-python). ([code](ethical-hacking/shodan-api))
3434
- [How to Make an HTTP Proxy in Python](https://www.thepythoncode.com/article/writing-http-proxy-in-python-with-mitmproxy). ([code](ethical-hacking/http-mitm-proxy))
3535
- [How to Extract Chrome Cookies in Python](https://www.thepythoncode.com/article/extract-chrome-cookies-python). ([code](ethical-hacking/chrome-cookie-extractor))
36+
- [How to Extract Saved WiFi Passwords in Python](https://www.thepythoncode.com/article/extract-saved-wifi-passwords-in-python). ([code](ethical-hacking/get-wifi-passwords))
3637

3738
- ### [Machine Learning](https://www.thepythoncode.com/topic/machine-learning)
3839
- ### [Natural Language Processing](https://www.thepythoncode.com/topic/nlp)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# [How to Extract Saved WiFi Passwords in Python](https://www.thepythoncode.com/article/extract-saved-wifi-passwords-in-python)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import subprocess
2+
import os
3+
import re
4+
from collections import namedtuple
5+
import configparser
6+
7+
8+
def get_windows_saved_ssids():
9+
"""Returns a list of saved SSIDs in a Windows machine using netsh command"""
10+
# get all saved profiles in the PC
11+
output = subprocess.check_output("netsh wlan show profiles").decode()
12+
ssids = []
13+
profiles = re.findall(r"All User Profile\s(.*)", output)
14+
for profile in profiles:
15+
# for each SSID, remove spaces and colon
16+
ssid = profile.strip().strip(":").strip()
17+
# add to the list
18+
ssids.append(ssid)
19+
return ssids
20+
21+
22+
def get_windows_saved_wifi_passwords(verbose=1):
23+
"""Extracts saved Wi-Fi passwords saved in a Windows machine, this function extracts data using netsh
24+
command in Windows
25+
Args:
26+
verbose (int, optional): whether to print saved profiles real-time. Defaults to 1.
27+
Returns:
28+
[list]: list of extracted profiles, a profile has the fields ["ssid", "ciphers", "key"]
29+
"""
30+
ssids = get_windows_saved_ssids()
31+
Profile = namedtuple("Profile", ["ssid", "ciphers", "key"])
32+
profiles = []
33+
for ssid in ssids:
34+
ssid_details = subprocess.check_output(f"""netsh wlan show profile "{ssid}" key=clear""").decode()
35+
# get the ciphers
36+
ciphers = re.findall(r"Cipher\s(.*)", ssid_details)
37+
# clear spaces and colon
38+
ciphers = "/".join([c.strip().strip(":").strip() for c in ciphers])
39+
# get the Wi-Fi password
40+
key = re.findall(r"Key Content\s(.*)", ssid_details)
41+
# clear spaces and colon
42+
try:
43+
key = key[0].strip().strip(":").strip()
44+
except IndexError:
45+
key = "None"
46+
profile = Profile(ssid=ssid, ciphers=ciphers, key=key)
47+
if verbose >= 1:
48+
print_windows_profile(profile)
49+
profiles.append(profile)
50+
return profiles
51+
52+
53+
def print_windows_profile(profile):
54+
"""Prints a single profile on Windows"""
55+
print(f"{profile.ssid:25}{profile.ciphers:15}{profile.key:50}")
56+
57+
58+
def print_windows_profiles(verbose):
59+
"""Prints all extracted SSIDs along with Key on Windows"""
60+
print("SSID CIPHER(S) KEY")
61+
print("-"*50)
62+
get_windows_saved_wifi_passwords(verbose)
63+
64+
65+
def get_linux_saved_wifi_passwords(verbose=1):
66+
"""Extracts saved Wi-Fi passwords saved in a Linux machine, this function extracts data in the
67+
`/etc/NetworkManager/system-connections/` directory
68+
Args:
69+
verbose (int, optional): whether to print saved profiles real-time. Defaults to 1.
70+
Returns:
71+
[list]: list of extracted profiles, a profile has the fields ["ssid", "auth-alg", "key-mgmt", "psk"]
72+
"""
73+
network_connections_path = "/etc/NetworkManager/system-connections/"
74+
fields = ["ssid", "auth-alg", "key-mgmt", "psk"]
75+
Profile = namedtuple("Profile", [f.replace("-", "_") for f in fields])
76+
profiles = []
77+
for file in os.listdir(network_connections_path):
78+
data = { k.replace("-", "_"): None for k in fields }
79+
config = configparser.ConfigParser()
80+
config.read(os.path.join(network_connections_path, file))
81+
for _, section in config.items():
82+
for k, v in section.items():
83+
if k in fields:
84+
data[k.replace("-", "_")] = v
85+
profile = Profile(**data)
86+
if verbose >= 1:
87+
print_linux_profile(profile)
88+
profiles.append(profile)
89+
return profiles
90+
91+
92+
def print_linux_profile(profile):
93+
"""Prints a single profile on Linux"""
94+
print(f"{str(profile.ssid):25}{str(profile.auth_alg):5}{str(profile.key_mgmt):10}{str(profile.psk):50}")
95+
96+
97+
def print_linux_profiles(verbose):
98+
"""Prints all extracted SSIDs along with Key (PSK) on Linux"""
99+
print("SSID AUTH KEY-MGMT PSK")
100+
print("-"*50)
101+
get_linux_saved_wifi_passwords(verbose)
102+
103+
104+
def print_profiles(verbose=1):
105+
if os.name == "nt":
106+
print_windows_profiles(verbose)
107+
elif os.name == "posix":
108+
print_linux_profiles(verbose)
109+
else:
110+
raise NotImplemented("Code only works for either Linux or Windows")
111+
112+
113+
if __name__ == "__main__":
114+
print_profiles()

0 commit comments

Comments
 (0)