secdev / scapy

Scapy: the Python-based interactive packet manipulation program & library.
https://scapy.net
GNU General Public License v2.0
10.67k stars 2.02k forks source link

Packet.__len__ throwing exception on deeply-nested packet #1552

Closed calebmadrigal closed 6 years ago

calebmadrigal commented 6 years ago

Packet.len throwing exception on deeply-nested packet

Environment

How to reproduce

I'm at DEF CON, and I think I intercepted some unknown packet which was deeply nested, based on the Traceback.

Actual result

Traceback (most recent call last):
  File "/usr/local/bin/trackerjacker", line 11, in <module>
    load_entry_point('trackerjacker==1.8.3', 'console_scripts', 'trackerjacker')()
  File "/usr/local/lib/python3.6/dist-packages/trackerjacker/__main__.py", line 303, in main
    tj.start()
  File "/usr/local/lib/python3.6/dist-packages/trackerjacker/__main__.py", line 220, in start
    scapy.sniff(iface=self.iface_manager.iface, prn=self.process_packet, store=0)
  File "/usr/local/lib/python3.6/dist-packages/scapy/sendrecv.py", line 780, in sniff
    r = prn(p)
  File "/usr/local/lib/python3.6/dist-packages/trackerjacker/__main__.py", line 153, in process_packet
    frame = dot11_frame.Dot11Frame(pkt, int(self.iface_manager.current_channel), iface=self.iface_manager.iface)
  File "/usr/local/lib/python3.6/dist-packages/trackerjacker/dot11_frame.py", line 25, in __init__
    self.frame_bytes = len(frame)
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 375, in __len__
    return len(self.__bytes__())
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 345, in __bytes__
    return self.build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 444, in build
    p = self.do_build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 429, in do_build
    pay = self.do_build_payload()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 416, in do_build_payload
    return self.payload.do_build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 429, in do_build
    pay = self.do_build_payload()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 416, in do_build_payload
    return self.payload.do_build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 429, in do_build
    pay = self.do_build_payload()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 416, in do_build_payload
    return self.payload.do_build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 429, in do_build
    pay = self.do_build_payload()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 416, in do_build_payload
    return self.payload.do_build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 429, in do_build
    pay = self.do_build_payload()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 416, in do_build_payload
    return self.payload.do_build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 429, in do_build
    pay = self.do_build_payload()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 416, in do_build_payload
    return self.payload.do_build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 429, in do_build
    pay = self.do_build_payload()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 416, in do_build_payload
    return self.payload.do_build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 426, in do_build
    pkt = self.self_build()
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 391, in self_build
    if self.getfieldval(fname) != fval:
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 872, in __ne__
    return not self.__eq__(other)
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 869, in __eq__
    return self.payload == other.payload
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 869, in __eq__
    return self.payload == other.payload
  File "/usr/local/lib/python3.6/dist-packages/scapy/packet.py", line 869, in __eq__
    return self.payload == other.payload
  [Previous line repeated 238 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object
gpotter2 commented 6 years ago

I hope it didn’t cause you any trouble :/ I still have no idea why this happened. Will investigate

calebmadrigal commented 6 years ago

It didn't cause any trouble - it was an entertaining DEF CON moment though :)

p-l- commented 6 years ago

Can you share a capture of the packet?

calebmadrigal commented 6 years ago

@p-l- Sorry, I didn't get one.

guedou commented 6 years ago

Could not reproduce it either with the following code. Please reopen if you can find something that can help us reproduce the issue.

$ cat test_len.py 
from scapy.all import *

N = 1000
a = Ether()
for i in xrange(N):
    a /= Ether()
    len(a)
    len(Ether(raw(a)))
    if i % 50 == 0:
        print i
william-stearns commented 4 years ago

I'm able to reproduce this with scapy 2.4.3 on Fedora Linux. I have a pcap file containing ipv4 tcp port 53 packets that when run through passer ( https://github.com/activecm/passer/ ) gives the following:

Traceback (most recent call last): File "/home/wstearns/med/programming/passer/passer.py", line 2428, in sniff(store=0, offline=work_filename, filter=cl_args['bpf'], prn=lambda x: processpacket(x)) File "/usr/lib/python3.5/site-packages/scapy/sendrecv.py", line 972, in sniff sniffer._run(*args, kwargs) File "/usr/lib/python3.5/site-packages/scapy/sendrecv.py", line 925, in _run session.on_packet_received(p) File "/usr/lib/python3.5/site-packages/scapy/sessions.py", line 47, in on_packet_received result = self.prn(pkt) File "/home/wstearns/med/programming/passer/passer.py", line 2428, in sniff(store=0, offline=work_filename, filter=cl_args['bpf'], prn=lambda x: processpacket(x)) File "/home/wstearns/med/programming/passer/passer.py", line 1714, in processpacket if p.getlayer(Raw): File "/usr/lib/python3.5/site-packages/scapy/packet.py", line 1148, in getlayer _subclass=_subclass, flt) File "/usr/lib/python3.5/site-packages/scapy/packet.py", line 1148, in getlayer _subclass=_subclass, flt) File "/usr/lib/python3.5/site-packages/scapy/packet.py", line 1148, in getlayer _subclass=_subclass, flt) ... File "/usr/lib/python3.5/site-packages/scapy/packet.py", line 1148, in getlayer _subclass=_subclass, flt) File "/usr/lib/python3.5/site-packages/scapy/packet.py", line 1148, in getlayer _subclass=_subclass, flt) File "/usr/lib/python3.5/site-packages/scapy/packet.py", line 1115, in getlayer if isinstance(cls, int): RecursionError: maximum recursion depth exceeded while calling a Python object

Command line used: passer.py -r scapy243.recursion_issue.notudp.port53.notip6.pcap >/dev/null

For reference:

scapy243.recursion_issue.notudp.port53.notip6.pcap.zip