ZT - UNIX 網路協議的深度分析(3)

saintsiro發表於2010-08-08

處理來自 tcpdump 的另一個方法是將原始網路資料包資料儲存到一個檔案中,然後處理這個檔案以便查詢和解碼出您想要的資訊。

[@more@]

處理來自 tcpdump 的另一個方法是將原始網路資料包資料儲存到一個檔案中,然後處理這個檔案以便查詢和解碼出您想要的資訊。

有許多使用不同語言編寫的模組具有讀取和解碼 tcpdump 和 snoop 捕捉的資料的功能。例如,有兩個用 Perl 編寫的模組:Net::SnoopLog(針對 snoop)和 Net::TcpDumpLog(針對 tcpdump)。它們將讀取原始資料內容。這些模組的基本介面是相同的。

要開始處理,您首先需要使用 snoop 或 tcpdump 將資料寫到一個檔案,而建立一個透過網路的資料包的二進位制記錄。對於本例,我們將使用 tcpdump 和 Net::TcpDumpLog 模組:$ tcpdump -w packets.raw

收集網路資料完成後,您就可以開始處理網路資料內容以查詢您想要的資訊。Net::TcpDumpLog 會解析 tcpdump 所儲存的原始網路資料。因為這些資料是以原始的二進位制格式儲存的,解析這些資訊就需要處理這個二進位制資料。為了方便起見,您可以使用另一組模組 NetPacket::* 來解碼原始資料。

例如,清單 8 顯示的是一個列印所有資料包的 IP 地址資訊的簡單指令碼。



				
use Net::TcpDumpLog;
    
use NetPacket::Ethernet;
    
use NetPacket::IP;

    
my $log = Net::TcpDumpLog->new();
 
$log->read("packets.raw");
 
 
foreach my $index ($log->indexes)
       
{
    
    my $packet = $log->data($index);
           

    my $ethernet = NetPacket::Ethernet->decode($packet);

  
    if ($ethernet->{type} == 0x0800)
       
    {
    
        my $ip = NetPacket::IP->decode($ethernet->{data});
          

    
        printf("  %s to %s protocol %s n",
               $ip->{src_ip},$ip->{dest_ip},$ip->{proto});
   }

} 

第一部分是提取每一個資料包。Net::TcpDumpLog 模組會將每一個資料包序列化,這樣我們就能夠透過資料包 ID 讀取每一個資料包。然後 data() 函式就會返回整個資料包的原始資料。

透過 snoop 的輸出,我們必須從原始網路資料包資訊中提取每一個資料塊。所以在本例中,我們首先需要從原始網路資料包中提取 Ethernet 資料包,包括資料有效負載。而 NetPacket::Ethernet 模組能夠幫我們執行這個操作。

因為我們尋找的是 IP 資料包,所以我們能透過檢查 Ethernet 資料包型別來檢查 IP 資料包。IP 資料包的 ID 為 0x0800。

然後,NetPacket::IP 模組會被用於從 Ethernet 資料包的資料負載中提取出 IP 資訊。這個模組能提供來源 IP、目標 IP 和協議資訊等等,然後我們可以列印出這些資訊。

透過使用這個基本的框架,您就能夠執行不依賴於 tcpdump 或 snoop 的自動化解決方案的更復雜查詢和解碼。例如,如果您懷疑 HTTP 流量是透過一個非標準埠傳輸的(如,不是埠 80),那麼您可以使用 清單 9 中的指令碼在懷疑的主機 IP 的非 80 埠上檢查 HTTP 資料包。



				
use Net::TcpDumpLog;
    
use NetPacket::Ethernet;
    
use NetPacket::IP;
    
use NetPacket::TCP;
    

    
my $log = Net::TcpDumpLog->new();
       
$log->read("packets.raw");
       

    
foreach my $index ($log->indexes)
       
{
    
    my $packet = $log->data($index);
       

    
    my $ethernet = NetPacket::Ethernet->decode($packet);
       

    
    if ($ethernet->{type} == 0x0800)
       
    {
    
        my $ip = NetPacket::IP->decode($ethernet->{data});
          

    
        if ($ip->{src_ip} eq '192.168.0.2')
       
        {
    
            if ($ip->{proto} == 6)
       
            {
    
                my $tcp = NetPacket::TCP->decode($ip->{data});
       
                if (($tcp->{src_port} != 80) &&
               
                    ($tcp->{data} =~ m/HTTP/))
       
                {
    
                    print("Found HTTP traffic on non-port 80n");
    
                    printf("%s (port: %d) to %s (port: %d)n%sn",
    
                           $ip->{src_ip},
       
                           $tcp->{src_port},
       
                           $ip->{dest_ip},
       
                           $tcp->{dest_port},
       
                           $tcp->{data});
 
                }
    
            }
    
        }
    
   }
    
}

在一個示例資料包集上執行上面的指令碼會返回如 清單 10 所示的結果。



				
$ perl http-non80.pl
Found HTTP traffic on non-port 80
192.168.0.2 (port: 39280) to 168.143.162.100 (port: 80)
GET /statuses/user_timeline.json HTTP/1.1
Found HTTP traffic on non-port 80
192.168.0.2 (port: 39282) to 168.143.162.100 (port: 80)
GET /statuses/friends_timeline.json HTTP/1

在這種特定的情況下,我們發現主機的流量是通向一個外部網站(Twitter)。

顯然,在這個例子中我們處理的是原始資料,但是您可以使用相同的基本結構進行解碼,也可以使用任何公開或私有協議結構的格式的資料。如果您正在使用這個方法使用或開發一個協議,並且您知道協議格式,您就能夠提取和監控正在傳輸的資料。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16896827/viewspace-1036463/,如需轉載,請註明出處,否則將追究法律責任。

相關文章