scapy 解析pcap文件总结

参考文献

http://blog.csdn.net/meanong/article/details/53942116

https://github.com/invernizzi/scapy-http

 目录:

  1. scapy存在的问题与解决方案

    1.1 内存泄漏问题

    1.2 解决方案

    1.3 不支持HTTP协议解析

    1.4 解决方案

  2. pcap文件解析实例

1. scapy存在的问题与解决方案

1.1 内存泄漏问题

  在使用 rdpcap() 函数读取pcap文件里的数据时,会发生内存泄漏问题,多读几个文件的话可能内存就满了。

  具体的原因在于 scapy 库在读取pcap文件时,open了文件却没有close,而用户又没有办法去close,所以会产生内存泄漏。

  rdpcap()函数源码如下:

  def rdpcap(filename, count=-1):
        """Read a pcap file and return a packet list
        count: read only <count> packets"""
        return PcapReader(filename).read_all(count=count)

  PcapReader类的read_all()函数继承于父类RawPcapReader,函数源码如下:

def read_all(self,count=-1):
    """return a list of all packets in the pcap file
    """
    res=[]
    while count != 0:
        count -= 1
        p = self.read_packet()
        if p is None:
            break
        res.append(p)
    return res

  在进一步查看其__init__()函数就会发现,它只写了打开文件的代码却没有close掉。

def __init__(self, filename):
    self.filename = filename
    try:
        self.f = gzip.open(filename,"rb")
        magic = self.f.read(4)
    except IOError:
        self.f = open(filename,"rb")
        magic = self.f.read(4)
    if magic == "\xa1\xb2\xc3\xd4": #big endian
        self.endian = ">"
    elif  magic == "\xd4\xc3\xb2\xa1": #little endian
        self.endian = "<"
    else:
        raise Scapy_Exception("Not a pcap capture file (bad magic)")
    hdr = self.f.read(20)
    if len(hdr)<20:
        raise Scapy_Exception("Invalid pcap file (too short)")
    vermaj,vermin,tz,sig,snaplen,linktype = struct.unpack(self.endian+"HHIIII",hdr)

    self.linktype = linktype

  

1.2 解决方案

1.2.1 修改源码

  相关部分的源码都在 scapy/utils.py文件下,只需要修改 rdpcap() 函数的内容即可,修改后的结果如下:

def rdpcap(filename, count=-1):
    """Read a pcap or pcapng file and return a packet list
    count: read only <count> packets
    """
    pcap = PcapReader(filename)
    data = pcap.read_all(count=count)
    pcap.close()
    return data

  在close掉pcap这个实例的时候,里面打开的文件也会被一同close掉。

1.2.2 不使用rdpacp()函数读取pcap文件数据

  

pr = PcapReader(‘E:/HTTP/Code/data/group1.pcap‘)
while True:
    packege = pr.read_packet()
    if packege is None:
        break
    else:
        #TODO
pr.close()

  这里我们直接实例化一个PcapReader对象,然后一个一个 的读取里面的包数据,最后再将这个实例关掉。

1.3 不支持HTTP协议解析

  查看 scapy/layers 就会发现,scapy不支持HTTP协议,我试着分析了一下包含HTTP协议的报文,结果都被解析为RAW协议了。

  如下:

  

<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=260 id=38843 flags=DF frag=0L ttl=63 proto=tcp chksum=0xce48 src=172.16.113.84 dst=206.161.232.233 options=[] |<TCP  sport=13002 dport=http seq=138591001 ack=2983383564L dataofs=5L reserved=0L flags=PA window=32120 chksum=0xa1c5 urgptr=0 options=[] |<Raw  load=‘GET /autoplus/autoplus.gif HTTP/1.0\r\nReferer: http://www.bostonian.com/\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)\r\nHost: www.bostonian.com\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n\r\n‘ |>>>>

  

1.4 解决方案

  有人对scapy进行了补充,项目地址:https://github.com/invernizzi/scapy-http

  只需要使用pip安装即可:

  

pip install scapy-http

  然后再程序里导入http层即可解析http协议

import scapy.all as scapy
from scapy.layers import http

  

2. pcap文件解析实例

# -*- coding:utf-8 -*-
import scapy.all as scapy
from scapy.layers import http

# 提取出pacp文件中的所有包
packeges = scapy.rdpcap(‘E:/HTTP/Code/data/group5.pcap‘)
print packeges

  这里我们直接打印 packeges ,输出的是所有包的类型信息,如下

<group5.pcap: TCP:1323 UDP:0 ICMP:0 Other:0>

  

