Почему при сниффинге фреймов Wi-Fi с использованием сокетов в Python я получаю фреймы Ethernet (не 802.11) - PullRequest
0 голосов
/ 12 мая 2018

Я пытаюсь написать программу, которая будет отображать все сети Wi-Fi и их клиентов.Код выглядит следующим образом:

import os
import socket
import struct

def unpack_ethernet_frame(data):
    dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14])  # Big-endian, 6bytes, 6bytes, 1 short
    return format_mac(dest_mac), format_mac(src_mac), socket.htons(proto), data[14:]

def format_mac(bytes_addr):
    bytes_s = map('{:02x}'.format, bytes_addr) 
    return ":".join(bytes_s).upper()

def format_ip(bytes_addr):
    return ".".join(map(str, bytes_addr))

def unpack_ipv4_frame(data):
    header_len = (data[0] & 15) * 4  # last 4 bits of first byte * 4
    ttl, prot, src, dst = struct.unpack("! 8x B B 2x 4s 4s", data[:20])
    return format_ip(src), format_ip(dst), prot, data[header_len:]

def unpack_tcp(data):
    src_port, dst_port = struct.unpack("! H H", data[:4])
    return src_port, dst_port

def unpack_udp(data):
    src_port, dst_port, size = struct.unpack("! H H 2x H", data[:8])
    return src_port, dst_port, size, data[8:]

if __name__ == '__main__':
    conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))

    while True:
        raw_data, addr = conn.recvfrom(65536)
        dest, src, prot, data = unpack_ethernet_frame(raw_data)
        if prot == 8:  # IP
            print("Dest {0}, Src {1}, prot {2}".format(dest, src, prot))
            src_id, dst_ip, prot, data = unpack_ipv4_frame(data)
            print("From {0} to {1}".format(src_id, dst_ip))
            if prot == 6:  # TCP
                src_port, dst_port = unpack_tcp(data)
                print("src_port {0} dst_port {1}".format(src_port, dst_port))
            if prot == 17:  # UdP
                src_port, dst_port, size, data = unpack_udp(data)
                print("src_port {0} dst_port {1} size {2}".format(src_port, dst_port, size))

Я не знаю почему, но функция "unpack_ethernet_frame" получает кадры Ethernet, а не кадры MAC.Если я получаю беспроводные кадры, то мне лучше получать MAC-кадры?В основном я пытаюсь выяснить, какие кадры являются кадрами маяка, и получить их SSID.

РЕДАКТИРОВАТЬ : я пытаюсь этот код с включенным режимом монитора

1 Ответ

0 голосов
/ 12 мая 2018

Когда вы получаете данные с socket, IEEE802 -рамка уже распакована, а Ethernet -фрейм внутри нее - это то, что вы видите. Существуют исторические причины, по которым это делается, и весь слой IEEE802 обычно не виден даже ОС. Для получения неизмененных IEEE802 -кадров необходимо

  • превратит ваше WiFi-устройство в «Режим монитора», который поддерживают не все устройства. Это приведет к тому, что все Ethernet- (и, соответственно, все TCP / UDP-) соединения будут сброшены.
  • получает ваши данные не от socket, а напрямую от устройства, например через libpcap .

Также см. этот ответ и эту ссылку относительно scapy .

...