mike01 / pypacker

:package: The fastest and simplest packet manipulation lib for Python
GNU General Public License v2.0
251 stars 46 forks source link

could not dissect in SSL: error('unpack requires a bytes object of length 2',) #44

Closed RadionBik closed 6 years ago

RadionBik commented 6 years ago

When I am trying to read packets from a pcap. file and convert them with ethernet.Ethernet() I am running into the following error:

ERROR (__init__): could not dissect in SSL: error('unpack requires a bytes object of length 2',)
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/pypacker-4.0-py3.5.egg/pypacker/pypacker.py", line 169, in __init__
    header_len = self._dissect(args[0])
  File "/usr/local/lib/python3.5/dist-packages/pypacker-4.0-py3.5.egg/pypacker/layer4/ssl.py", line 146, in _dissect
    record_len = unpack_H(buf[offset + 3: offset + 5])[0]
struct.error: unpack requires a bytes object of length 2

And the same code in ipython3 gives the following:

ValueError: not enough values to unpack (expected 2, got 1)

The code is as follows:

from pypacker import ppcap
from pypacker.layer12 import ethernet
from pypacker.layer3 import ip
from pypacker.layer4 import tcp,udp
for ts, raw in ppcap.Reader(filename=pcapfile):
    eth = ethernet.Ethernet(raw)   
        #create the keys for IP UDP/TCP flows
        if eth[ip.IP] is not None:
            print(eth)

The pcap file is available via the link: https://yadi.sk/d/p-ylrJSp3ToLAd

update: the binary form of a packet the error is being thrown from:

