【问题标题】:Raw socket packet sniffer in Python 3.6 on WindowsWindows 上 Python 3.6 中的原始套接字数据包嗅探器
【发布时间】:2017-01-10 09:35:07
【问题描述】:

我正在尝试嗅探数据包,但我得到了奇怪的输出,我不明白原因..
这就是我的代码帮助我
(我在 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 list,此协议不存在并使用 Wireshark 分析我的流量,我确信我的 LAN 中不存在此 MAC

所以我肯定做错了什么,但我不明白是什么
提前致谢

【问题讨论】:

    标签: python windows python-3.x sockets network-programming


    【解决方案1】:

    好的,感谢 selbi 我明白了这个问题,非常感谢
    但是要在 Windows 中使用 Python 捕获以太网标头,您必须使用:

    1。 PyPCap

    2。文件包

    • 要安装 dpkt,只需以管理员身份打开 cmd 并输入:

      py -2 -m pip install 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
    来源:6459f81dc690
    协议:0800

    以太网帧:
    目标 MAC:6459f81dc690
    来源:5404a6f2740c
    协议:0800

    以太网帧:
    目标 MAC:5404a6f2740c
    来源:6459f81dc690
    协议:0800

    希望您再次享受感谢selbie

    (对不起,因为我的声誉,我不能放更多链接)

    【讨论】:

    • 我已经尝试过上面相同的数据包嗅探器代码。它在我的 Windows 10 上不起作用。
    • @krish 这个问题已经过时了。我会尽快修复它。你得到了哪些错误?
    • 以太网总帧不匹配。它没有给出正确的源mac和des mac
    【解决方案2】:

    提示是您的所有目标 Mac 地址都以 0x45 开头。这是IP header 的第一个字节。因此,您的代码正在获取所有 IP 数据包,但不是这些帧的 MAC 标头。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 2014-08-31
    • 2016-05-14
    • 1970-01-01
    • 2010-10-02
    相关资源
    最近更新 更多