简体   繁体   English

Python中的数据包嗅探(Windows)

[英]Packet sniffing in Python (Windows)

What is the best way to sniff network packets using Python? 使用Python嗅探网络数据包的最佳方法是什么?

I've heard from several places that the best module for this is a module called Scapy, unfortunately, it makes python.exe crash on my system. 我从几个地方听说,最好的模块是一个名为Scapy的模块,不幸的是,它使我的系统上的python.exe崩溃。 I would assume that it's just a problem with how I installed it, except that many other people have told me that it doesn't work particularly well on Windows. 我会认为这只是我安装它的一个问题,除了很多其他人告诉我它在Windows上运行效果不佳。 (If anyone is interested, I'm running Windows Vista, which might affect things). (如果有人有兴趣,我正在运行Windows Vista,这可能会影响事情)。

Does anyone know of a better solution? 有谁知道更好的解决方案?

UPD: UPD:

After reading the answer telling me to install PyPcap, I messed around with it a bit and found out that Scapy, which I had tried using, was telling me to install PyPcap as well, except that it's a modified version for it's use. 在阅读了告诉我安装PyPcap的答案之后,我稍微搞砸了一下,发现我曾尝试使用的Scapy也告诉我安装PyPcap,除了它是一个修改版本供它使用。 It was this modified PyPcap that was causing the problem, apparently, since the example in the answer also caused a hang. 正是这个修改过的PyPcap导致了问题,显然,因为答案中的例子也导致了问题。

I installed the original version of PyPcap (from Google's site), and Scapy started working fine (I didn't try many things, but at least it didn't crash as soon as I started sniffing). 我安装了原始版本的PyPcap(来自谷歌的网站),而且Scapy开始工作正常(我没有尝试过很多东西,但至少它在我开始嗅探时没有崩溃)。 I sent a new defect ticket to the Scapy developers: http://trac.secdev.org/scapy/ticket/166 , hope they can do something with it. 我向Scapy开发人员发送了一张新的缺陷票: http ://trac.secdev.org/scapy/ticket/166,希望他们能用它做点什么。

Anyways, just thought I'd let y'all know. 无论如何,只是想我会让你们都知道。

The hard way 艰难的方式

You can sniff all of the IP packets using a raw socket. 您可以使用原始套接字嗅探所有IP数据包。
Raw socket is a socket the sends and receives data in binary. Raw socket是一个以二进制形式发送和接收数据的套接字。
Binary in python is represented in a string which looks like this \\x00\\xff ... every \\x.. is a byte. python中的二进制文件用字符串表示,它看起来像这个\\x00\\xff ...每个\\x..是一个字节。
To read an IP packet you need to analyze the received packet in binary according to the IP protocol. 要读取IP数据包,您需要根据IP协议分析二进制接收的数据包。

This is and image of the format of the IP protocol with the sized in bits of every header. 这是IP协议格式的图像,其大小为每个报头的位。

IP协议格式

This tutorial might help you understand the proccess of understanding a raw packet and splitting it to headers: http://www.binarytides.com/python-packet-sniffer-code-linux/ 本教程可能有助于您了解理解原始数据包并将其拆分为标题的过程: http//www.binarytides.com/python-packet-sniffer-code-linux/

The easy way 简单的方法

Another method to sniff IP packets very easily is to use the scapy module. 另一种非常容易嗅探IP数据包的方法是使用scapy模块。

from scapy.all import *
sniff(filter="ip", prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}"))

This code will print for you the source IP and the destination IP for every IP packet. 此代码将为您打印每个IP数据包的源IP和目标IP。 You can do much more with scapy by reading it's documentation here: http://www.secdev.org/projects/scapy/doc/usage.html 你可以通过阅读它的文档来做更多的scapy: http//www.secdev.org/projects/scapy/doc/usage.html

It depends on the goal you are trying to achieve but if you need to build a project the one it's features is sniffing IP packets then I recommend to use scapy for more stable scripts. 这取决于你想要实现的目标,但如果你需要构建一个项目,它的功能是嗅探IP数据包,那么我建议使用scapy来获得更稳定的脚本。

Using pypcap : 使用pypcap

import dpkt, pcap
pc = pcap.pcap()     # construct pcap object
pc.setfilter('icmp') # filter out unwanted packets
for timestamp, packet in pc:
    print dpkt.ethernet.Ethernet(packet)

output sample: 输出样本:

Ethernet(src='\x00\x03G\xb2M\xe4', dst='\x00\x03G\x06h\x18', data=IP(src='\n\x00\x01\x1c',
dst='\n\x00\x01\x10', sum=39799, len=60, p=1, ttl=128, id=35102, data=ICMP(sum=24667,
type=8, data=Echo(id=512, seq=60160, data='abcdefghijklmnopqrstuvwabcdefghi'))))

Ethernet(src='\x00\x03G\x06h\x18', dst='\x00\x03G\xb2M\xe4', data=IP(src='\n\x00\x01\x10',
dst='\n\x00\x01\x1c', sum=43697, len=60, p=1, ttl=255, id=64227, data=ICMP(sum=26715,
data=Echo(id=512, seq=60160, data='abcdefghijklmnopqrstuvwabcdefghi'))))

Use python-libpcap . 使用python-libpcap

import pcap

p = pcap.pcapObject()
dev = pcap.lookupdev()
p.open_live(dev, 1600, 0, 100)
#p.setnonblock(1)
try:
    for pktlen, data, timestamp in p:
        print "[%s] Got data: %s" % (time.strftime('%H:%M', 
                                                   time.localtime(timestamp)),
                                     data)
except KeyboardInterrupt:
    print '%s' % sys.exc_type
    print 'shutting down'
    print ('%d packets received, %d packets dropped'
           ' %d packets dropped by interface') % p.stats()

you can use raw sockets, with your interface ip address (in admin mode), 你可以使用原始套接字,你的接口IP地址(在管理模式下),

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.IPPROTO_IP)
s.bind(("YOUR_INTERFACE_IP",0))
s.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)
s.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON)
while True:
   data = s.recvfrom(10000)
   print data

Another option is pypcap . 另一种选择是pypcap

To parse the results, Construct is very slick. 要解析结果, Construct非常灵活。

If scapy, pleae try the following method. 如果是scapy,请尝试以下方法。 (It works on Windows 10) (适用于Windows 10)

# -*- coding: utf-8 -*-

# pip install scapy

"""
[{'name': 'Intel(R) 82574L Gigabit Network Connection',
  'win_index': '4',
  'description': 'Ethernet0',
  'guid': '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}',
  'mac': '00:0C:29:5C:EE:6D',
  'netid': 'Ethernet0'}]
"""

from pprint import pprint
from scapy.arch.windows import get_windows_if_list
from scapy.all import *


# disable verbose mode
conf.verb = 0


def parse_packet(packet):
    """sniff callback function.
    """
    if packet and packet.haslayer('UDP'):
        udp = packet.getlayer('UDP')
        udp.show()


def udp_sniffer():
    """start a sniffer.
    """
    interfaces = get_windows_if_list()
    pprint(interfaces)

    print('\n[*] start udp sniffer')
    sniff(
        filter="udp port 53",
        iface=r'Intel(R) 82574L Gigabit Network Connection', prn=parse_packet
    )


if __name__ == '__main__':
    udp_sniffer()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM