簡體   English   中英

Windows上的Python 3.6中的原始套接字數據包嗅探器

[英]Raw socket packet sniffer in Python 3.6 on Windows

我正在嘗試嗅探數據包,但輸出卻很奇怪,我不明白原因。
這就是我的代碼, 幫幫我
(我在Windows 8.1上使用Python 3.6)

碼:

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

以太網幀:
目標MAC: 45:00:00:43:00:00
源MAC: 40:00:2C:11:48:D3
協議: 4266

以太網幀:
目標MAC: 45:00:00:42:11:E7
源MAC: 00:00:80:11:00:00
通訊協定: C0A8

以太網幀:
目標MAC: 45:00:00:33:04:D6
源MAC: 00:00:80:11:00:00
通訊協定: C0A8




根據EtherType列表,此協議不存在,並且使用Wireshark分析我的流量,我確定此MAC在我的LAN中不存在

所以我肯定做錯了,但是我不明白
提前致謝

好的,感謝塞爾比,我了解這個問題,非常感謝
但是要在Windows中使用Python捕獲以太網頭,您必須使用:

1. PyPCap

2. Dpkt

  • 要安裝dpkt,只需以管理員身份打開cmd並輸入:

    py -2 -m pip安裝dpkt

這里是Python Docs的參考

3. Python 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()

輸出:

以太網幀:
目標MAC: 5404a6f2740c <-我的網卡MAC
資料來源: 6459f81dc690
通訊協定: 0800 <-正確的通訊協定

以太網幀:
目標MAC: 6459f81dc690
資料來源: 5404a6f2740c
協議: 0800

以太網幀:
目標MAC: 5404a6f2740c
資料來源: 6459f81dc690
協議: 0800

希望您再次感謝selbie

(對不起,由於我的聲譽,我無法放置更多鏈接)

提示您所有的目標Mac地址都以0x45 那是IP標頭的第一個字節。 因此,您的代碼將獲取所有IP數據包,而不是那些幀的MAC標頭。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM