2015-05-19 148 views
2

我目前正在开发一个程序,该程序需要一个.pcap文件并使用scapy软件包将所有数据包通过ip分隔开。我想解压使用gzip包压缩的有效负载。我可以告诉大家,如果有效载荷gzip压缩的,因为它包含使用Python解压缩数据包的压缩负载

Content-Encoding: gzip 

我想使用

fileStream = StringIO.StringIO(payload) 
gzipper = gzip.GzipFile(fileobj=fileStream) 
data = gzipper.read() 

解压缩的有效载荷,其中

payload = str(pkt[TCP].payload) 

当我试图做到这一点我得到错误

IOError: Not a gzipped file 

当我打印的第一有效载荷我得到

HTTP/1.1 200 OK 
Cache-Control: private, max-age=0 
Content-Type: text/html; charset=utf-8 
P3P: CP="NON UNI COM NAV STA LOC CURa DEVa PSAa PSDa OUR IND" 
Vary: Accept-Encoding 
Content-Encoding: gzip 
Date: Sat, 30 Mar 2013 19:23:33 GMT 
Content-Length: 15534 
Connection: keep-alive 
Set-Cookie: _FS=NU=1; domain=.bing.com; path=/ 
Set-Cookie: _SS=SID=F2652FD33DC443498CE043186458C3FC&C=20.0; domain=.bing.com; path=/ 
Set-Cookie: MUID=2961778241736E4F314E732240626EBE; expires=Mon, 30-Mar-2015 19:23:33 GMT; domain=.bing.com; path=/ 
Set-Cookie: MUIDB=2961778241736E4F314E732240626EBE; expires=Mon, 30-Mar-2015 19:23:33 GMT; path=/ 
Set-Cookie: OrigMUID=2961778241736E4F314E732240626EBE%2c532012b954b64747ae9b83e7ede66522; expires=Mon, 30-Mar-2015 19:23:33 GMT; domain=.bing.com; path=/ 
Set-Cookie: SRCHD=D=2758763&MS=2758763&AF=NOFORM; expires=Mon, 30-Mar-2015 19:23:33 GMT; domain=.bing.com; path=/ 
Set-Cookie: SRCHUID=V=2&GUID=02F43275DC7F435BB3DF3FD32E181F4D; expires=Mon, 30-Mar-2015 19:23:33 GMT; path=/ 
Set-Cookie: SRCHUSR=AUTOREDIR=0&GEOVAR=&DOB=20130330; expires=Mon, 30-Mar-2015 19:23:33 GMT; domain=.bing.com; path=/ 

?}k{?H????+0?#!?,_???$?:?7vf?w?Hb???ƊG???9???/9U?\$;3{9g?ycAӗ???????W{?o?~?FZ?e ]>??<??n????׻?????????d?t??a?3? 
?2?p??eBI?e??????ܒ?P??-?Q?-L?????ǼR?³?ׯ??%' 
?2Kf?7???c?Y?I?1+c??,ae]?????<{?=ƞ,?^?J?ď???y??6O?_?z????_?ޞ~?_?????Bo%]???_?????W=? 

有关其他信息,这是分离,因为它包含的内容编码数据包:从gzip的一个项目提供了一个示例.pcap文件。

+0

我可能是错误的这一点,但我怀疑'gzip.GzipFile'要对付*文件*,如由类/函数的名称和文档提供(无论如何,对于2.7.x而言)。为了压缩/解压缩* buffers *,可能'zlib'模块(特别是'compress'和'decompress'函数)可能更合适...... – twalberg

+0

@twalberg,不,StringIO将会很好。 OP的问题是他没有将压缩的消息体与头分开,而是试图解压缩完整的消息。 –

+0

@LukasGraf这是我第二次猜测,但问题并不清楚是否有任何事情正在做删除标题等...... – twalberg

回答

2

为了解码压缩的HTTP响应,您只需要解码响应body,而不是标头。

你的情况中的​​是整个TCP负载,即包括标题和正文的整个HTTP消息。

HTTP消息(请求和响应)是RFC 822消息(它与E-Mail消息(RFC 2822)基于的通用消息格式相同)。

的822消息的结构是非常简单的:

  • 零个或多个首标线(由:分隔的键/值对),通过CRLF
  • 一个空行(CRLF(回车终止,换行,所以'\r\n'
  • 消息体

您现在可以以隔离体解析自己这个消息。但我宁愿RECOM修补你使用Python已经为你提供的工具。 httplib模块(Python 2.x)包含HTTPMessage类,httplib在内部使用该类来解析HTTP响应。它不是直接使用,但在这种情况下,我可能仍会使用它 - 它会为您处理一些HTTP特定的细节。

这里是你如何使用它的身体从头部分离:

>>> from httplib import HTTPMessage 
>>> 
>>> f = open('gzipped_response.payload') 
>>> 
>>> # Or, if you already have the payload in memory as a string: 
... # f = StringIO.StringIO(payload) 
... 
>>> status_line = f.readline() 
>>> msg = HTTPMessage(f, 0) 
>>> body = msg.fp.read() 

HTTPMessage类的工作以类似的方式rfc822.Message做:

  • 首先,你需要阅读(或丢弃)状态行(HTTP/1.1 200 OK),因为这不是RFC822消息的一部分,也不是头。

  • 然后,您将实例化HTTPMessage,其中句柄为打开文件,seekable参数设置为0。文件指针存储为msg.fp

  • 实例化时,它调用msg.readheaders(),它读取所有标题行,直到遇到空行(CRLF)。
  • 在这一点上,msg.fp已经进展到头结束和正文开始的地步。因此,您可以致电msg.fp.read()阅读留言的其余部分 - 正文。

之后,你的解压缩gzip压缩体代码只是工作:

>>> body_stream = StringIO.StringIO(body) 
>>> gzipper = gzip.GzipFile(fileobj=body_stream) 
>>> data = gzipper.read() 
>>> 
>>> print data[:25] 
<!DOCTYPE html> 
<html> 
+0

我现在遇到这个错误,实现你的建议代码: 'line = self。 fp.readline(_MAXLINE + 1)' 'AttributeError:'str'对象没有属性'readline'' – Delta

+0

看起来好像你直接使用字符串而不是'StringIO'来安装'HTTPMessage'。 –

+0

@Delta - 还要注意我稍微更新了代码。你需要通过调用'payload.readline()'来放弃第一行(状态行),然后你不需要自己调用'msg.readheaders()'。 –