2015-05-19 144 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()'。 –