Skip to content

Commit a4f958b

Browse files
authored
Fix bug if DNS compression gives an offset of exactly 46 (secdev#4688)
* Remove orb() usage * Fix bug if DNS pointer was exactly 46
1 parent 494e472 commit a4f958b

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

scapy/layers/dns.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from scapy.ansmachine import AnsweringMachine
3030
from scapy.base_classes import Net, ScopedIP
3131
from scapy.config import conf
32-
from scapy.compat import orb, raw, chb, bytes_encode, plain_str
32+
from scapy.compat import raw, chb, bytes_encode, plain_str
3333
from scapy.error import log_runtime, warning, Scapy_Exception
3434
from scapy.packet import Packet, bind_layers, Raw
3535
from scapy.fields import (
@@ -199,9 +199,12 @@ def dns_get_str(s, full=None, _ignore_compression=False):
199199

200200

201201
def _is_ptr(x):
202-
return b"." not in x and (
203-
(x and orb(x[-1]) == 0) or
204-
(len(x) >= 2 and (orb(x[-2]) & 0xc0) == 0xc0)
202+
"""
203+
Heuristic to guess if bytes are an encoded DNS pointer.
204+
"""
205+
return (
206+
(x and x[-1] == 0) or
207+
(len(x) >= 2 and (x[-2] & 0xc0) == 0xc0)
205208
)
206209

207210

@@ -396,7 +399,7 @@ def m2i(self, pkt, s):
396399
# RDATA contains a list of strings, each are prepended with
397400
# a byte containing the size of the following string.
398401
while tmp_s:
399-
tmp_len = orb(tmp_s[0]) + 1
402+
tmp_len = tmp_s[0] + 1
400403
if tmp_len > len(tmp_s):
401404
log_runtime.info(
402405
"DNS RR TXT prematured end of character-string "
@@ -559,7 +562,7 @@ def _pack_subnet(self, subnet):
559562
# type: (bytes) -> bytes
560563
packed_subnet = inet_pton(self.af_familly, plain_str(subnet))
561564
for i in list(range(operator.floordiv(self.af_length, 8)))[::-1]:
562-
if orb(packed_subnet[i]) != 0:
565+
if packed_subnet[i] != 0:
563566
i += 1
564567
break
565568
return packed_subnet[:i]
@@ -699,9 +702,9 @@ def bitmap2RRlist(bitmap):
699702
log_runtime.info("bitmap too short (%i)", len(bitmap))
700703
return
701704

702-
window_block = orb(bitmap[0]) # window number
705+
window_block = bitmap[0] # window number
703706
offset = 256 * window_block # offset of the Resource Record
704-
bitmap_len = orb(bitmap[1]) # length of the bitmap in bytes
707+
bitmap_len = bitmap[1] # length of the bitmap in bytes
705708

706709
if bitmap_len <= 0 or bitmap_len > 32:
707710
log_runtime.info("bitmap length is no valid (%i)", bitmap_len)
@@ -713,7 +716,7 @@ def bitmap2RRlist(bitmap):
713716
for b in range(len(tmp_bitmap)):
714717
v = 128
715718
for i in range(8):
716-
if orb(tmp_bitmap[b]) & v:
719+
if tmp_bitmap[b] & v:
717720
# each of the RR is encoded as a bit
718721
RRlist += [offset + b * 8 + i]
719722
v = v >> 1

test/scapy/layers/dns.uts

+9-1
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,15 @@ data = b'\xac\x81\x81\x80\x00\x01\x00\x06\x00\r\x00\x00\x04mqtt\x0bweatherflow\x
440440

441441
p = DNS(data)
442442
cmp = p.compress()
443-
assert len(cmp) == len(data)
443+
assert bytes(cmp) == data
444+
445+
= DNS - dns_compress with pointer b'\xc0.'
446+
447+
data = b'\x00\x02\x81\x00\x00\x01\x00\x03\x00\x00\x00\x00\x05forms\x06office\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x05\x00\x01\x00\x00\x01\x1b\x00&\x05forms\x06office\x03com\x06b-0039\x08b-msedge\x03net\x00\xc0.\x00\x05\x00\x01\x00\x00\x00\xdf\x00\x02\xc0?\xc0?\x00\x01\x00\x01\x00\x00\x00\xdf\x00\x04\rk\x06\xc2'
448+
449+
p = DNS(data)
450+
cmp = p.compress()
451+
assert bytes(cmp) == data
444452

445453
= DNS - dns_encode edge cases
446454

0 commit comments

Comments
 (0)