I want to add some rules or download some ready rules to detect DNS label Decoding DoS (Cross Reference at DNS decompression) can anyone know how can I do this?
I want to add some rules or download some ready rules to detect DNS label Decoding DoS (Cross Reference at DNS decompression) can anyone know how can I do this?
I am not aware of any known DoS attacks against the label decoding/compression trick that DNS uses (references perhaps?). That said, you can design a rule to detect the presence of a compression pointer using
byte_test
as such:byte_test:2,&,0xc000,0;
. This uses a bitwise AND to mask out all but the two highest bits and see if they are both '11', which is the marker for a compression pointer (the remaining 14 bits specify the offset from the start of the payload to the referenced DNS label). If that byte_test returns true, you've detected such a pointer, and you can then build the rest of the rule around that. It's up to you to walk the DNS packet until you arrive at the place where you expect such a pointer to exist.Have a look over the DNS protocol for any further oddities of this clever trick.
Edit:
Thinking about it, I think it's really only possible with the second byte of the packet. Unfortunately, Snort resets the
doe_ptr
to the start of the payload with each new rule option unless you specify arelative
to any of thebyte_*
options (I think). I do not believe that one byte option can be relative to a previous byte option, only to content matches.So, given that 99% of your DNS packets will never use the remaining 6 bits of the second high byte, you can start by looking for the hex value
0xc0
, which in binary is11000000
. This can replace the firstbyte_test
.In order:
content:"|c0|";
- Find a compression pointer.byte_extract:1,0,dns_comp_ptr,relative,little;
- grab the next byte and store it to the variabledns_comp_ptr
(untested! My offset may be incorrect -- might need to add +1).byte_test:1,=,dns_cmp_ptr,dns_comp_ptr,little;
- test one byte and see if it is equal to the value stored indns_comp_ptr
, after jumping the value indicated bydns_comp_ptr
, in little-endian format (which is how we see it as displayed in Wireshark).If the last
byte_test
returns true, then the rest of the rule will validate and alert. All in theory, of course. Totally untested and I offer no guarantees that it will work. But it encompasses the basic idea of needing to check every compression pointer in a DNS response (with a response on a Google domain, expect several of these) to see if that pointer points back to itself by following it at least once.The only way, that I can think of anyways, to test both bytes, is you would need a way to jump the
doe_ptr
to the byte immediately prior to the compression pointer, i.e., via a content. Snort doesn't have a rule option that directly says to move thedoe_ptr
by a specified value all by itself (though that really would be a cool idea, TBH).Once you have the
doe_ptr
placed properly, you usebyte_test:2,&,0xc000,1,relative,little;
to mask out all bits except the first two and see if they match the hex0xc000
. Then you dobyte_extract:2,0,dns_comp_ptr,little,bitwiseand 0x3fff;
thenbyte_test:2,=,dns_comp_ptr,dns_comp_ptr,little;
. Again untested, so my offsets are probably wrong. I forget how Snort twiddles with the byte placement precisely.Also, that
bitwiseand 0x3fff
thingy is my own creation.byte_extract
currently has no way to do bitmasking (which is a bitwise AND operation) to only extract out a few bits in a byte. I made the operand up.PS, I have no packets available to actually test this. Maybe I can hack one together at some point and try it out.