Как вы, возможно, уже знаете, Wi-Fiએ используется в разных местах для подключения к нескольким сетям, и на вашем компьютере определенно есть способ где-то хранить пароль Wi‑Fi, поэтому при следующем подключении вам не приходится повторно вводить его снова.
Здесь вы узнаете, как быстро создать скрипт Python для извлечения сохраненного пароля Wi‑Fi на компьютерах с Windows или Linux.
Нам не потребуется установка какой-либо сторонней библиотеки, так как мы будем использовать netsh в Windows и анализ папки NetworkManager в Linux. Импорт библиотек:
import subprocess import os import re from collections import namedtuple import configparser
Получение паролей Wi‑Fi в Windows
В Windows, чтобы получить все имена Wi‑Fi (ssids), используем команду ОС netsh wlan show profiles, функция ниже использует subprocess() для вызова этой команды и анализирует результат её выполнения в Python:
def get_windows_saved_ssids():
"""Возвращает список сохраненных SSID на машине Windows с помощью команды netsh"""
# получить все сохраненные профили на ПК
output = subprocess.check_output("netsh wlan show profiles").decode()
ssids = []
profiles = re.findall(r"Весь профиль пользователя\s(.*)", output)
for profile in profiles:
# для каждого SSID удалите пробелы и двоеточие
ssid = profile.strip().strip(":").strip()
# добавить в список
ssids.append(ssid)
return ssids
Используем регулярные выражения для поиска сетевых профилей. Затем можно использовать show profile [ssid] key = clear для получения пароли сети:
def get_windows_saved_wifi_passwords(verbose=1):
"""Извлекает сохраненные пароли Wi‑Fi на машине Windows, эта функция извлекает данные с помощью netsh
команды в Windows
Аргументы:
verbose (int, optional): whether to print saved profiles real-time. Defaults to 1.
Результат:
[list]: list of extracted profiles, a profile has the fields ["ssid", "ciphers", "key"]
"""
ssids = get_windows_saved_ssids()
Profile = namedtuple("Profile", ["ssid", "ciphers", "key"])
profiles = []
for ssid in ssids:
ssid_details = subprocess.check_output(f"""netsh wlan show profile "{ssid}" key=clear""").decode()
# получить шифры
ciphers = re.findall(r"Cipher\s(.*)", ssid_details)
# очистить пробелы и двоеточие
ciphers = "/".join([c.strip().strip(":").strip() for c in ciphers])
# получить пароль Wi‑Fi
key = re.findall(r"Key Content\s(.*)", ssid_details)
# очистить пробелы и двоеточие
try:
key = key[0].strip().strip(":").strip()
except IndexError:
key = "None"
profile = Profile(ssid=ssid, ciphers=ciphers, key=key)
if verbose >= 1:
print_windows_profile(profile)
profiles.append(profile)
return profiles
def print_windows_profile(profile):
"""Печать одного профиля в Windows"""
print(f"{profile.ssid:25}{profile.ciphers:15}{profile.key:50}")
Сначала вызываем наш get_windows_saved_ssids(), чтобы получить все SSID, к которым мы подключались ранее, затем инициализируем наш namedtuple, чтобы включить ssid, ciphers и key. Вызываем show profile [ssid] key=clear для каждого извлеченного SSID и анализируем шифры и ключ (пароль), распечатываем его с помощью простой функции print_windows_profile().
Сейчас запишем эту функцию:
def print_windows_profiles(verbose):
"""Печатает все извлеченные SSID вместе с ключом в Windows"""
print("SSID CIPHER(S) KEY")
print("-"*50)
get_windows_saved_wifi_passwords(verbose)
Итак, print_windows_profiles() печатает все SSID вместе с шифром и ключом (паролем).
Получение паролей Wi‑Fi в Linux
В Linux все по-другому, информация о всех ранее подключенных сетях находится в каталоге /etc/NetworkManager/system-connections/ в виде файлов INI, нам просто нужно прочитать эти файлы и распечатать их в удобном формате:
def get_linux_saved_wifi_passwords(verbose=1):
"""Извлекает сохраненные пароли Wi‑Fi на машине Linux, эта функция извлекает данные в каталоге `/etc/NetworkManager/system-connections/`
Аргументы:
verbose (int, optional): whether to print saved profiles real-time. Defaults to 1.
Результат:
[list]: list of extracted profiles, a profile has the fields ["ssid", "auth-alg", "key-mgmt", "psk"]
"""
network_connections_path = "/etc/NetworkManager/system-connections/"
fields = ["ssid", "auth-alg", "key-mgmt", "psk"]
Profile = namedtuple("Profile", [f.replace("-", "_") for f in fields])
profiles = []
for file in os.listdir(network_connections_path):
data = { k.replace("-", "_"): None for k in fields }
config = configparser.ConfigParser()
config.read(os.path.join(network_connections_path, file))
for _, section in config.items():
for k, v in section.items():
if k in fields:
data[k.replace("-", "_")] = v
profile = Profile(**data)
if verbose >= 1:
print_linux_profile(profile)
profiles.append(profile)
return profiles
def print_linux_profile(profile):
"""Печатает один профиль в Linux"""
print(f"{str(profile.ssid):25}{str(profile.auth_alg):5}{str(profile.key_mgmt):10}{str(profile.psk):50}")
Как уже упоминалось, мы вызываем os.listdir() в этом каталоге для вывода списка всех файлов, затем используем configparser для чтения файла INI и перебираем элементы, если мы находим поля, которые нам интересны, просто добавляем их в наши данные.
В файлах INI есть и другая информация, но нас интересует только SSID, auth-alg, key-mgmt и psk(password). Далее запишем функцию печати:
def print_linux_profiles(verbose):
"""Печатает все извлеченные SSID вместе с ключом (PSK) в Linux"""
print("SSID AUTH KEY-MGMT PSK")
print("-"*50)
get_linux_saved_wifi_passwords(verbose)
Наконец, запишем функцию, которая вызывает print_linux_profiles() или print_windows_profiles() в зависимости от нашей ОС:
def print_profiles(verbose=1):
if os.name == "nt":
print_windows_profiles(verbose)
elif os.name == "posix":
print_linux_profiles(verbose)
else:
raise NotImplemented("Код работает только для ОС Linux или Windows")
if __name__ == "__main__":
print_profiles()
Запускаем скрипт:
$ python get_wifi_passwords.py
Вывод на моей машине с Windows:
SSID CIPHER(S) KEY -------------------------------------------------- OPPO F9 CCMP/GCMP 0120123489@ TP-Link_83BE_5G CCMP/GCMP 0xxxxxxx Access Point CCMP/GCMP super123 HUAWEI P30 CCMP/GCMP 00055511 ACER CCMP/GCMP 20192019 HOTEL VINCCI MARILLIA CCMP 01012019 Bkvz-U01Hkkkkkzg CCMP/GCMP 00000011 nadj CCMP/GCMP burger010 Griffe T1 CCMP/GCMP 110011110111111 BIBLIO02 None None AndroidAP CCMP/GCMP 185338019mbs ilfes TKIP 25252516 Point CCMP/GCMP super123
И это результат на Linux:
SSID AUTH KEY-MGMT PSK -------------------------------------------------- KNDOMA open wpa-psk 5060012009690 TP-LINK_C4973F None None None None None None None Point open wpa-psk super123 Point None None None
Заключение
Хорошо, и всё на сегоня. Я уверен, что для вас это полезный код и вы сможете быстро получить сохраненные пароли Wi‑Fi на своём компьютере.
Посмотрие полный код.
import subprocess
import os
import re
from collections import namedtuple
import configparser
def get_windows_saved_ssids():
"""Возвращает список сохраненных SSID на машине Windows с помощью команды netsh"""
# получить все сохраненные профили на ПК
output = subprocess.check_output("netsh wlan show profiles").decode()
ssids = []
profiles = re.findall(r"Весь профиль пользователя\s(.*)", output)
for profile in profiles:
# для каждого SSID удалите пробелы и двоеточие
ssid = profile.strip().strip(":").strip()
# добавить в список
ssids.append(ssid)
return ssids
def get_windows_saved_wifi_passwords(verbose=1):
"""Извлекает сохраненные пароли Wi‑Fi на машине Windows, эта функция извлекает данные с помощью netsh
команды в Windows
Аргумены:
verbose (int, optional): whether to print saved profiles real-time. Defaults to 1.
Результат:
[list]: list of extracted profiles, a profile has the fields ["ssid", "ciphers", "key"]
"""
ssids = get_windows_saved_ssids()
Profile = namedtuple("Profile", ["ssid", "ciphers", "key"])
profiles = []
for ssid in ssids:
ssid_details = subprocess.check_output(f"""netsh wlan show profile "{ssid}" key=clear""").decode()
# получить шифры
ciphers = re.findall(r"Cipher\s(.*)", ssid_details)
# убрать пробелы и двоеточие
ciphers = "/".join([c.strip().strip(":").strip() for c in ciphers])
# получить пароль Wi‑Fi
key = re.findall(r"Key Content\s(.*)", ssid_details)
# убрать пробелы и двоеточие
try:
key = key[0].strip().strip(":").strip()
except IndexError:
key = "None"
profile = Profile(ssid=ssid, ciphers=ciphers, key=key)
if verbose >= 1:
print_windows_profile(profile)
profiles.append(profile)
return profiles
def print_windows_profile(profile):
"""Печать одного профиля в Windows"""
print(f"{profile.ssid:25}{profile.ciphers:15}{profile.key:50}")
def print_windows_profiles(verbose):
"""Печатает все извлеченные SSID вместе с ключом в Windows"""
print("SSID CIPHER(S) KEY")
get_windows_saved_wifi_passwords(verbose)
def get_linux_saved_wifi_passwords(verbose=1):
"""Извлекает сохраненные пароли Wi‑Fi на машине Linux, эта функция извлекает данные в каталоге `/etc/NetworkManager/system-connections/`
Аргументы:
verbose (int, optional): whether to print saved profiles real-time. Defaults to 1.
Результат:
[list]: list of extracted profiles, a profile has the fields ["ssid", "auth-alg", "key-mgmt", "psk"]
"""
network_connections_path = "/etc/NetworkManager/system-connections/"
fields = ["ssid", "auth-alg", "key-mgmt", "psk"]
Profile = namedtuple("Profile", [f.replace("-", "_") for f in fields])
profiles = []
for file in os.listdir(network_connections_path):
data = { k.replace("-", "_"): None for k in fields }
config = configparser.ConfigParser()
config.read(os.path.join(network_connections_path, file))
for _, section in config.items():
for k, v in section.items():
if k in fields:
data[k.replace("-", "_")] = v
profile = Profile(**data)
if verbose >= 1:
print_linux_profile(profile)
profiles.append(profile)
return profiles
def print_linux_profile(profile):
"""Печатает один профиль в Linux"""
print(f"{str(profile.ssid):25}{str(profile.auth_alg):5}{str(profile.key_mgmt):10}{str(profile.psk):50}")
def print_linux_profiles(verbose):
"""Печатает все извлеченные SSID вместе с ключом (PSK) в Linux"""
print("SSID AUTH KEY-MGMT PSK")
get_linux_saved_wifi_passwords(verbose)
def print_profiles(verbose=1):
if os.name == "nt":
print_windows_profiles(verbose)
elif os.name == "posix":
print_linux_profiles(verbose)
else:
raise NotImplemented("Код работает только для ОС Linux or Windows")
if __name__ == "__main__":
print_profiles()
По мотивам
Как извлечь сохраненные пароли WiFi в Python, опубликовано К ВВ, лицензия — Creative Commons Attribution-NonCommercial 4.0 International.
Респект и уважуха

