![](/img/trans.png)
[英]Python Packet Sniffing / Packet Capture - pcapy not capturing packets
[英]Packet sniffing in Python (Windows)
使用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協議格式的圖像,其大小為每個報頭的位。
本教程可能有助於您了解理解原始數據包並將其拆分為標題的過程: 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()
你可以使用原始套接字,你的接口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
如果是scapy,請嘗試以下方法。 (適用於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.