dpkt項目是一個`Python`模塊,主要用於對網路數據包進行解析和操作。它可以處理多種協議,例如`TCP`、`UDP`、`IP`等,並提供了一些常用的網路操作功能,例如計算校驗和、解析`DNS`數據包等。由於其簡單易用的特性,`dpkt`被廣泛應用於網路安全領域,例如流量分析、漏洞利用、入侵檢測... ...
dpkt項目是一個Python
模塊,主要用於對網路數據包進行解析和操作。它可以處理多種協議,例如TCP
、UDP
、IP
等,並提供了一些常用的網路操作功能,例如計算校驗和、解析DNS
數據包等。由於其簡單易用的特性,dpkt
被廣泛應用於網路安全領域,例如流量分析、漏洞利用、入侵檢測等。使用該庫可以快速解析通過各類抓包工具抓到的數據包,從而提取分析包內的參數。
- 安裝DPKT工具:pip install dpkt
在分析數據包之前我們需要抓取特定數據包並保存為*.pcap
格式,通常情況下這種數據包格式可通過WireShark
等工具抓取到,當然也可以使用上一篇提到的Scapy
庫實現,該庫中存在一個sniff
函數,該函數可以實現網路抓包功能,如下一個演示案例我們分別通過sniff(count=2)
函數抓取兩個數據包並使用wrpcap()
函數將其保存到文件內,當需要分析時可通過調用rdpcap()
函數打開數據包即可實現分析。
>>> from scapy.all import *
>>>
>>> packets = sniff(count=2) # 動態抓取2個數據包
>>>
>>> wrpcap("d://lyshark.pcap",packets) # 保存數據包
>>> pcap_packets = rdpcap("d://lyshark.pcap") # 讀取數據包
>>>
>>> pcap_packets
<lyshark.pcap: TCP:2 UDP:0 ICMP:0 Other:0>
>>>
>>> pcap_packets.show()
0000 Ether / IP / TCP 192.168.1.101:63995 > 172.217.24.10:https S
0001 Ether / IP / TCP 192.168.1.101:63907 > 103.235.46.191:https A / Raw
>>>
>>> pcap_packets.summary()
Ether / IP / TCP 192.168.1.101:63995 > 172.217.24.10:https S
Ether / IP / TCP 192.168.1.101:63907 > 103.235.46.191:https A / Raw
>>>
>>> pcap_packets[0].dst
'FF:2d:1e:0f:1e:a1'
>>>
>>> pcap_packets[0].src
'a4:7e:33:ee:cc:b3'
>>>
# 如下分別代表: 鏈路層 [Ethernet]、網路層[IP]、傳輸層[TCP/UDP]、應用層[RAW]
>>> pcap_packets[0].show()
>>>
# 抓包後直接輸出
>>> sniff(prn=lambda x: x.show(), count=1)
通過上方的抓包流程讀者即可實現簡單的抓包功能,當然sniff
函數參數眾多我們完全可以在抓包時增加不同的抓包條件,同時該函數也支持回調函數,當由新的請求被觸發時則自動執行回調函數,如下則是使用Scapy
抓包的完整案例,該案例展示了抓取60
秒數據包,並將其保存至d://lyshark.pcap
目錄。
from scapy.all import *
import scapy.all as scapy
# 數據包回調函數
def packet_callback(packet):
if packet[TCP].payload:
m_packet = str(packet[TCP].payload)
print("主機地址: {} ---> 數據包內容: {}".format(packet[IP].dst,packet[TCP].payload))
if __name__ == "__main__":
# 抓取80埠的數據包並輸出到屏幕
# sniff(filter="tcp port 80", prn=packet_callback, store=0)
# 抓取 過濾出tcp協議 抓取1分鐘後保存到文件中
package=sniff(filter="tcp", timeout=60, prn=packet_callback, store=1)
wrpcap("d://lyshark.pcap", package)
運行上方抓包程式,讀者可看到如下圖所示的輸出結果,等待60
秒後即可看到d://lyshark.pcap
文件。
當讀者抓取到這些數據包之後,下一步則是解析這些數據包,解析的方法有許多可以使用DPKT
解析,也可以使用scapy
自帶的工具解析,本章首先介紹如何使用Scapy
工具實現解析數據包內的HTTP
請求,並輸出的功能,如下是完整的代碼實現;
from scapy.all import *
import scapy.all as scapy
# 解析獲取到的數據包
def get_http_pcap(pcap_path):
pcap_infos = list()
packets = scapy.rdpcap(pcap_path)
for p in packets:
if p.haslayer("IP"):
src_ip = p["IP"].src
dst_ip = p["IP"].dst
if p.haslayer("TCP"):
raw_http = p["TCP"].payload.original
sport = p["TCP"].sport
dport = p["TCP"].dport
if p.haslayer("HTTPRequest"):
host = p["HTTPRequest"].Host
uri = p["HTTPRequest"].Path
http_fields = p["HTTPRequest"].fields
# print("主機地址: {} --> URI: {}".format(host,uri))
print("原IP地址: {}:{} --> 目標IP地址: {}:{}".format(src_ip,sport,dst_ip,dport))
if __name__ == "__main__":
get_http_pcap("d://lyshark.pcap")
讀者可自行運行上述代碼,並傳入剛纔抓取到的lyshark.pcap
數據包,此時則可解析出當前數據包中所有HTTP訪問數據,如下圖所示;
對於數據包的解包功能,Dpkt
工具包也可以很好的完成,對於使用Dpkt
解包而言,首先需要通過open()
打開數據包,接著調用dpkt.pcap.Reader(fp)
將文件內的位元組轉化為PCAP格式,最後調用自定義函數GetDpkt
根據欄位進行解析即可。
import dpkt
import socket
def GetDpkt(pcap):
for timestamp,packet in pcap:
try:
eth = dpkt.ethernet.Ethernet(packet)
ip = eth.data
tcp = ip.data
src = socket.inet_ntoa(ip.src)
dst = socket.inet_ntoa(ip.dst)
sport = tcp.sport
dport = tcp.dport
print("[+] 源地址: {}:{} --> 目標地址:{}:{}".format(src,sport,dst,dport))
except Exception:
pass
# 檢測主機是否被DDOS攻擊了
def FindDDosAttack(pcap):
pktCount = {}
for timestamp,packet in pcap:
try:
eth = dpkt.ethernet.Ethernet(packet)
ip = eth.data
tcp = ip.data
src = socket.inet_ntoa(ip.src)
dst = socket.inet_ntoa(ip.dst)
sport = tcp.sport
# 累計判斷各個src地址對目標地址80埠訪問次數
if dport == 80:
stream = src + ":" + dst
if pktCount.has_key(stream):
pktCount[stream] = pktCount[stream] + 1
else:
pktCount[stream] = 1
except Exception:
pass
for stream in pktCount:
pktSent = pktCount[stream]
# 如果超過設置的檢測閾值500,則判斷為DDOS攻擊行為
if pktSent > 500:
src = stream.split(":")[0]
dst = stream.split(":")[1]
print("[+] 源地址: {} 攻擊: {} 流量: {} pkts.".format(src,dst,str(pktSent)))
# FindPcapURL 監控提取數據包中的所有URL
def FindPcapURL(pcap):
Url = []
for timestamp,packet in pcap:
try:
eth = dpkt.ethernet.Ethernet(packet)
ip = eth.data
src = socket.inet_ntoa(ip.src)
tcp = ip.data
http = dpkt.http.Request(tcp.data)
if(http.method == "GET"):
UrlHead = http.headers
for key,value in UrlHead.items():
url = re.findall('^https*://.*',str(value))
if url:
print("[+] 源地址: %10s --> 訪問URL: %-80s"%(src, url[0]))
except Exception:
pass
return set(Url)
# 動態保存pcap文件(每1024位元組保存一次pcap文件),並讀取出其中的網址解析出來
def write_cap(pkt):
global pkts
global count
pkts.append(pkt)
count += 1
if count == 1024:
wrpcap("data.pcap",pkts)
fp = open("./data.pcap","rb")
pcap = dpkt.pcap.Reader(fp)
FindPcapURL(pcap)
fp.close()
pkts,count = [],0
if __name__ == "__main__":
fp = open("d://lyshark.pcap","rb")
pcap = dpkt.pcap.Reader(fp)
GetDpkt(pcap)
運行上述代碼,同樣可以輸出這些IP信息,如下圖所示;
本文作者: 王瑞
本文鏈接: https://www.lyshark.com/post/29b6bdae.html
版權聲明: 本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!
文章出處:https://www.cnblogs.com/LyShark/p/17777817.html
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!