Reputation: 54821
I'm trying to use Python to parse hex-formated DNS RDATA-values (should be RFC1035-compliant) that's generated in audit logs from Windows DNS Server when a record is created or deleted. I've tried a couple of Python dns-modules and think I'm getting close with dnslib, however all the documentation I find is for parsing a complete DNS-packet captured from the network including question and answer header ++.
The audit log only provides the class type and the RDATA it stores in AD (Active Directory-integrated zone), so I figured I might be able to use the parse(buffer,length)
method of the individual record type-classes to parse it, but so far all my attempts are failing.
Sample data:
Type = MX
RDATA = 0A0011737276312E636F6E746F736F2E636F6D2E
Which should be parsed to:
preference = 10
mx = srv1.contoso.com.
Latest attempt:
import dnslib
import binascii
mxrdata = binascii.unhexlify(b'0A0011737276312E636F6E746F736F2E636F6D2E')
b = dnslib.DNSBuffer(mxrdata)
mx = dnslib.MX.parse(b,len(b))
this fails with:
Traceback (most recent call last):
File "C:\Python37-32\lib\site-packages\dnslib\dns.py", line 1250, in parse
mx = buffer.decode_name()
File "C:\Python37-32\lib\site-packages\dnslib\label.py", line 235, in decode_name
(length,) = self.unpack("!B")
File "C:\Python37-32\lib\site-packages\dnslib\buffer.py", line 103, in unpack
data = self.get(struct.calcsize(fmt))
File "C:\Python37-32\lib\site-packages\dnslib\buffer.py", line 64, in get
(self.offset,self.remaining(),length))
dnslib.buffer.BufferError: Not enough bytes [offset=20,remaining=0,requested=1]
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python37-32\lib\site-packages\dnslib\dns.py", line 1254, in parse
(buffer.offset,e))
dnslib.dns.DNSError: Error unpacking MX [offset=20]: Not enough bytes [offset=20,remaining=0,requested=1]
Can anyone help me? Is it even possible using this module?
Upvotes: 3
Views: 2213
Reputation: 18410
You are encoding the RDATA wrongly a bit:
First, you specify the preference:
0A00
However, this is not 10 (because integer are encoded MSB first, not LSB first), but 2560. So this should be
000A
Then, you try to encode the hostname here:
11737276312E636F6E746F736F2E636F6D2E
0x11
should be the length byte and the rest is the domain name srv1.contoso.com.
. But this is not how encoding a hostname works. You have to encode each label separately with a length byte and terminate the hostname with a 0-length label. So this should be:
04 73727631 07 636F6E746F736F 03 636F6D 00
s r v 1 . c o n t o s o . c o m .
This adds up to:
mxrdata = binascii.unhexlify(b'000A047372763107636F6E746F736F03636F6D00')
Them the parser should succeed. So if you really get the RDATA in such an invalid format, you have to convert it first in to make it rfc1035-compliant.
Upvotes: 2