Сниффер пакетов необработанных сокетов в Python 3.6 в Windows

Я пытаюсь пронюхать пакеты, но получаю странный вывод и не понимаю причины..
Вот мой код пожалуйста, помогите мне
(я использую Python 3.6 на Windows 8.1)

Код:

import socket
import struct
import binascii
import textwrap

def main():
    # Get host
    host = socket.gethostbyname(socket.gethostname())
    print('IP: {}'.format(host))

    # Create a raw socket and bind it
    conn = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
    conn.bind((host, 0))

    # Include IP headers
    conn.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
    # Enable promiscuous mode
    conn.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

    while True:
        # Recive data
        raw_data, addr = conn.recvfrom(65536)

        # Unpack data
        dest_mac, src_mac, eth_proto, data = ethernet_frame(raw_data)

        print('\nEthernet Frame:')
        print("Destination MAC: {}".format(dest_mac))
        print("Source MAC: {}".format(src_mac))
        print("Protocol: {}".format(eth_proto))

# Unpack ethernet frame
def ethernet_frame(data):
    dest_mac, src_mac, proto = struct.unpack('!6s6s2s', data[:14])
    return get_mac_addr(dest_mac), get_mac_addr(src_mac), get_protocol(proto), data[14:]

# Return formatted MAC address AA:BB:CC:DD:EE:FF
def get_mac_addr(bytes_addr):
    bytes_str = map('{:02x}'.format, bytes_addr)
    mac_address = ':'.join(bytes_str).upper()
    return mac_address

# Return formatted protocol ABCD
def get_protocol(bytes_proto):
    bytes_str = map('{:02x}'.format, bytes_proto)
    protocol = ''.join(bytes_str).upper()
    return protocol

main()

Из этого кода я получаю этот вывод:

IP: 192.168.1.12

Кадр Ethernet:
MAC-адрес назначения: 45:00:00:43:00:00
MAC-адрес источника: 40:00:2C:11:48:D3 >
Протокол: 4266

Кадр Ethernet:
MAC-адрес назначения: 45:00:00:42:11:E7
MAC-адрес источника: 00:00:80:11:00:00 >
Протокол: C0A8

Кадр Ethernet:
MAC-адрес назначения: 45:00:00:33:04:D6
MAC-адрес источника: 00:00:80:11:00:00 >
Протокол: C0A8

.
.
.

Согласно списку EtherType, эти протоколы не существуют, и, анализируя мой трафик с помощью Wireshark, я уверен, что этот MAC не существует в моей локальной сети

Так что я определенно делаю что-то не так, но я не понимаю, что
Заранее спасибо


person Alessandro Lodi    schedule 10.01.2017    source источник


Ответы (2)


Подсказка в том, что все ваши адреса Mac назначения начинаются с 0x45. Это первый байт IP-заголовка. Таким образом, ваш код получает все IP-пакеты, но не заголовок MAC для этих кадров.

person selbie    schedule 10.01.2017
comment
Но как я могу получить заголовок MAC? (я новичок в Python) - person Alessandro Lodi; 10.01.2017
comment
Вместо открытия сокета AF_INET откройте сокет AF_PACKET. opensourceforu.com/2015/03/a-guide-to -использование необработанных сокетов - person selbie; 10.01.2017

Хорошо, спасибо selbi, я понимаю проблему, большое спасибо
Но чтобы поймать заголовок Ethernet с помощью Python в Windows, вы должны использовать:

1. ПиПКап

2. ДПКТ

  • Чтобы установить dpkt, просто откройте cmd от имени администратора и введите:

    py -2 -m pip установить dpkt

Здесь ссылки на Python Docs

3. Питон 2.7

Но вам нужно установить Python 3.4>, чтобы получить pip

И, наконец, это код:

#!/usr/bin/env python

import getopt, sys
import dpkt, pcap
import socket
import struct
import binascii
import textwrap

def main():
    # Get host
    host = socket.gethostbyname(socket.gethostname())
    print('IP: {}'.format(host))

    name = None            
    pc = pcap.pcap(name)
    decode = { pcap.DLT_LOOP:dpkt.loopback.Loopback,
               pcap.DLT_NULL:dpkt.loopback.Loopback,
               pcap.DLT_EN10MB:dpkt.ethernet.Ethernet }[pc.datalink()]
    try:
        print 'listening on %s: %s' % (pc.name, pc.filter)
        for ts, pkt in pc:
            pkt = str(decode(pkt))
            dest_mac, src_mac, eth_proto, data = ethernet_frame(pkt)

            print '\nEthernet Frame:'
            print "Destination MAC: {}".format(dest_mac)
            print "Source: {}".format(src_mac)
            print "Protocol: {}".format(eth_proto)
    except KeyboardInterrupt:
        nrecv, ndrop, nifdrop = pc.stats()
        print '\n%d packets received by filter' % nrecv
        print '%d packets dropped by kernel' % ndrop

# Unpack ethernet frame
def ethernet_frame(data):
    dest_mac, src_mac, proto = struct.unpack('!6s6s2s', data[:14])
    return binascii.hexlify(dest_mac), binascii.hexlify(src_mac), binascii.hexlify(proto), data[14:]

if __name__ == '__main__':
    main()

Выход:

Кадр Ethernet:
MAC-адрес назначения: 5404a6f2740c ‹- MAC-адрес моей сетевой карты
Источник: 6459f81dc690
Протокол: 0800 ‹- Правильный протокол

Кадр Ethernet:
MAC-адрес назначения: 6459f81dc690
Источник: 5404a6f2740c
Протокол: 0800

Кадр Ethernet:
MAC-адрес назначения: 5404a6f2740c
Источник: 6459f81dc690
Протокол: 0800

Надеюсь, вам понравится еще раз спасибо selbie

(Извините, я не могу разместить больше ссылок из-за моей репутации)

person Alessandro Lodi    schedule 10.01.2017
comment
Я пробовал вышеуказанный код анализатора пакетов. это не работало на моих окнах 10. - person krish; 15.01.2021
comment
@krish вопрос старый .. Я постараюсь исправить его как можно скорее. Какие ошибки вы получаете? - person Alessandro Lodi; 15.01.2021
comment
Общий кадр Ethernet не соответствует. он не дал правильный исходный mac и des mac - person krish; 16.01.2021