kapetan / dns

A DNS library written in C#
MIT License
415 stars 126 forks source link

Mishandled pointer in CNAME records #73

Open XorZy opened 4 years ago

XorZy commented 4 years ago

Thank you for this very nice library!

While working with the library I discovered the following bug.

If you try parsing from a byte array a DNS response containing CNAME records with label pointers in the data section, the resulting array from Response.ToArray(), is invalid ( Got bad packet: bad label type with nslookup).

The problem resides from the fact ResourceRecordFactory.FromArray(byte[] message, int offset, out int endOffest) blindly copies the data section while parsing the input array, therefore keeping a pointer to an invalid location if you try converting the response back to an array.

A simple fix would be to change

case RecordType.CNAME:
                    return new CanonicalNameResourceRecord(record, message, dataOffset);

to

case RecordType.CNAME:
                    return new CanonicalNameResourceRecord(record.Name, Domain.FromArray(message, dataOffset), record.TimeToLive);

in ResourceRecordFactory.FromArray(byte[] message, int offset, out int endOffest) to get rid of the pointer.

Please find attached to this issue, two dump files.

originalResponse.txt contains the raw DNS Reponse from Cloudlfare's DNS. generatedResponse.txt contains the reponse generated from first parsing Cloudflare's response, then immediately converting back to an array

var originalResponse = Response.FromArray(payload);
var generatedResponse = originalResponse.ToArray();

As you can see in generatedResponse.txt at offset 0h171, instead of having the label ".net", there is the original pointer (C0 D5) as found in the compressed Response from Cloudlfare.

Hope this can help,

Thanks! generatedResponse.txt originalResponse.txt