2 votes

Pourquoi lorsque je renifle des trames wifi en utilisant des sockets en python, j'obtiens des trames ethernet (pas 802.11)

J'essaie d'écrire un programme qui affichera tous les réseaux wifi et leurs clients. Le code ressemble à ce qui suit :

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))

Je ne sais pas pourquoi, mais la fonction "unpack_ethernet_frame" reçoit des trames Ethernet, pas des trames MAC. Si je reçois des trames sans fil, je devrais plutôt recevoir des trames MAC ? Ce que j'essaie de faire, c'est de trouver quelles trames sont des trames de balises et d'obtenir leur SSID.

EDIT : J'essaie ce code avec le mode Moniteur activé

3voto

user2722968 Points 2421

Lorsque vous obtenez vos données à partir d'un socket El IEEE802 -a déjà été déballé et le cadre de l Ethernet -Ce que vous voyez, c'est le cadre dans lequel il se trouve. Il y a des raisons historiques pour lesquelles cela est fait, et l'ensemble de l'histoire de l'entreprise. IEEE802 -est généralement invisible, même pour le système d'exploitation. Afin de recevoir des données non modifiées IEEE802 -pour les cadres, vous devez

  • mettre votre appareil WiFi en "mode surveillance", ce que tous les appareils ne supportent pas. Cela entraînera la perte de toutes les connexions Ethernet (et par extension, toutes les connexions TCP/UDP).
  • recevoir vos données non pas d'un socket mais directement à partir de l'appareil, par exemple par l'intermédiaire de libpcap .

Voir aussi este réponse et cette enlace concernant scapy .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X