Repository: secdev/scapy

Issue:
Unhandled exception in asn1 BER decoding
#### Brief description

asn1/ber.py throws a TypeError instead of a BER_Decoding_Error or ASN1_Error

#### Environment

- Scapy version: 6d41839db39b2365bfeb84170df6e626d76c7e73
- Python version: 2.7.15rc1
- Operating System: Ubuntu 18.04.1 LTS


#### How to reproduce

SNMP('0\x81\xbc\x02\x01\x00\x04\x06public\xa4\x81\xae\x06\t+\x06\x01\x04\x01\x04\x01\x02\x15@\x04\x7f\x00\x00\x01\x02\x01\x00\x1f\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x01\x01\x00C\x02\x01U0\x0f0\r\x06\x08+\x06\x01\x02\x01\x02\x01\x00\x02\x01!')

(This is test case 00000341 from the trap-enc segment of the PROTOS SNMPv1 test suite https://www.ee.oulu.fi/roles/ouspg/PROTOS_Test-Suite_c06-snmpv1 ) There are other cases in that suite that trigger what appears to be the same bug.

#### Actual result
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "scapy/base_classes.py", line 252, in __call__
    i.__init__(*args, **kargs)
  File "scapy/packet.py", line 138, in __init__
    self.dissect(_pkt)
  File "scapy/packet.py", line 806, in dissect
    s = self.do_dissect(s)
  File "scapy/asn1packet.py", line 33, in do_dissect
    return self.ASN1_root.dissect(self, x)
  File "scapy/asn1fields.py", line 378, in dissect
    _, x = self.m2i(pkt, s)
  File "scapy/asn1fields.py", line 370, in m2i
    s = obj.dissect(pkt, s)
  File "scapy/asn1fields.py", line 138, in dissect
    v, s = self.m2i(pkt, s)
  File "scapy/asn1fields.py", line 549, in m2i
    return self.extract_packet(choice, s)
  File "scapy/asn1fields.py", line 122, in extract_packet
    c = cls(s)
  File "scapy/base_classes.py", line 252, in __call__
    i.__init__(*args, **kargs)
  File "scapy/packet.py", line 138, in __init__
    self.dissect(_pkt)
  File "scapy/packet.py", line 806, in dissect
    s = self.do_dissect(s)
  File "scapy/asn1packet.py", line 33, in do_dissect
    return self.ASN1_root.dissect(self, x)
  File "scapy/asn1fields.py", line 378, in dissect
    _, x = self.m2i(pkt, s)
  File "scapy/asn1fields.py", line 370, in m2i
    s = obj.dissect(pkt, s)
  File "scapy/asn1fields.py", line 138, in dissect
    v, s = self.m2i(pkt, s)
  File "scapy/asn1fields.py", line 101, in m2i
    return codec.dec(s, context=self.context)
  File "scapy/asn1/ber.py", line 266, in dec
    return cls.do_dec(s, context, safe)
  File "scapy/asn1/ber.py", line 319, in do_dec
    l, s, t = cls.check_type_check_len(s)
  File "scapy/asn1/ber.py", line 243, in check_type_check_len
    l, s3 = cls.check_type_get_len(s)
  File "scapy/asn1/ber.py", line 235, in check_type_get_len
    s2 = cls.check_type(s)
  File "scapy/asn1/ber.py", line 228, in check_type
    if cls.tag != tag:
TypeError: int.__cmp__(x,y) requires y to be a 'int', not a 'long'

#### Expected result

Domain specific exception

Unhandled exception in asn1 BER decoding
#### Brief description

asn1/ber.py throws a TypeError instead of a BER_Decoding_Error or ASN1_Error

#### Environment

- Scapy version: 6d41839db39b2365bfeb84170df6e626d76c7e73
- Python version: 2.7.15rc1
- Operating System: Ubuntu 18.04.1 LTS


#### How to reproduce

SNMP('0\x81\xbc\x02\x01\x00\x04\x06public\xa4\x81\xae\x06\t+\x06\x01\x04\x01\x04\x01\x02\x15@\x04\x7f\x00\x00\x01\x02\x01\x00\x1f\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x01\x01\x00C\x02\x01U0\x0f0\r\x06\x08+\x06\x01\x02\x01\x02\x01\x00\x02\x01!')

(This is test case 00000341 from the trap-enc segment of the PROTOS SNMPv1 test suite https://www.ee.oulu.fi/roles/ouspg/PROTOS_Test-Suite_c06-snmpv1 ) There are other cases in that suite that trigger what appears to be the same bug.

#### Actual result
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "scapy/base_classes.py", line 252, in __call__
    i.__init__(*args, **kargs)
  File "scapy/packet.py", line 138, in __init__
    self.dissect(_pkt)
  File "scapy/packet.py", line 806, in dissect
    s = self.do_dissect(s)
  File "scapy/asn1packet.py", line 33, in do_dissect
    return self.ASN1_root.dissect(self, x)
  File "scapy/asn1fields.py", line 378, in dissect
    _, x = self.m2i(pkt, s)
  File "scapy/asn1fields.py", line 370, in m2i
    s = obj.dissect(pkt, s)
  File "scapy/asn1fields.py", line 138, in dissect
    v, s = self.m2i(pkt, s)
  File "scapy/asn1fields.py", line 549, in m2i
    return self.extract_packet(choice, s)
  File "scapy/asn1fields.py", line 122, in extract_packet
    c = cls(s)
  File "scapy/base_classes.py", line 252, in __call__
    i.__init__(*args, **kargs)
  File "scapy/packet.py", line 138, in __init__
    self.dissect(_pkt)
  File "scapy/packet.py", line 806, in dissect
    s = self.do_dissect(s)
  File "scapy/asn1packet.py", line 33, in do_dissect
    return self.ASN1_root.dissect(self, x)
  File "scapy/asn1fields.py", line 378, in dissect
    _, x = self.m2i(pkt, s)
  File "scapy/asn1fields.py", line 370, in m2i
    s = obj.dissect(pkt, s)
  File "scapy/asn1fields.py", line 138, in dissect
    v, s = self.m2i(pkt, s)
  File "scapy/asn1fields.py", line 101, in m2i
    return codec.dec(s, context=self.context)
  File "scapy/asn1/ber.py", line 266, in dec
    return cls.do_dec(s, context, safe)
  File "scapy/asn1/ber.py", line 319, in do_dec
    l, s, t = cls.check_type_check_len(s)
  File "scapy/asn1/ber.py", line 243, in check_type_check_len
    l, s3 = cls.check_type_get_len(s)
  File "scapy/asn1/ber.py", line 235, in check_type_get_len
    s2 = cls.check_type(s)
  File "scapy/asn1/ber.py", line 228, in check_type
    if cls.tag != tag:
TypeError: int.__cmp__(x,y) requires y to be a 'int', not a 'long'

#### Expected result

Domain specific exception



Discussion:

Resolving patch:
diff --git a/scapy/asn1/ber.py b/scapy/asn1/ber.py
--- a/scapy/asn1/ber.py
+++ b/scapy/asn1/ber.py
@@ -225,7 +225,7 @@ def check_string(cls, s):
     def check_type(cls, s):
         cls.check_string(s)
         tag, remainder = BER_id_dec(s)
-        if cls.tag != tag:
+        if type(tag) is not int or cls.tag != tag:
             raise BER_BadTag_Decoding_Error("%s: Got tag [%i/%#x] while expecting %r" %  # noqa: E501
                                             (cls.__name__, tag, tag, cls.tag), remaining=s)  # noqa: E501
         return remainder


Test patch:
diff --git a/test/regression.uts b/test/regression.uts
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -10146,6 +10146,16 @@ r1 == b'@\x04\x08\x08\x08\x08'
 r2 = b.dec(r1)[0]
 r2.val == '8.8.8.8'
 
+a = b'\x1f\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x01\x01\x00C\x02\x01U0\x0f0\r\x06\x08+\x06\x01\x02\x01\x02\x01\x00\x02\x01!'
+ret = False
+try:
+    BERcodec_Object.check_type(a)
+except BER_BadTag_Decoding_Error:
+    ret = True
+else:
+    ret = False
+
+assert(ret)
 
 ############
 ############