使用Python嗅探网络数据包的最佳方法是什么?
我从几个地方听说,最好的模块是一个名为Scapy的模块,不幸的是,它使我的系统上的python.exe崩溃。我会认为这只是我安装它的一个问题,除了很多其他人告诉我它在Windows上运行效果不佳。 (如果有人有兴趣,我正在运行Windows Vista,这可能会影响事情。)
有谁知道更好的解决方案?
UPD:
在阅读了告诉我安装PyPcap的答案之后,我稍微搞砸了一下,发现我曾尝试使用的Scapy也告诉我安装PyPcap,不过它是一个修改版本供它使用。显然,正是这个修改过的PyPcap引起了问题,因为答案中的例子也导致了问题。
我安装了PyPcap的原始版本(来自谷歌的网站),而且Scapy开始正常工作(我没有尝试过很多东西,但至少它在我开始嗅探时没有崩溃)。我向Scapy开发人员发送了一张新的缺陷票:http://trac.secdev.org/scapy/ticket/166,希望他们能用它做点什么。
无论如何,只是以为我会让你们都知道。
答案 0 :(得分:13)
您可以使用原始套接字嗅探所有IP数据包
Raw socket是一个以二进制形式发送和接收数据的套接字
python中的二进制文件用字符串表示,看起来像\x00\xff
...每个\x..
都是一个字节。
要读取IP数据包,您需要根据IP协议分析二进制接收的数据包。
这是IP协议格式的图像,其大小为每个标题的位。
本教程可帮助您了解理解原始数据包并将其拆分为标题的过程: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。 您可以通过阅读此处的文档来了解更多信息:http://www.secdev.org/projects/scapy/doc/usage.html
这取决于您尝试实现的目标,但如果您需要构建项目,那么它的功能就是嗅探IP数据包,那么我建议使用scapy来获得更稳定的脚本。
答案 1 :(得分:11)
使用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'))))
答案 2 :(得分:8)
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()
答案 3 :(得分:2)
您可以使用原始套接字,使用您的接口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
答案 4 :(得分:1)
答案 5 :(得分:1)
如果是肩cap骨,请尝试以下方法。 (适用于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()