scapy icon indicating copy to clipboard operation
scapy copied to clipboard

Avoid repeated update of some fields when fuzzing

Open fouzhe opened this issue 4 years ago • 4 comments

Just an improvement of fuzz.

fouzhe avatar Nov 25 '21 02:11 fouzhe

Could you provide some context that will help us understand the fix?

guedou avatar Nov 25 '21 07:11 guedou

Hi, @guedou Here is the code snippet of Fuzz https://github.com/secdev/scapy/blob/c17140a419e3e4496706faa1cb9753816a6c586b/scapy/packet.py#L2475-L2489 The new_default_fields in L2481 doesn't contain fields in multiple_type_fields: https://github.com/secdev/scapy/blob/c17140a419e3e4496706faa1cb9753816a6c586b/scapy/packet.py#L2466-L2468

Hence, we can clear new_default_fields after L2481, avoiding duplicate update of some fields in L2488.

fouzhe avatar Nov 27 '21 07:11 fouzhe

Thanks for your explanation! Could you share a small piece of code that will help us reproduce the issue?

guedou avatar Nov 27 '21 12:11 guedou

Hi, @guedou @gpotter2

Take the IFETlv packet in ife.py for example:

class IFETlv(Packet):
    """
    Parent Class interhit by all ForCES TLV strucutures
    """
    name = "IFETlv"

    fields_desc = [
        ShortEnumField("type", 0, IFE_META_TYPES),
        FieldLenField("length", None, length_of="value",
                      adjust=lambda pkt, x: x + 4),
        MultipleTypeField(
            [
                (PadField(ShortField("value", 0), 4, padwith=b'\x00'),
                 lambda pkt: pkt.type in IFE_TYPES_SHORT),
                (PadField(IntField("value", 0), 4, padwith=b'\x00'),
                 lambda pkt: pkt.type in IFE_TYPES_INT),
            ],
            PadField(IntField("value", 0), 4, padwith=b'\x00')
        ),
    ]

    def extract_padding(self, s):
        return "", s

Edit Fuzz to obtain some debug information:

diff --git a/scapy/packet.py b/scapy/packet.py
index aaa74b6c..c1bcc674 100644
--- a/scapy/packet.py
+++ b/scapy/packet.py
@@ -2479,6 +2479,7 @@ def fuzz(p,  # type: Packet
                 for key, val in six.iteritems(new_default_fields)
             }
             q.default_fields.update(new_default_fields)
+            print("First update:", new_default_fields)
             # add the random values of the MultipleTypeFields
             for name in multiple_type_fields:
                 fld = cast(MultipleTypeField, q.get_field(name))
@@ -2486,5 +2487,6 @@ def fuzz(p,  # type: Packet
                 if rnd is not None:
                     new_default_fields[name] = rnd
         q.default_fields.update(new_default_fields)
+        print("Second update:", new_default_fields)
         q = q.payload
     return p

Run the following code:

from scapy.all import fuzz
from scapy.contrib.ife import IFETlv
p = IFETlv()
fuzz(p)

The output is as follows:

First update: {'type': 56623}
Second update: {'type': 56623, 'value': 3728151828}

The update for 'type' field is duplicate.

fouzhe avatar Nov 28 '21 12:11 fouzhe