Как вы, возможно, уже знаете, 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.
Респект и уважуха