码迷,mamicode.com
首页 > 其他好文 > 详细

scapy 解析pcap文件总结

时间:2017-12-23 17:13:50      阅读:555      评论:0      收藏:0      [点我收藏+]

标签:flags   except   auto   解决   报文   rdp   pos   gic   使用   

参考文献

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

  

 

scapy 解析pcap文件总结

标签:flags   except   auto   解决   报文   rdp   pos   gic   使用   

原文地址:http://www.cnblogs.com/14061216chen/p/8093441.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!