tintinweb / scapy-ssl_tls

SSL/TLS layers for scapy the interactive packet manipulation tool
GNU General Public License v2.0
419 stars 156 forks source link

AttributeError: 'TypedPacketListField' object has no attribute 'type_' #128

Open HarunGlec opened 6 years ago

HarunGlec commented 6 years ago

I am getting error while I was trying to import scapy_ssl_tls.ssl_tls. What is the problem? Who can help me?

>>> from scapy_ssl_tls.ssl_tls import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/scapy_ssl_tls/ssl_tls.py", line 691, in <module>
    class TLSHelloRetryRequest(Packet):
  File "/usr/local/lib/python2.7/dist-packages/scapy_ssl_tls/ssl_tls.py", line 695, in TLSHelloRetryRequest
    TypedPacketListField("extensions", None, TLSExtension, length_from=lambda x:x.length, type_="TLSHelloRetryRequest")]
  File "/usr/local/lib/python2.7/dist-packages/scapy_ssl_tls/ssl_tls.py", line 228, in __init__
    self.type_ = type_
AttributeError: 'TypedPacketListField' object has no attribute 'type_'
tintinweb commented 6 years ago

Hi @HarunGlec,

this is a dup #127. Can you provide information on how to reproduce this? I wasn't able to do so in #127.

regards, Martin

HarunGlec commented 6 years ago

I just opened interactive python shell and try to import like this "from scapy_ssl_tls.ssl_tls import * " that is only what i did.

yuzvir commented 6 years ago

I think it happens because there is no 'type_' in TypedPacketListField.__slots__ it can be fixed like this.

class BLenField(LenField):
    __slots__ = LenField.__slots__ + [
        'adjust_i2m', 'adjust_m2i', 'numbytes',
        'length_of', 'count_of'
    ]
class BEnumField(EnumField):
    __slots__ = EnumField.__slots__ + ['numbytes']
class StackedLenPacket(Packet):
    __slots__ = Packet.__slots__ + ['tls_ctx']
class TypedPacketListField(PacketListField):
    __slots__ = PacketListField.__slots__ + ['type_']
class TLSRecord(StackedLenPacket):
    __slots__ = StackedLenPacket.__slots__ + ['fragments']
class TLSExtension(PacketLengthFieldPayload):
    __slots__ = PacketLengthFieldPayload.__slots__ + ['type_']
class TLSKeyExchange(Packet):
    __slots__ = Packet.__slots__ + ['tls_ctx']
class TLSDecryptablePacket(PacketLengthFieldPayload):
    __slots__ = PacketLengthFieldPayload.__slots__ + ['tls_ctx']
class TLSHandshake(PacketLengthFieldPayload):
    __slots__ = PacketLengthFieldPayload.__slots__ + ['tls_ctx']
class SSL(Packet):
    __slots__ = Packet.__slots__ + [
        'tls_ctx', '_origin', 'guessed_next_layer', '__dict__'
    ]

But this is not the only issue I faced with when I tried to make it work with the latest version of scapy . The other thing is x509.X509Cert was renamed to x509.X509_Cert and there is no more x509.X509v3Ext. I suppose that x509.X509_Extension can be used instead of it. After all fixes, i'm still not sure that it works properly.

simon-schneider commented 6 years ago

Steps to reproduce: Install manually from branch py3compat e0f3be072311aaa1ae06d6d355b160c99dc4a32f. Open scapy.

I use Python 3.5.2, IPython 6.4.0, scapy 2.4.0.

Applying the mentioned changes (slots.diff.txt) seems indeed to be a fix.

tintinweb commented 6 years ago

Hi,

There's an open issue #117 ( we currently do not support scapy >=2.3.3 due to api changes since we wanted to avoid constantly fixing incompatibilities). But since acc. to a comment in #117 the api should be stable now I could have a 2nd look. The py3compat branch is still experimental.

Haven't worked with slots before but is slots of a subclass supposed to include all slots of the parent? see usage of slots on SO

Happy to merge the changes if this fixes problems.

cheers, tin

sand7000 commented 3 years ago

Applying the changes in the above diff file worked for me but I am having am still having an issue sending a DTLSRecord:

server_address = (dest_ip, dest_port)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
p = DTLSRecord(length=self.record_len) / self.d1_hs / self.d1_ch
sock.sendto(str(p),server_address)

This worked fine in python 2.7 but in 3.7 i get the error:

TypeError: a bytes-like object is required, not 'str'

I tried altering it to:

sock.sendto(str(p).encode('utf-8'),server_address)

which does get me past the error but the resulting packet that gets sent is not recognized by wireshark as a DTLS Hello like it was in python 2.7 so that is apparently not working like I hoped.

Any suggestions? Thanks!

sand7000 commented 3 years ago

It looks like the issue is not with the encoding. There is a length field that is incorrect in the DTLS portion of the packet so somewhere a calculation went haywire. I haven't dug into where that is yet.