ZT - UNIX 网络协议的深度分析(3)

解析原始数据以理解数据包内容

处理来自 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 地址信息的简单脚本。


清单 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 数据包。


清单 9. 在非 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 所示的结果。


清单 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/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/16896827/viewspace-1036463/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值