使用Python嗅探网络数据包的最佳方法是什么?
我从几个地方听说,最好的模块是一个名为Scapy的模块,不幸的是,它使我的系统上的python.exe崩溃.我会认为这只是我安装它的一个问题,除了很多其他人告诉我它在Windows上运行效果不佳.(如果有人有兴趣,我正在运行Windows Vista,这可能会影响事情).
有谁知道更好的解决方案?
UPD:
在阅读了告诉我安装PyPcap的答案之后,我稍微搞砸了一下,发现我曾尝试使用的Scapy也告诉我安装PyPcap,除了它是一个修改版本供它使用.正是这个修改过的PyPcap导致了问题,显然,因为答案中的例子也导致了问题.
我安装了原始版本的PyPcap(来自谷歌的网站),而且Scapy开始工作正常(我没有尝试过很多东西,但至少它在我开始嗅探时没有崩溃).我向Scapy开发人员发送了一张新的缺陷票:http://trac.secdev.org/scapy/ticket/166 ,希望他们能用它做点什么.
无论如何,只是想我会让你们都知道.
您可以使用原始套接字嗅探所有IP数据包.
Raw socket是一个以二进制形式发送和接收数据的套接字.
python中的二进制文件用字符串表示,看起来像这样\x00\xff
......每个\x..
都是一个字节.
要读取IP数据包,您需要根据IP协议分析二进制接收的数据包.
这是IP协议格式的图像,其大小为每个报头的位.
IP协议格式http://cfs13.blog.daum.net/image/6/blog/2008/04/26/19/15/481300a2a7674&filename=IP_Header.png
本教程可能有助于您了解理解原始数据包并将其拆分为标题的过程:http://www.binarytides.com/python-packet-sniffer-code-linux/
简单的方法另一种非常容易嗅探IP数据包的方法是使用scapy模块.
from scapy.all import * sniff(filter="ip", prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}"))
此代码将为您打印每个IP数据包的源IP和目标IP.你可以通过阅读它的文档来做更多的scapy:http://www.secdev.org/projects/scapy/doc/usage.html
这取决于你想要实现的目标,但如果你需要构建一个项目,它的功能是嗅探IP数据包,那么我建议使用scapy来获得更稳定的脚本.
使用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)
输出样本:
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'))))
使用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()