b'\xf4\xec8\xa8\xa0\xf2\x1coeN7\r\x08\x00E\x00\x05\x8cQk@\x00\x80\x06\xd7&\xc0\xa8\x01d\n\x00\x00\xce\xc5\xb9\x00PU\x06\xeaF\xf6g\xe5DP\x18\x01\x00\x03j\x00\x006\x007\x004\x00C\x001\x008\x00C\x007\x005\x009\x005\x00A\x00D\x003\x006\x00C\x00B\x005\x004\x00<\x00/\x00P\x00r\x00o\x00p\x00e\x00r\x00t\x00y\x00>\x00<\x00/\x00H\x00o\x00o\x00k\x002\x00>\x00<\x00/\x00H\x00o\x00o\x00k\x00s\x00>\x00<\x00P\x00a\x00y\x00l\x00o\x00a\x00d\x00 \x00T\x00y\x00p\x00e\x00=\x00"\x00i\x00n\x00l\x00i\x00n\x00e\x00"\x00/\x00>\x00<\x00T\x00a\x00r\x00g\x00e\x00t\x00H\x00o\x00s\x00t\x00>\x00S\x00R\x00V\x00-\x00S\x00C\x00C\x00M\x00.\x00d\x00c\x00k\x00a\x00i\x00.\x00r\x00u\x00<\x00/\x00T\x00a\x00r\x00g\x00e\x00t\x00H\x00o\x00s\x00t\x00>\x00<\x00T\x00a\x00r\x00g\x00e\x00t\x00E\x00n\x00d\x00p\x00o\x00i\x00n\x00t\x00>\x00M\x00P\x00_\x00R\x00e\x00l\x00a\x00y\x00E\x00n\x00d\x00p\x00o\x00i\x00n\x00t\x00<\x00/\x00T\x00a\x00r\x00g\x00e\x00t\x00E\x00n\x00d\x00p\x00o\x00i\x00n\x00t\x00>\x00<\x00R\x00e\x00p\x00l\x00y\x00M\x00o\x00d\x00e\x00>\x00A\x00s\x00y\x00n\x00c\x00<\x00/\x00R\x00e\x00p\x00l\x00y\x00M\x00o\x00d\x00e\x00>\x00<\x00P\x00r\x00o\x00t\x00o\x00c\x00o\x00l\x00>\x00h\x00t\x00t\x00p\x00<\x00/\x00P\x00r\x00o\x00t\x00o\x00c\x00o\x00l\x00>\x00<\x00/\x00M\x00s\x00g\x00>\x00\r\n--aAbBcCdDv1234567890VxXyYzZ\r\ncontent-type: application/octet-stream\r\n\r\nx\x9c\xed\x96[O\x1aQ\x10\xc7\xe7\xa3\x18^|h\x80\xdde+\xb4A\x1b\xb9l%\xd5\xd6Hm_\xfaB\x04\xd1\x14\xc4\x08^\xe8\x87o\xfb\x9b9\x0b\xec\xc5\x8a\xe9\xed\x89\x90\xb3;g.\xff3\xb73K]Nd \xd72\x91\x1b\x99\xc9\x9e\xd4S\xfb\x03\xe8\x9e\xf4y\xde\x98\xacc\xf4\x15\x92K9g\x9d!Uz\x02O\xe5G\xec\xcf\xe4\x02\xce\x15z\xcai\xca\x88\x9d\xb3\xe9\xf0\x9c\xf2\xee\xc1\x1b\xc1\xeb\xa3\xe1\xa3S^\xab\x95\xc6\xf9(s<\x1c<j\xbd\x92e\xcfn\xc1{+\xa7F\xbd\x96\x90g\x1b\x8d\x80g[<)JE\x1aP>T(\x91\xd4x\x16\xe1\xa8\x9eoT\x15\xed\x1a;\x8f_SvX\x11+\xef}+w\xf6\'\xcb\xdft\x99\xa7\x97R2\x94\x12x\x01\xe7\xbe\x82\xf2\x8d\xe3\xe5\xf0\xb2\xb6uy\x0fg\x86?\x1d\xf9 ]v=\x19[\xbc\'\xc4\xde\xc5S\x0f\xfc"\xcb\x03Yw.G\xbf\xb2RO\'V\xd5cxC\xe3\xd5\x88n\'\xf6$+\xabc=\xb7\xfa\x0c@h\xf1<Gv\x8b\xc739D\xdf\xc5\xaf\xd1\x84\xc4\xa5\x18\xcf\xd1W\xbd|\xef\x94\xd7\xf6[\xb2W[\x16a\x0f\xe9\x88\xf3\xb2\xd2\xa6\xd9\xccb\xb4=\xbc\x9a\x808\x93{,n\xe0~\x91\x07\xcb\x7f\xc0:2$\xcd\xbb\xfa2L\xc9Z\xe6A\xcf\xbc{\n?}\xfa\xaa+#\x8b}\x94\xb3O\xf6\xad;C\xe9\xc0\xeaW\xb3Z\x06t\xa0\xcf/\xe4]\xa1>%\xa3+q\xdf\xbc\x88\xf5\x14we_\xcf\xf5\x8fo\xbd\xa7Z\xf9\xce\x8a\xcc\x97\xb1Y\'5\xd3\xfc\xac\xe7\xf9\xbc\x97\x9f\x9c!\xe5\xcc\xc4\x11\xf9\xf1\xbd.o\xc8\xf1\x18\x84-\xb9K\xf9\xb5+\xdb\xb1\'\xdb\xc84\xbbg\xd6\x93\xae2*=%w\x11\x9d\xee\x93\x93mp\xb2\xb9\xdf\xcc\xb4\xcdL\xdb\xcc\xb4\xcdL\xfb\x973-)kX\x7f\xcd\x8d\x7f\x0cGw\xb7T\xd9M\x81s\xf6[\x96\xd91\x16=8\xf3e\xe7\xeeJ\x81\x93;\xe4\xadHf\x02z\xad\x80n\x1a#\xa9\xfb9u\xab\xf2\xba\xe9l\xa8\x85\x8b\x7f\xb1\xf2\x16\x87\xe6\xd1\x90\x9d\xbb\x1b\xce\xc6\xf5}!\xbe)\xe9\x1e\x8b,G\x83Dl\x0b\x8e\xe6p\n\xaav\xdc\xf5\xb2\xc3\x15\xf1\x10jh}XDS\xe9\t\'\xce\xb0\x1d\x9b\xce%\xb4\xe6\xb2\x90@{N,\x0b\xddd\x8e\xee\xf1`\x95\xa3\x12\xef\x07VR\xbb\xcb\xfb[\xac\xad]\xa8\xbd\x18\x18\xa2\xc6{\x80t\x1a\xfb\xe3\xee\xea(q\x97\x167g+\xc1\xd3\xe9\xbe\xe0\xeb$p\xb8:\x7f\xab\xfc\xda\x96O\x9d\xbd\x81\xf1t27\x98l\xb5\x98\xd76\x9ez\xa13/\x92}\x10\xaa\xbc}*\xd00\xbfO\xf1G\xcfIwMS\xde\xa1\xdb\xe1^\x9f\xa0\xdd\xc0\xd7\xafHoy^\xc4z}b\xb83\x84\xae\xf9\xe6n\xe8\xe5\x12\xe3\xb1{\xe9\xd97\xa3\x1a\xcfv/s/\x15\xabM^\xfbkqV\xf7;\xb09\x9c\xc7q>\xcd\xf0xj(\x958\xff\xe5gV\xe0\xef\xd5j\x9f\xfc\x85\xf1W\xb4j\xb5\xf2-\x8a\x96\xd5\xaa\x82\xc7\x91\xd5J\xe7f`_\xa5\x00N\xdb\xbe\xbd!R\xfd5\xcd\xff\xffU\xab\x1d\xeb\x0e\xcffF\xf8\x07\xb5r8\x15Cy\n\'[\xab\xe07jU^;I\x9c\xd6\xe3\x134?\x91\x93S7\xfb\x0f\xf3\'\x1e\xa4j\x16\r\n--aAbBcCdDv1234567890VxXyYzZ--'