for p in packages:
    print repr(p)

  这里就可以打印出每一个包的详细信息,如下:

<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=290 id=42742 flags=DF frag=0L ttl=63 proto=tcp chksum=0xb263 src=172.16.113.84 dst=167.8.29.15 options=[] |<TCP  sport=31009 dport=http seq=1946692237 ack=672469499 dataofs=5L reserved=0L flags=PA window=32120 chksum=0xf91c urgptr=0 options=[] |<HTTP  |<HTTPRequest  Method=u‘GET‘ Path=u‘/leadpage/credit/credrib.gif‘ Http-Version=u‘HTTP/1.0‘ Host=u‘www.usatoday.com‘ User-Agent=u‘Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ Accept=u‘image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*‘ Referer=u‘http://www.usatoday.com/leadpage/credit/credit.htm‘ Headers=u‘Host: www.usatoday.com\r\nReferer: http://www.usatoday.com/leadpage/credit/credit.htm\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ |>>>>>
<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=281 id=42838 flags=DF frag=0L ttl=63 proto=tcp chksum=0xb20c src=172.16.113.84 dst=167.8.29.15 options=[] |<TCP  sport=31011 dport=http seq=4290014843L ack=3755501580L dataofs=5L reserved=0L flags=PA window=32120 chksum=0xe139 urgptr=0 options=[] |<HTTP  |<HTTPRequest  Method=u‘GET‘ Path=u‘/feedback/buyus.htm‘ Http-Version=u‘HTTP/1.0‘ Host=u‘www.usatoday.com‘ User-Agent=u‘Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ Accept=u‘image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*‘ Referer=u‘http://www.usatoday.com/leadpage/credit/credit.htm‘ Headers=u‘Host: www.usatoday.com\r\nReferer: http://www.usatoday.com/leadpage/credit/credit.htm\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ |>>>>>
<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=273 id=42847 flags=DF frag=0L ttl=63 proto=tcp chksum=0xb20b src=172.16.113.84 dst=167.8.29.15 options=[] |<TCP  sport=31018 dport=http seq=1370418497 ack=2248894642L dataofs=5L reserved=0L flags=PA window=32120 chksum=0xf812 urgptr=0 options=[] |<HTTP  |<HTTPRequest  Method=u‘GET‘ Path=u‘/inetart/scribe.gif‘ Http-Version=u‘HTTP/1.0‘ Host=u‘www.usatoday.com‘ User-Agent=u‘Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ Accept=u‘image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*‘ Referer=u‘http://www.usatoday.com/feedback/buyus.htm‘ Headers=u‘Host: www.usatoday.com\r\nReferer: http://www.usatoday.com/feedback/buyus.htm\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ |>>>>>

  这里每个包 p 的结构如下:

    物理层 --> 网络层 --> 传输层 --> 应用层

  每一层的数据都可以根据相应层的协议名获取,然后再通过字段名获取具体层具体字段的信息,代码如下:

for p in packages:
    print repr(p)
    print p[‘Ether‘].name
    print p[‘Ether‘].dst
    print p[‘Ether‘].src

    print p[‘IP‘].name
    print p[‘IP‘].dst
    print p[‘IP‘].src

    print p[‘TCP‘].name
    print p[‘TCP‘].sport
    print p[‘TCP‘].dport

  输出结果如下:

