Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't disagree overall that a competent team really could get this right in the same time it'd take to make it work how you wanted with BIND, but although DNS is simple there are some corner cases where an incorrect solution will appear to work in trivial scenarios - "It worked in my Chrome" but may have either functional problems or security problems.

For example the 0x20 trick. The specification for DNS is clear that you aren't supposed to care about bit 0x20 in labels. ClOWnS and cLowNs and clowns and CLOWNS are all the same label as far as DNS is concerned.

However your answers need to bit-for-bit match the question you were asked. So if you answer "ClOWns A?" with "CLOWNS A 10.20.30.40" that's a mistake, you were asked about "ClOWns" not "CLOWNS". In 1995 if your DNS server got this wrong nothing of consequence breaks. But in 2021 if you get this wrong some important things magically don't work.

The transaction IDs that should make forging DNS answers hard are very short, and so to beef that up slightly some stacks will hide more bits in the 0x20 bit of labels where they will be echo'd back by a compliant implementation. But to reap this reward they must ignore answers that get the 0x20 bits wrong, like yours.

I feel like if "You can't get this wrong" (a stronger claim that you admittedly didn't make) was true, my visits to the Let's Encrypt community site wouldn't all begin by ignoring the people whose problem is obviously just that their DNS server doesn't work properly. Some of them have problems an authority server doesn't care about, but lots of them have dumb problems you'd imagine are impossible and yet apparently people have successfully sold commercial DNS servers with those problems.



Your comment suggests that the answer records in a DNS response need to be bit-for-bit identical to the original query. But the Vixie 0x20 draft says only that the question section in the response needs to be identical for this trick to work --- which is the ordinary way you'd implement an authority server (answers might come from a database or whatnot, but in both miekg/dns and the Rust NLNet library, the natural way to formulate a response simply copies the original query record).

At any rate: the possibility of breaking a 0x20-enforcing resolver scares me a lot less than depending on BIND, whose last memory corruption vulnerability was announced (checks notes) yesterday.


How is BIND still so bad 20 years after everyone already knew it was so bad :(.


You should rewrite it in rust


Bit by bit, that's what everyone is doing.


For anyone curious about 0x20:

* https://tools.ietf.org/html/draft-vixie-dnsext-dns0x20

I'm not surprised that Vixie is involved. :)


The simple solution to this is to return the same binary query as was received from the request.

It’s easy to screw up, definitely agree, but fairly clear how to fix when it’s pointed out. (I made that mistake)


If you don't mind, what things would magically break if the case of the answer does not match? Comparisons should be case-insensitive anyway.

Also, since DNS labels are strictly ASCII (this is why punycode exists), why converting all of them to the canonical upper case won't be a good idea?


There's a lot of daft DNS code out there that makes strange assumptions. My favorite example isn't quite relevant here but I'll mention it anyway because I think it paints the picture well: PowerDNS purportedly added compression support in its responses because a common stub resolver required answer owner names to be a compression pointer to the question.

EDIT: Found a reference:

"Turns out some customers were using a CPE router that thought ‘C0 0C’ was some kind of ‘answer starts here’ marker. And if it did not find that marker, its DNS component would crash. And at that time, PowerDNS did not compress that first response record, so there was no ‘C0 0C’."

-- https://berthub.eu/articles/posts/history-of-powerdns-2003-2...


The random mixed-case patterns are used to reduce the probability that someone evil could send spoofed DNS replies to your queries and have your DNS resolver trust those fake replies.


But if an adversary can send a spoofed reply with the desired domain name at all, I expect that the adversary could read the original request packet, too?


They're racing. The adversary needs to have their spoofed reply arrive first so you'll accept it as genuine. They will most often seek to arrange to reply to a query they guess you've asked, such that their answer arrives after it's asked but before you receive the honest answer.

This is why that transaction ID matters, the honest answer will copy the transaction ID verbatim from your question in the answer, so you get to pick it at random (back when I was a child it might just be a sequential counter) and your adversary has to guess it. But, alas the ID isn't very wide, so they really do have a good chance to just guess it. Hence, let's hide more random bits elsewhere in our queries to get a better chance of foiling the adversary.

How does an adversary guess what you're asking? Well, for one thing they might have chosen the question you're about to ask. When a bad guy's web site has an image at the top with <IMG SRC="http://real.website.example/header.jpg"> doesn't your web browser try to look up real.website.example to go get the image? Very predictable.


No, you can do it blindly. For example, if you have a web page that has an <img> tag pointing to a specific domain, then you can assume the client will perform a DNS lookup, so you can send fake replies blindly, hoping it will match a lookup request that you don't see.

Adding mixed case matching makes it more difficult to make a lucky guess when sending a fake reply blindly.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: