Đọc gói DNS trong python
Câu hỏi này đã được hỏi trước đây nhưng câu hỏi này chưa bao giờ được giải đáp đầy đủ và là từ năm 2013. Tôi đang sử dụng ổ cắm python để quan sát các gói DNS, chúng xuất hiện như vậy:
b'\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x10googletagmanager\x03com\x00\x00\x01\x00\x01'
Khi nghiên cứu các nguyên tắc cơ bản của gói DNS, tôi thấy chúng được cấu trúc như vậy:
QR | OpCode | AA | TC | RD | RA | Z | QUẢNG CÁO | CD | RCODE
Sau đó, tôi đã giải mã gói tin thành ASCII:
>> str = b'\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03www\x10googletagmanager\x03com\x00\x00\x01\x00\x01'
>> print(str.decode("ascii"))
wwwgoogletagmanagercom
Điều này chỉ trả về một chuỗi duy nhất với tên của địa chỉ chứ không phải thông tin khác như được chỉ định ở trên. Phần còn lại của dữ liệu, như QR và OpCode ở đâu? Tôi giải mã nó không chính xác?
Nói rõ hơn, tôi không muốn sử dụng thư viện bên ngoài và mục đích của tôi là hiểu cách cấu trúc các gói DNS và cách giải mã chúng; Tôi biết các thư viện như dnslibvà scapy.
Trả lời
Tôi không phải là chuyên gia về ổ cắm. Từ tham chiếu - Tiêu đề DNS được tạo thành từ các bit không phải byte ... vì vậy bạn cần phải phân tích cú pháp nó thành các bit. Sử dụng byte và bit mặt nạ. Xem mẫu bên dưới. Không chắc nội dung của header hdr [12:] là gì?
Đây là một số mã mẫu dựa trên thông số kỹ thuật ở trên:
def DNStoDict(hdr):
'''
Parse QNAME by using length (byte) +data sequence -- final length=0 signifies end of QNAME
Refer to https://stackoverflow.com/questions/34841206/why-is-the-content-of-qname-field-not-the-original-domain-in-a-dns-message
1) DNS knows nothing of URLs. DNS is older than the concept of a URL.
2) Because that's how DNS's wire format works. What you see is the
domain name www.mydomain.com, encoded in the DNS binary format.
Length+data is a very common way of storing strings in general.
'''
# Build DNS dictionary of values... include QNAME
l = len(hdr)
argSize = hdr[10]*256+hdr[11]
dnsDict = dict(ID = hdr[0]*256+hdr[1],
QR = bool(hdr[2] & int('10000000', 2)),
Opcode = (hdr[2] & int('01111000', 2))>>3,
AA = bool(hdr[2] & int('00000100', 2)),
TC = bool(hdr[2] & int('00000010', 2)),
RD = bool(hdr[2] & int('00000001', 2)),
RA = bool(hdr[3] & int('10000000', 2)),
Z = bool(hdr[3] & int('01000000', 2)),
AD = bool(hdr[3] & int('00100000', 2)),
CD = bool(hdr[3] & int('00010000', 2)),
RCode = bool(hdr[3] & int('00001111', 2)),
QDCOUNT = hdr[4]*256+hdr[5],
ANCOUNT = hdr[6]*256+hdr[7],
NSCOUNT = hdr[8]*256+hdr[9],
ARCOUNT = argSize,
QTYPE = hdr[l-4]*256+hdr[l-3],
QCLASS = hdr[l-2]*256+hdr[l-2])
# Parse QNAME
n = 12
mx = len(hdr)
qname = ''
while n < mx:
try:
qname += hdr[n:n+argSize].decode() + '.'
n += argSize
argSize = int(hdr[n])
n += 1
if argSize == 0 :
break
except Exception as err:
print("Parse Error", err, n, qname)
break
dnsDict['QNAME'] = qname[:-1]
return dnsDict
# Sample DNS Packet Data
hdr = b'\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03www\x10googletagmanager\x03com\x00\x00\x01\x00\x01'
# Parse out the QNAME
dnsDict = DNStoDict(hdr)
print("\n DNS PACKET dictionary")
print(dnsDict)
ĐẦU RA:
Từ điển DNS PACKET {'ID': 257, 'QR': False, 'Opcode': 0, 'AA': False, 'TC': False, 'RD': False, 'RA': False, 'Z': False, 'AD': False, 'CD': False, 'RCode': False, 'QDCOUNT': 0, 'ANCOUNT': 0, 'NSCOUNT': 0, 'ARCOUNT': 3, 'QTYPE': 1, 'QCLASS': 0, 'QNAME': 'www.googletagmanager.com'}
Thao tác Pyhon Bit
Tham khảo
- https://wiki.python.org/moin/BitManipulation
- http://www.java2s.com/Tutorials/Python/Data_Types/How_to_create_integer_in_Python_octal_binary_hexadecimal_and_long_integer.htm
Một byte ( b'xxxx') đại diện cho 4 byte. Mỗi byte được tạo thành từ 8 bit
0000 0000 - 0 0000 0001 - 1 0000 0010 - 2 0000 0100 - 4 0000 1000 - 8 0001 0000 - 16 0010 0000 - 32 0100 0000 - 64 1000 0000 - 128 1111 1111 - 255 (128 + 64 + 32 + 16 + 8 + 4 + 2 + 1)
Trong python, định dạng int ('00000111', 2) được chuyển đổi một mảng chuỗi ['0' / '1'] bằng cách sử dụng modulo 2 (bit). Điều này trả về giá trị 7 modulo 10.
Tiêu đề DNS tham chiếu: https://www2.cs.duke.edu/courses/fall16/compsci356/DNS/DNS-primer.pdf http://www.networksorcery.com/enp/protocol/dns.htm