Вы когда-нибудь хотели создать инструмент для отображения ближайших беспроводных сетей вместе с их MAC-адресами и другой полезной информацией? Что ж, в этом уроке мы собираемся создать сканер Wi-Fi, используя библиотеку Scapy на Python.

Если вы в этой области какое-то время, вы, возможно, видели утилиту airodump-ng, которая перехватывает, захватывает и декодирует кадры 802.11 для отображения ближайших беспроводных сетей в удобном формате, в этом руководстве мы сделаем похожий.

Начиная

Для начала нужно установить Scapy, я клонировал девелоперскую версию, также можно установить с помощью pip:

pip3 install scapy
git clone https://github.com/secdev/scapy.git
cd scapy
sudo python setup.py install

Примечание. В этом руководстве предполагается, что вы используете любую среду на основе Unix, также рекомендуется использовать Kali Linux.

После этого мы будем использовать панды только для печати в хорошем формате (вы, очевидно, можете изменить это):

pip3 install pandas

Теперь код этого руководства не будет работать, если вы не включите режим монитора в своем сетевом интерфейсе, установите aircrack-ng (предустановленный на Kali) и выполните следующую команду:

Теперь вы можете проверить имя вашего интерфейса с помощью iwconfig:

Как видите, наш интерфейс теперь находится в режиме монитора и имеет имя «wlan0».

Вы также можете использовать сам iwconfig, чтобы перевести вашу сетевую карту в режим монитора:

sudo ifconfig wlan0 down
sudo iwconfig wlan0 mode monitor

Написание кода

Давайте начнем, откройте новый файл Python и импортируйте необходимые модули:

from scapy.all import *
from threading import Thread
import pandas
import time
import os

Далее нам нужно инициализировать пустой фрейм данных, в котором хранятся наши сети:

# initialize the networks dataframe that will contain all access points nearby
networks = pandas.DataFrame(columns=["BSSID", "SSID", "dBm_Signal", "Channel", "Crypto"])
# set the index BSSID (MAC address of the AP)
networks.set_index("BSSID", inplace=True)

Поэтому я установил BSSID (MAC-адрес точки доступа) в качестве индекса каждой строки, так как он уникален для каждого устройства.

Если вы знакомы со Scapy, то вы точно знаете, что мы собираемся использовать функцию sniff(), которая принимает функцию обратного вызова, которая выполняется всякий раз, когда пакет перехвачен, давайте реализуем эту функцию:

def callback(packet):
    if packet.haslayer(Dot11Beacon):
        # extract the MAC address of the network
        bssid = packet[Dot11].addr2
        # get the name of it
        ssid = packet[Dot11Elt].info.decode()
        try:
            dbm_signal = packet.dBm_AntSignal
        except:
            dbm_signal = "N/A"
        # extract network stats
        stats = packet[Dot11Beacon].network_stats()
        # get the channel of the AP
        channel = stats.get("channel")
        # get the crypto
        crypto = stats.get("crypto")
        networks.loc[bssid] = (ssid, dbm_signal, channel, crypto)

Этот обратный вызов гарантирует, что в перехваченном пакете есть уровень маяка, если это так, то он извлечет BSSID, SSID (имя точки доступа), сигнал и некоторые статистические данные. Класс Scapy Dot11Beacon имеет замечательную функцию network_stats(), которая извлекает из сети некоторую полезную информацию, такую ​​как канал, скорость и тип шифрования. Наконец, мы добавляем эту информацию во фрейм данных с BSSID в качестве индекса.

Вы столкнетесь с некоторыми сетями, у которых нет SSID (SSID равен «»), это показатель того, что это скрытая сеть. В скрытых сетях точка доступа оставляет информационное поле пустым, чтобы скрыть обнаружение имени сети, вы все равно найдете их с помощью скрипта из этого руководства, но без имени сети.

Теперь нам нужен способ визуализировать этот фрейм данных. Так как мы собираемся использовать функцию sniff() (которая блокирует и начинает анализировать в основном потоке), нам нужно использовать отдельный поток для печати содержимого networks фрейма данных, следующий код делает это:

def print_all():
    while True:
        os.system("clear")
        print(networks)
        time.sleep(0.5)

Теперь к основному коду:

if __name__ == "__main__":
    # interface name, check using iwconfig
    interface = "wlan0mon"
    # start the thread that prints all the networks
    printer = Thread(target=print_all)
    printer.daemon = True
    printer.start()
    # start sniffing
    sniff(prn=callback, iface=interface)

Изменение каналов

Теперь, если вы выполните это, вы заметите, что не все близлежащие сети доступны, потому что мы прослушиваем только один канал WLAN. Мы можем использовать команду iwconfig для изменения канала, вот функция Python для этого:

def change_channel():
    ch = 1
    while True:
        os.system(f"iwconfig {interface} channel {ch}")
        # switch channel from 1 to 14 each 0.5s
        ch = ch % 14 + 1
        time.sleep(0.5)

Например, если вы хотите переключиться на канал 2, команда будет такой:

iwconfig wlan0mon channel 2

Отлично, это будет постепенно менять каналы от 1 до 14 каждые 0,5 секунды, порождая поток демона, который запускает эту функцию:

# start the channel changer
    channel_changer = Thread(target=change_channel)
    channel_changer.daemon = True
    channel_changer.start()

Примечание. Каналы 12 и 13 разрешены в режиме пониженного энергопотребления, а канал 14 запрещен и разрешен только в Японии.

Обратите внимание, что мы устанавливаем для атрибута daemon потока значение True, поэтому этот поток будет завершаться при выходе из программы.

Вот скриншот моего исполнения:

Заключение

Хорошо, в этом уроке мы написали простой Wi-Fi-сканер с использованием библиотеки Scapy, который перехватывает и декодирует beacon-frames, которые каждый раз передаются точками доступа, они служат для оповещения о наличии беспроводной сети.

Вот исходный код статьи: - https://github.com/KoderKumar/Wifi-Scanner

Спасибо, что прочитали мою статью

И если вам это нравится, дайте мне следовать.

https://www.instagram.com/coder_kumar/

Если этот пост был полезен, пожалуйста, несколько раз нажмите кнопку аплодисментов 👏, чтобы выразить свою поддержку автору 👇

🚀Разработчики: учитесь и развивайтесь, не отставая от того, что важно, ПРИСОЕДИНЯЙТЕСЬ К FAUN.