<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=204 id=7838 flags=DF frag=0L ttl=63 proto=tcp chksum=0x7ceb src=172.16.113.84 dst=207.46.179.15 options=[] |<TCP  sport=1751 dport=http seq=2094829820 ack=3501118724L dataofs=5L reserved=0L flags=PA window=32120 chksum=0x91d6 urgptr=0 options=[] |<HTTP  |<HTTPRequest  Method=u‘GET‘ Path=u‘/‘ Http-Version=u‘HTTP/1.0‘ Host=u‘home.microsoft.com‘ User-Agent=u‘Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ Accept=u‘image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*‘ Headers=u‘Host: home.microsoft.com\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ |>>>>>
Ethernet
00:60:97:de:54:36
00:00:0c:04:41:bc
IP
207.46.179.15
172.16.113.84
TCP
1751
80
<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=256 id=7878 flags=DF frag=0L ttl=63 proto=tcp chksum=0x7f6b src=172.16.113.84 dst=207.46.176.51 options=[] |<TCP  sport=1814 dport=http seq=1495749711 ack=1496378949 dataofs=5L reserved=0L flags=PA window=32120 chksum=0xfd2b urgptr=0 options=[] |<HTTP  |<HTTPRequest  Method=u‘GET‘ Path=u‘/mps_id_sharing/redirect.asp?home.microsoft.com/Default.asp‘ Http-Version=u‘HTTP/1.0‘ Host=u‘msid.msn.com‘ User-Agent=u‘Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ Accept=u‘image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*‘ Headers=u‘Host: msid.msn.com\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ |>>>>>
Ethernet
00:60:97:de:54:36
00:00:0c:04:41:bc
IP
207.46.176.51
172.16.113.84
TCP
1814
80
<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=256 id=7888 flags=DF frag=0L ttl=63 proto=tcp chksum=0x7c85 src=172.16.113.84 dst=207.46.179.15 options=[] |<TCP  sport=1876 dport=http seq=3929480773L ack=300743146 dataofs=5L reserved=0L flags=PA window=32120 chksum=0x7f03 urgptr=0 options=[] |<HTTP  |<HTTPRequest  Method=u‘GET‘ Path=u‘/Default.asp?newguid=1e5bf4633b9f11d2a26600805fb7e334‘ Http-Version=u‘HTTP/1.0‘ Host=u‘home.microsoft.com‘ User-Agent=u‘Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ Accept=u‘image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*‘ Headers=u‘Host: home.microsoft.com\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ |>>>>>
Ethernet
00:60:97:de:54:36
00:00:0c:04:41:bc
IP
207.46.179.15
172.16.113.84
TCP
1876
80

  

  这里也有个比较重要的属性 payload ,可以获取上一层协议的数据,比如:

for p in packages:
    print repr(p)

    print p.name
    print p.payload.name
    print p.payload.payload.name

  这里就可以把前三层所使用的协议名打出来:

<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=204 id=7838 flags=DF frag=0L ttl=63 proto=tcp chksum=0x7ceb src=172.16.113.84 dst=207.46.179.15 options=[] |<TCP  sport=1751 dport=http seq=2094829820 ack=3501118724L dataofs=5L reserved=0L flags=PA window=32120 chksum=0x91d6 urgptr=0 options=[] |<HTTP  |<HTTPRequest  Method=u‘GET‘ Path=u‘/‘ Http-Version=u‘HTTP/1.0‘ Host=u‘home.microsoft.com‘ User-Agent=u‘Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ Accept=u‘image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*‘ Headers=u‘Host: home.microsoft.com\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ |>>>>>
Ethernet
IP
TCP
<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=256 id=7878 flags=DF frag=0L ttl=63 proto=tcp chksum=0x7f6b src=172.16.113.84 dst=207.46.176.51 options=[] |<TCP  sport=1814 dport=http seq=1495749711 ack=1496378949 dataofs=5L reserved=0L flags=PA window=32120 chksum=0xfd2b urgptr=0 options=[] |<HTTP  |<HTTPRequest  Method=u‘GET‘ Path=u‘/mps_id_sharing/redirect.asp?home.microsoft.com/Default.asp‘ Http-Version=u‘HTTP/1.0‘ Host=u‘msid.msn.com‘ User-Agent=u‘Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ Accept=u‘image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*‘ Headers=u‘Host: msid.msn.com\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ |>>>>>
Ethernet
IP
TCP
<Ether  dst=00:60:97:de:54:36 src=00:00:0c:04:41:bc type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=256 id=7888 flags=DF frag=0L ttl=63 proto=tcp chksum=0x7c85 src=172.16.113.84 dst=207.46.179.15 options=[] |<TCP  sport=1876 dport=http seq=3929480773L ack=300743146 dataofs=5L reserved=0L flags=PA window=32120 chksum=0x7f03 urgptr=0 options=[] |<HTTP  |<HTTPRequest  Method=u‘GET‘ Path=u‘/Default.asp?newguid=1e5bf4633b9f11d2a26600805fb7e334‘ Http-Version=u‘HTTP/1.0‘ Host=u‘home.microsoft.com‘ User-Agent=u‘Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ Accept=u‘image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*‘ Headers=u‘Host: home.microsoft.com\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\nUser-Agent: Mozilla/3.01 (X11; I; SunOS 4.1.4 sun4u)‘ |>>>>>
Ethernet
IP
TCP

  

时间: 2024-11-29 05:21:59

scapy 解析pcap文件总结的相关文章

python解析pcap文件中的http数据包