Although dpkt seem to process it correctly.

mike01 commented 6 years ago

The pasted bytes seem to belong to a platintext HTTP packet, new master version contains fixes.

RadionBik commented 6 years ago

Thank you for the fast reply! Unfortunately, the error remains exactly in the same form, although, probably, for a different packet. Could you, please, check the library against the dump? the link is the following: https://yadi.sk/d/p-ylrJSp3ToLAd

mike01 commented 6 years ago

Most of the packets are fragmented TCP segments. You need complete packet bytes to create the SSL packets, pypacker can't recreate them from nothing.

RadionBik commented 6 years ago

So, I captured a trace in a completely different network with a different device, but I ran into the error again! Am I the only person who has faced it? :) The code is different now:

import re, dpkt, pcap
import pandas as ps
import numpy as np
import sklearn
import socket 

from pypacker import ppcap
from pypacker.layer12 import ethernet
from pypacker.layer3 import ip
from pypacker.layer4 import tcp,udp

def parseVoIPpacker(pcapfile,ipOfInterest,portsOfInterest):
    for ts, raw in ppcap.Reader(filename=pcapfile):
        eth = ethernet.Ethernet(raw)

        #create the keys for IP UDP/TCP flows
        if eth[ip.IP] is not None:
            if eth[udp.UDP] is not None:
                if ((eth.ip.src_s in ipOfInterest) or (eth.ip.dst_s in ipOfInterest)): #and ((eth.ip.udp.sport in portsOfInterest) or (eth.ip.udp.dport in portsOfInterest)):
                    #if ((eth.ip.udp.sport in portsOfInterest) or (eth.ip.udp.dport in portsOfInterest)):
                    key = (ts,'udp', frozenset(((eth.ip.src_s, eth.ip.udp.sport),(eth.ip.dst_s, eth.ip.udp.dport))))
                    print(key)
            else:
                continue

pcapfile = '../voiceTraces/wpNormalCall.pcap'

ipOfInterest = ['31.13.72.49', '176.59.109.149']
portsOfInterest = [45015,50787]
parseVoIPpacker(pcapfile,ipOfInterest,portsOfInterest)

Take a look at the commented condition (the one checking port numbers): as soon as I activate it, the error occurs again.

The trace is about 1MB and available via the link: https://yadi.sk/d/406rOCIL3U49zR

I want to emphasize that dpkt works flawlessly. I wonder what can be wrong here, taking into account that only UDP packets are being processed in the code.

mike01 commented 6 years ago

So to make it clear: you are talking about this type of error (e.g. appearing when parsing packet No. 3)?

ERROR (__init__): could not dissect in SSL: error('unpack requires a bytes object of length 2',)
Traceback (most recent call last):
  File "/usr/lib/python3.4/site-packages/pypacker-4.0-py3.4.egg/pypacker/pypacker.py", line 169, in __init__
    header_len = self._dissect(args[0])
  File "/usr/lib/python3.4/site-packages/pypacker-4.0-py3.4.egg/pypacker/layer4/ssl.py", line 146, in _dissect
    record_len = unpack_H(buf[offset + 3: offset + 5])[0]
struct.error: unpack requires a bytes object of length 2
RadionBik commented 6 years ago

yes, I meant exactly this error, although for a different packet number.

mike01 commented 6 years ago

That's exactly what I was talking about: Pypacker outputs warnings if it has problems dissecting bytes. You're trying to create a packet from incomplete packet bytes eg packet No. 3. Packet No. 3 is a TCP segment of a larger SSL stream spannning over multiple packets. Pypacker tries to dissect the bytes assuming it's a complete SSL packet, which it isn't. This leads to the errors (messages) you are seeing but you can access all values in the packet after all. In fact you can even access the non-dissectable bytes via body_bytes eg. eth.ip.tcp.body_bytes (assuming ip and tcp layers are present). Regarding dpkt: I can't see where it's parsing SSL/TLS (or any other application layer data above TCP) so I assume it gives a sh§% about it (see dpkt -> tcp.py). I've removed the warning outputs in the newest master commit, seems to be too confusing (;

mike01 commented 6 years ago

Closing due response timeout