python dpkt 解析 pcap 文件


dpkt Tutorial #2: Parsing a PCAP File

原文鏈接:https://jon.oberheide.org/blog/2008/10/15/dpkt-tutorial-2-parsing-a-pcap-file/
正如我們在dpkt庫第一部分教程所示,dpkt庫構建數據包很簡單。
Dpkt在解析數據包和文件時是等同效率的,所以在第二部分的教程中我們將會證明解析
PCAP文件和被它所包含的包。

Dpkt在創建和解析數據包上是一個非常棒的框架。然而dpkt並沒有很多文檔,一旦你熟悉使用這個模塊,其余方面就相當容易了。我將會用一些簡單的小任務作為 dpkt 教程,希望能提供一些文檔的例子。
如果你有任何項目想要用 dpkt 庫完成,就寫信給我。
在本教程中,我們不僅僅展示如何解析原始PCAP文件格式,而且如何會展示如何解析在PCAP文件中的數據包。讓我們開始吧!

讓我們解析一個之前捕獲的PCAP文件,test.pcap,包括了一些HTTP會話。如果我們打開dpkt/pcap.py模塊,我們可以看到它提供了一個讀取類,包含了一個文件對象和公開了一個類似於讀取記錄的接口給pypcap。讓我們用讀取類打開test.pcap吧:

f = open('test.pcap')
pcap = dpkt.pcap.Reader(f)

我們現在可以通過迭代pcap對象和訪問數據包的每一行的輸出。例如,我們可以打印出時間郵戳和數據包每個記錄的數據長度:

>>> for ts, buf in pcap:
>>>     print ts, len(buf)
1220901348.61 66
1220901348.68 66
...

當然,這會花費大量的效率解析數據包,讓它變得更友好,可用的格式。使用dpkt,我們可以簡單地傳遞一個原始的緩沖區給恰當的dpkt類並且讓它的內容自動解析和解碼到更友好的python對象:

for ts, buf in pcap:
    eth = dpkt.ethernet.Ethernet(buf)

傳遞數據包給dpkt 的Ethernet類,解析和解碼到eth對象。因為dpkt的Ethernet類同樣包括一些額外功能去解析已知的高層次的協議,我們可以看到IP層和TCP層的信息也被解碼:

>>> print eth
Ethernet(src='\x00\x1a\xa0kUf', dst='\x00\x13I\xae\x84,', data=IP(src='\xc0\xa8\n\n',
off=16384, dst='C\x17\x030', sum=25129, len=52, p=6, id=51105, data=TCP(seq=9632694,
off_x2=128, ack=3382015884, win=54, sum=65372, flags=17, dport=80, sport=56145)))

正如我們從輸出所看到的,eth是Ethernet對象,pkt.data是IP對象,pkt.data.data是個TCP對象。我們可以以更友好的方式分配索引給這些對象:

ip = eth.data
tcp = ip.data

我們照例查看不同對象的屬性。比如,我們可以看到源地址和TCP頭的目的端口:

>>> print tcp.sport
56145
>>> print tcp.dport
80

當然,自從我們知道數據包輸出包含了HTTP繪畫,我們也許想要解析超過TCP的層次如解碼HTTP請求。像這樣,我們會確保我們的目的端口是80端口(顯示一個與響應截然相反的請求)並且支持超過了tcp層的數據解析。我們會使用dpkt的HTTP解碼器去解析這些數據:
if tcp.dport == 80 and len(tcp.data) > 0:
    http = dpkt.http.Request(tcp.data)
一旦HTTP payload被解析,我們可以查看它的各個屬性:

>>> print http.method
GET
>>> print http.uri
/testurl
>>> print http.version
1.1
>>> print http.headers['user-agent']
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.5)

出於我們的教程的目標,我們僅僅會輸出http的uri屬性。

並且決定我們的教程是為了解析PCAP文件和文件里面的數據包。在僅僅10行python里,我們創造了一個讀取原始PCAP文件,解析和解碼Ethernet、IP、TCP、IP層和打印出HTTP請求的URI的強有力的工具。

教程接下來是完整的python腳本:

#!/usr/bin/env python

import dpkt

f = open('test.pcap')
pcap = dpkt.pcap.Reader(f)

for ts, buf in pcap:
    eth = dpkt.ethernet.Ethernet(buf)
    ip = eth.data
    tcp = ip.data

    if tcp.dport == 80 and len(tcp.data) > 0:
        http = dpkt.http.Request(tcp.data)
        print http.uri

f.close() 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM