处理来自 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/