使用scapy.scapy_http就可以方便的对pcap包中的http数据包进行解析 scapy_http可以在https://github.com/invernizzi/scapy-http下载,该地址下也给出了简单的示例程序,按照此示例程序我修改了一个输出pcap包中http包的源目的地址.payload的小程序,如下所示: 其中,p为数据包,scapy_http将其分为: Ethernet->TCP->RAW三个层次, 使用p.show()函数可以打印出如下结果: ###[ Ether

pcap文件的python解析实例

最近一直在分析数据包.同时也一直想学python. 凑一块儿了...于是,便开工了.座椅爆炸! 正文 首先要说的是,我知道python有很多解析pcap文件的库,这里不使用它们的原因是为了理解pcap文件的格式细节.使用tcpdump你可以很容易抓取到一系列的数据包,然而tcpdump并没有分析数据包的功能,如果想从这个抓包文件中分析出一些端倪,比如重传情况,你必须使用wireshark之类的软件,用wireshark打开tcpdump抓取的pcap文件,如果你看到了一堆堆的深红色(类似静脉血管

Windows下使用scapy+python2.7实现对pcap文件的读写操作

scapy在linux环境中对pcap文件进行操作非常方便,但在windows下,特别是在python2.7环境下却会碰到各种各样的依赖包无法使用的问题,最明显的可能就属dnet和pcap的python依赖包了,因为scapy的conf.use_pcap和conf.use_dnet在windows环境下无法进行配置,在scapy\arch\windows\__init__.py中都被强行置为1了,也就是必须使用pcap和dnet依赖包.具体代码如下所示 from scapy.sendrecv i

Nginx、Apache解析php文件的区别

一.Apache是如何解析php文件的 我们常说的lamp架构是linux.apache.mysql.php,我们知道任何架构或者网站离不开数据库的支持,那么php和apache又是如何协同工作的呢? php是apache的一个外挂程序,必须依靠web服务器才可以运行.当客户端浏览器触发事件--->php程序提交到apache服务器---->apache服务器根据php程序的特点判断是php程序,并从内存或者硬盘中提取访问所需要的应用程序,将其提交给php引擎程序--->php引擎程序解

接口测试-解析har文件

之前我已经研究到让业务测试通过不同方式来获取我们工具需要的har文件,现在我们拿到了业务测试提供的har文件,我们首先要解析这些文件里存放的信息,特别是entries字段里的信息,在万能的github上果然搜出来一个工具包 地址 har 因为maven库里还没有这个jar包提供下载,你需要将源码下载到本地,打包后上传到自己公司的私有库里,供其他开发者下载 源码 主要的类为HarUtils.java,还有命令行下执行需要的2个类(HarCli.java,ViewHar.java),这两个类的主要作

Java通过jxl解析Excel文件入库,及日期格式处理方式 (附源代码)

JAVA可以利用jxl简单快速的读取文件的内容,但是由于版本限制,只能读取97-03  xls格式的Excel. 本文是项目中用到的一个实例,先通过上传xls文件(包含日期),再通过jxl进行读取上传的xls文件(文件格式见下user.xls),解析不为空的行与列,写入数据库. 文件user.xls格式为: 下面来看代码实例演示: 一.前端jsp页面(本来内容很多,这里精简了) <%@ page language="java" contentType="text/htm

java解析properties文件

在自动化测试过程中,经常会有一些公用的属性要配置,以便后面给脚本使用,我们可以选择xml, excel或者json格式来存贮这些数据,但其实java本身就提供了properties类来处理properties文件,虽然名字叫properties,其实打开它发现就是一个记事本的文件,所以看起来也比较直观,下面是解析properties文件的实现代码. properties文件里存贮的样子是这样的,然后给他保存为xxx.properties即可. gsBAMUserName1=automation_

练习:读取解析CSV文件,将读取结果输出的控制台上,并封装到4个Teacher对象中.

/** *    读取解析CSV文件,将读取结果输出的控制台上,并封装到4个Teacher对象中. *    1, 土鳖, 13101015338, 北京海淀区 2, 咪咪, 13201015338, 北京朝阳区 3, 小仓, 13601015818, 北京宣武区 4, 饭岛爱, 13201025818, 北京朝阳区 /** * 读取解析CSV文件,将读取结果输出的控制台上,并封装到4个Teacher对象中. * 1, 土鳖, 13101015338, 北京海淀区 2, 咪咪, 13201015

使用XML序列化器生成XML文件和利用pull解析XML文件

首先,指定XML格式,我指定的XML格式如下: <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <message> <sms> <body> 陈驰0 </body> <date> 1462162910995 </date> <address> 1380 </address> <type> 1 </type> &