diff --git a/mitmproxy/net/dns/domain_names.py b/mitmproxy/net/dns/domain_names.py index 97f14944c..520fb65e1 100644 --- a/mitmproxy/net/dns/domain_names.py +++ b/mitmproxy/net/dns/domain_names.py @@ -147,17 +147,23 @@ def decompress_from_record_data( decompress_size = 0 while data_offset < end_data - offset: if buffer[offset + data_offset] & _POINTER_INDICATOR == _POINTER_INDICATOR: - ( - rr_name, - rr_name_len, - ) = unpack_from_with_compression(buffer, offset + data_offset, cached_names) - data[ - data_offset + decompress_size : data_offset - + decompress_size - + rr_name_len - ] = pack(rr_name) - decompress_size += len(rr_name) - data_offset += rr_name_len - continue + try: + ( + rr_name, + rr_name_len, + ) = unpack_from_with_compression( + buffer, offset + data_offset, cached_names + ) + data[ + data_offset + decompress_size : data_offset + + decompress_size + + rr_name_len + ] = pack(rr_name) + decompress_size += len(rr_name) + data_offset += rr_name_len + continue + except struct.error: + # the byte isn't actually a domain name compression pointer but some other data type + pass data_offset += 1 return bytes(data) diff --git a/test/mitmproxy/net/dns/test_domain_names.py b/test/mitmproxy/net/dns/test_domain_names.py index a6d749f96..72467ed27 100644 --- a/test/mitmproxy/net/dns/test_domain_names.py +++ b/test/mitmproxy/net/dns/test_domain_names.py @@ -85,3 +85,17 @@ def test_decompress_from_record_data(): == b"\x03ns1\x06google\x03com\x00\tdns-admin\x06google\x03com\x00&~gw\x00\x00\x03\x84\x00\x00\x03\x84\x00" + b"\x00\x07\x08\x00\x00\x00<" ) + + +def test_record_data_contains_fake_pointer(): + # \xd2\a2 and \xc2\x00 seem like domain name compression pointers but are actually part of some other data type + buffer = ( + b"\xfc\xc7\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00\x06google\x03com\x00\x00\x06\x00\x01\xc0\x0c\x00\x06\x00" + + b"\x01\x00\x00\x008\x00&\x03ns1\xc0\x0c\tdns-admin\xc0\x0c&\xd2\xa2\xc2\x00\x00\x03\x84\x00\x00\x03\x84\x00" + + b"\x00\x07\x08\x00\x00\x00<" + ) + assert ( + domain_names.decompress_from_record_data(buffer, 40, 78, domain_names.cache()) + == b"\x03ns1\x06google\x03com\x00\tdns-admin\x06google\x03com\x00&\xd2\xa2\xc2\x00\x00\x03\x84\x00\x00\x03" + + b"\x84\x00\x00\x07\x08\x00\x00\x00<" + )