Archive for the ‘Bitching About Protocols’ Category
Eric Monti | February 22nd, 2008 | Filed Under: Bitching About Protocols, Industry Punditry
If you do any kind of info security work or FOSS integration with windows and other Microsoft products, go and bookmark this link now!
By this time, I imagine everybody has heard about Microsoft’s new “Interoperability Initiative” announcement yesterday and all the buzz surrounding it. Lots of nay-saying about the actual level of openness coming out of Redmond, which is to be expected as par for the course. But… have you actually READ any of the references they published???
Whether this is as complete as it could be is probably still debatable to an extent. As somebody who’s got some experience reversing Microsoft protocols, I have to say from skimming the site, it looks like the lions share of transparency the FOSS and security communities have been calling for for a long time now. Given some more time, even I will inevitably nitpick about the things that aren’t included or are “under-included” in this reference material. Off the bat, for example, there seems to be little if any information on SQL Server and similar tertiary MS technologies.
But this is definitely a huge step by Microsoft. I really hope they will keep all of this material up to date and keep it coming where there are gaps. Something tells me they probably will.
So… credit where credit’s due. Microsoft definitely gets kudos for this. The nay-sayers claiming “we’ve heard that one before” appear to be dead wrong this time. My natural instincts would normally be to join them, but the evidence is to the contrary. In the spirit of my fairly blatant and deep-seeded prejudices, I will still at least proclaim “It’s about freaking time, Redmond!”. Oh and while I’m being snide… that stuff about not suing some of us is real sweet to hear from Ballmer too…
Still, my gold kudo ultimately goes to the EU. The whole episode definitely affirms that our government representatives in the US never put any real teeth on our MS anti-trust struggle over the past decade and that they really should have a long time ago. As we’ve seen in the last number of years with MS’s increased security transparency initiatives, I think it will become even more apparent that increased transparency has never been contrary to corporate interests either.
Anyway politics aside… Deep down, while skimming the site, I’m feeling a little like Wiley Coyote in the ACME factory after closing time.
As soon as I got wind of the release, I made a bee-line right for this document — NTLMSSP/NTLMv2 token exchanges being a subject near and dear to me during several projects a few years back. I think this is an example of where the new references, accessibility, and toning down of the “suing” rhetoric may bear fruit.
Now that MS seems to have admitted that it is “legal” to do so (more sarcasm) we may for example see Firefox and other open browsers fully implement NTLMv2 authentication blobs to get along with IIS webserver authentication. On the flip side, people might start using NTLM under Apache to integreate with their Windows domains and/or directories (I seem to recall a 3rd party module or two out there that even does this already). NTLMSSP is goofy, sure. Don’t get me wrong. I still dislike NTLM, it’s just that I got pretty “close to it” for a while there. For all the troubled past and arguable nastiness, NTLMv2 challenge/response handshakes over HTTP are at least a better alternative to Basic Auth (at least somewhat comparable to Digest). Sure, there are some really gross flaws in the crypto, arguably some information leakage… but on the plus-side there are tons of IE browsers out there all ready to actually start using it if it actually becomes relevant by working elsewhere other than just IIS.
A little background: Even though for some time, this has been considered “conquered territory”— lots of FOSS implements it to varying degrees (as evidenced by the Wikipedia entry) — NTLMv2 and NTLMSSP are still and have long been Microsoft inventions that are not terribly well understood by “the rest of us”. This is mostly due to the lack of documentation out of Redmond. Before it was “deprecated” by Active Directory/Kerberos, Microsoft cobbled NTLM/NTLMv2 into all sorts of protocol implementations. Examples include CIFS (where it’s rooted), MS-SQL, POP3, IMAP, HTTP, SMTP, even Telnet for jebus’ sake! The list goes on. To many, it would be an understatement to say that Microsoft has historically leveraged NTLM to attain a degree of ill-gotten market dominance through incompatibility.
NTLMSSP is still relevant in the AD/Kerberos world for that matter. Probably in order to save themselves the hassle (irony), MS decided to leverage much of the basic NTLMSSP token structure and protocol semantics for when AD/Kerberos message exchanges came around. You’re still pretty likely to see NTLMSSP blobs in and out of Base64 packaging in many MS protocol implementations — regardless of whether you’re using Kerberos or still downwardly compatible.
In the past, incorporating or implmenting NTLMv2 (let alone “correctly” whatever that was) was a pretty big hassle. Just deciphering those NTLMSSP NegotiateFlags was cause of considerable grief. The worst part was wondering whether and which of the “unused” bits were “really unused”. Now, seeing all those bits laid out and documented in their entirety outside of a Samba or MS-SDK C header this way gets me a little dizzy. There was, I admit, a masochistic kind of pleasure in cobbling together and in some cases reversing the information from various sources back then — like discovering new frontiers or something. But yeesh… I think my rational side ultimately wins out on that kind of nostalgic waxing. Yea, enough of that crap! It’s time to move on.
So… in conclusion:
Keep it up MS and… <cough>… thank you!
I’m pretty sure MS wont regret this, either. I hope the old-guard holdouts out there (yes that includes YOU, Apple… Cisco…) pay very close attention over the weeks and months to come.
6 Comments
Thomas Ptacek | August 22nd, 2007 | Filed Under: Bitching About Protocols
Larry Seltzer, writing in his column:
Of course, as Aitchison says, even that third party is accessed
through domain names. If I’m spoofing DNS, what’s to stop me from
spoofing verisign.com and putting up my own fake certificate
authority?
Of course, what stops you from erecting your own CA is that you can’t
recover the prime factors of very large numbers (or pretend to), or if you can, you
have better things to do with your time than set up phishing
sites. Like winning a Fields medal.
In other words: your browser shipped with Verisign’s key. You never
trusted the (insecure) DNS to get it. Neither did you trust:
the (insecure) DHCP protocol, which told you your router’s
address, or
the (insecure) ARP protocol, which told you how to reach
that address, or
the (insecure) OSPF routing protocol, which told your ISP’s
network where to send the packets you handed your router, or
the (insecure) BGP interdomain routing protocol, which, but
for a carefully-crafted regex string, allowed any network in the
world to claim the destination address of those packets.
Because of any of these failed, you’d be in the same pickle, DNSSEC or
not.
… it’s like, I don’t even care if the DNS is secure.
8 Comments
Thomas Ptacek | August 21st, 2007 | Filed Under: Bitching About Protocols
.
I’m Ron Aitchison, and you’re wrong about about DNSSEC.
Thanks for sharing. But what makes you so sure?
.
Because I’m “the President of Zytrax”.
Do they have SSL in Zytrax?
.
You “have to get to the right place, the right IP address” for SSL to
work; insecure DNS undercuts SSL.
No, it doesn’t. SSL doesn’t depend on DNS for security. That would
have been lunacy: DNS is insecure. So instead, your browser shipped
with Verisign’s key. You can’t spoof a certificate because you
can’t break RSA.
.
But I can make my own certificates “in the real name of
respectedfinancialinstitution.com but sign it myself using a plausible
looking name”, and you’ll just ignore the error. After all, Google’s
SSL certs never work.
DNSSEC has exactly the same problem. Both DNSSEC and SSL provide the
same signal: “the authenticity of this server cannot be
verified”. Just because the signal comes from DNS, doesn’t make
it any easier for Firefox to render it.
Oh, what’s that you say? DNSSEC solves the problem? Oh, that’s right:
when DNSSEC signatures don’t validate, domain names don’t resolve! I
get it. The major advance that DNSSEC provides is removing the
“continue” button from the SSL certificate warning dialog in my
browser.
A modest proposal: can we just disable that button, and forget about
DNSSEC? I don’t know who’s going to explain it to the users,
though. One-two-three not it!
Oh, sorry. You meant, “I can get a legitimate, Verisign-signed
certificate with an authentic-sounding name, and fool users with the
name alone”. Allow me to retort: “goto DNSSEC has exactly the same
problem”.
.
It is “stunningly naive” to assume sites without SSL are
unimportant. I can plant stories in the New York Times! With “grainy,
on-the-spot, sense-of-realism” footage, and cause mass panic!
Wow. That is a cool story. Let me see if I can outdo you. I’m
cheating, though: compared to yours, my story is plausible.
First, construct a time machine, and send the Internet back 93 years.
A young Gavrilo Princip, enraged at Austro-Hungarian hegemony over
Serbia, is just about to let off some steam with a scathing DailyKos
post. But just as he pushes the “Submit” button, a DNSSEC RR signature
expires, and Gavrilo gets a “host not found” error. Enraged, he storms
from his house to a deli, where he comes upon Archduke Franz
Ferdinand and puts a bullet through his jugular, goading Austria to
issue a series of untenable demands to Serbia. Entangling alliances
and the DNSSEC-prompted delivery failures of conciliatory diplomatic
emails drag a whole continent into a bloody, pointless war of
attrition.
So you see, for me, no matter what the cost, avoiding DNSSEC is vital
to the future integrity of the Internet.
.
Yes, “One of the underlying principles of security is that more code =
more errors and security holes.” But no it isn’t. “Bugs are removed
and the world moves forward.”
It’s either “one of the underlying principles”, or it isn’t. Google:
“hand waving”.
.
In fact, DNSSEC will be “be relatively more bug-free” than SSL,
because DNSSEC servers can use OpenSSL’s libraries.
Now Google “asymptote”.
.
DNSSEC servers “would do a trivial amount more work”, and are only
“marginally more vulnerable to DoS attacks”.
Now Google “chargen Case Against DNSSEC”. Then hit control-F, search
for “let’s not even start talking about the guys who run COM”. I
didn’t make that up. I also didn’t make up the proposal to turn DNS
zones into Unix password files, or the proposal to construct fake
covering RR sets to foil zone transfers.
Shenanigans. Read the backlogs of
namedroppers, the deployment list, or the dnsops list. Performance is an issue.
.
When DNSSEC is “end-to-end”, which it must be, all the heavy lifting
will be done by end-user machines.
I propose a new drinking game: “imagine that you could wave a magic
wand and update the bare metal software of every mainstream
machine on the Internet, and then come up with something more valuable
to do with that power than DNSSEC. Whoever comes closest to the floor
value of DNSSEC, without going through it, wins.”
My entry: every host on the Internet gets a royalty-free copy of
Univers, in all its normal and oblique widths. Also we
eliminate Comic Sans. In fact, just get rid of Comic Sans. Still more valuable than
DNSSEC!
.
Yes, to make end-to-end DNSSEC work, “the current stub-resolvers
installed on most of the worlds computers would need to be
replaced”.
Why, that’s no harder than spontaneously converting the whole world to
IPv6!
.
“By the way, Verner was convinced”.
They have medication for that.
[PS]
When you deride the Google ops teams by saying they can’t keep their SSL certificates up-to-date, I’ll respectfully oblige you to cite sources, or again call “shenanigans!” on you.
6 Comments
Eric Monti | May 21st, 2007 | Filed Under: Bitching About Protocols, Reversing, Uncategorized
We just wrapped up a security assessment on a commercial enterprise server/agent security product. I can’t get too specific here, but we did run into an interesting problem that we thought would be worth a post.
The application we were evaluating had a home-grown network protocol doing some interesting things worth investigating. What we were seeing from our network capture wasn’t too far from this:
00 46414b45 02000000 06060601 5e000000 |FAKE............|
10 dab624ba da73fed5 b9872696 08ea97a5 |..$..s....&.....|
20 2d626160 60c86248 61c86748 65e000b2 |-ba``.bHa.gHe...|
30 bd80ac0c 863c0605 0617b098 3450cc99 |.....<......4P..|
40 c18a2186 21802191 a1042817 c3100294 |..!.!.!...(.....|
50 89610806 92b94015 310c6e0c 990c3940 |.a....@.1.n...9@|
60 961e4332 502c8f21 0dc84f67 0000 |..C2P,.!..Og..|
6e
Just by glancing at the first 16 bytes, you can spot (1) a message signature; (2) some 4-byte little-endian word values, one of which was obviously a length value for the payload; and (3) version number of 1.6.6.6 in the middle.
This looked promising so, we decided to pick it apart some more and see where it got us.
Let me just add at this point: General approaches can vary a lot when it comes to reverse engineering. As you’ll see, what we were doing was not strictly just protocol reversing. We had access to server-side binaries, which we were simultaneously disassembling to guide us at several steps. We could have just gone the strict disassembly route, but in my experience combining the two tends to yield much quicker results.
So, away we went. Or rather, got stuck next. Just past the header of the protocol was a chunk of seemingly meaningless binary data. A bit of disassembling told us that it was something compressed with .NET’s DeflateStream. Here was the real payload and it was time to write our first bit of code.
Since we were working with BlackBag (as regular readers will have noticed — Matasano tends to do) our ideal tools would be small focused ones that could run on Unix. Preferably in the middle of a list of several piped commands so we could say things like:
% cat | _inflate_ | hexdump -C
And if things got interesting, maybe even:
% cat | _inflate_ | bkb sub | _deflate_ | bkb blit
We figured, we should be able to get the “Inflated” stream using Zlib. So, we set out to put together some Ruby to take a “deflated” standard input and dump “inflated” standard output.
#!/usr/bin/env ruby
require 'zlib'
buf = STDIN.read()
zs = Zlib::Inflate.new
out = zs.inflate buf
STDOUT.write(out)
And… Fire!
% cat msg.raw |bkb shf 16 | inflate.rb|hd
./inflate.rb:7:in `inflate': incorrect header check (Zlib::DataError)
from ./inflate.rb:7
Woops… maybe not so simple. We asked the Google! Turned out .NET’s DeflateStream doesn’t use the usual ZLIB header and footer as defined in RFC 1950.
Side note: Obviously this had already been tackled. Even though we didn’t try the IronPython solution linked above, I’d probably recommend using it or something like it unless you need something really quick and dirty as we did. The obvious question, is why didn’t we? We were sticking with ruby for other reasons on this session and didn’t really need a “robust” solution just yet.
So we actually read RFC 1950 at this point. Turned out we just needed to tack on the header (and maybe the footer) ourselves.
#!/usr/bin/env ruby
require 'zlib'
header = "x78x01"
buf = STDIN.read()
zs = Zlib::Inflate.new
# Add the header first
zs << header
out = zs.inflate buf
STDOUT.write(out)
Um.. Fire?
$ cat msg.raw |bkb shf 16 |./inflate.rb |hd
00 b6a45b7b 499fd59d c2917411 2f7666a2 |..[{I.....t./vf.|
10 04000000 6a006400 6f006500 08000000 |....j.d.o.e.....|
20 4a006f00 68006e00 20004400 6f006500 |J.o.h.n. .D.o.e.|
30 1b000000 43003a00 5c005000 61007400 |....C.:..P.a.t.|
40 68005c00 54006f00 5c005300 6f006d00 |h..T.o..S.o.m.|
50 65005c00 46006900 6c006500 2e006300 |e..F.i.l.e...c.|
60 6f006e00 66006900 6700 |o.n.f.i.g.|
6a
Much better.
Those who’ve read the RFC or are already familiar with ZLib may notice we didn’t bother with the ADLER32 checksum footer. Our quick/dirty Ruby ZLib implementation didn’t seem to notice when it was missing. Honestly not sure whether this is expected behavior or not, but it suited us just fine. We really just wanted to get back to picking apart the protocol.
What was “inflated” might also need to get “deflated” again, so we also whipped up a “deflater”.
#!/usr/bin/env ruby
require 'zlib'
buf = STDIN.read()
zs = Zlib::Deflate.new()
out = zs.deflate(buf,Zlib::SYNC_FLUSH)
# Output the deflated chunk without the 2b zlib header and 4b adler32 footer
STDOUT.write(dst[2,(dst.length - 6)])
Turned out we didn’t need to use the “deflate” script much: between protocol decoding and disassembly, we learned one of the original uncompressed 4-bytes in the protocol’s header was for payload *type*, either *deflated* or *raw*. So, even though we confirmed our deflater worked well enough, we usually just changed the type to *raw* whenever we wanted to send something back to the server.
And in conclusion (which I have to speak in vague terms about to protect the guilty - sorry). Now that we could read and compose messages, we learned this protocol was letting the agent do some truly crazy things. Things like, passing entire lists of fields to insert/update directly into SQL. Without authentication.
Identifying and decompressing the protocol’s payload was the only hurdle we had to get over to proceed with other attacks. In the end, these culminated in several findings, including trivial database corruption and even injecting malicious data to capture admin privileges through the product’s console. Again… without authentication.
Moral of the story:
I try to not to speculate too much about what developers’ intentions are or were when I find something like this. Hindsight is 20/20 and it’s generally a lot easier to break than build. But, I couldn’t help but wonder whether they had intended to use DeflateStream as a cheap form of obfuscation here. It’s just as possible they just wanted to keep the payloads small and didn’t even consider the risks faced by the protocol at all.
Zlib is not encryption (I feel dumb even saying it). Even more so if your protocol is wide open. Authentication would have been tricky no matter what. There were inherent trust boundaries invading way into the agent. That was even more reason for this protocol to use encryption. Though frankly it wouldn’t have solved all this protocol’s problems — crypto is not an argent projectile. There were some deeper design issues lurking here.
But at the very least, it would have raised the bar for reversing. Because the ZLib “hurdle” took us all of about 20 minutes to beat.
24 Comments
Dave G. | May 1st, 2007 | Filed Under: Bitching About Protocols, Reversing
I was recently working on a Java-based application that communicated
exclusively over SSL. This is a good thing for the application, but
a bad thing for someone trying to test it. I naively thought that I
could edit a couple of files and boom, be on my way. Alas, what follows
is what I had to do to get in between and start understanding the application:
My initial take was that I would use two instances of stunnel (I use 3.x because I am old, crusty, and like the simplicity of the 3.x command line interface), with Blackbag’s replug in between so I can view the traffic.
So, here is my simple setup (monitoring a connection to www.amazon.com as an example):

All I do is test it with another instance of stunnel and we see that traffic
is passing through our rat’s nest of proxying.
Of course, the first wrinkle is that I need to actually test from Windows.
So we load up Parallels and get the application pointing at our
tunnels. Easiest way to do this is to just edit the hosts file, located
at \WINDOWS\System32\Drivers\etc. Looks just like /etc/hosts, so we just add:
192.168.2.2 alas.we.cant.share.this.com
Which should work as long as IP addresses aren’t hardcoded into the application. Thankfully, they weren’t. Now I just run the app, and everything works.
Except that it doesn’t work at all. Turns out that the JVM does certificate validation. When web browsers encounter certificate problems, they let the user decide if they want to continue to connect. When just about any other kind of application encounters validation problems, they will just fail.
There are two basic validation steps it will perform:
Valid Certificate: Is this signed by someone that we trust (e.g. Verisign)?
Hostname: Does the hostname inside of the certificate match the hostname we are trying to connect?
This is where I feel like I must have missed something. I can’t find anywhere inside of the Java documentation where I can disable this using JVM configuration files. After poking around for a bit, and using google, I see two options.
- Install a new certificate into the instance of Java I am using
- Decompile, edit and recompile (you can turn off certificate validation programmatically)
So, I go with Option #1. I start by generating a new certificate using the stunnel Makefile (you can just use OpenSSL):

The most important parameter you are setting is the Common Name. It must match the server that our application thinks that it is going to communicate with.
Then I cheat and use InstallCert, a Java app written by Andreas Sterbenz who also beat his head against Java certificate validation issues. The neat thing about InstallCert is that you just give it a URL and it will grab the cert and create a keystore you can use. You just copy over your old cacerts file with the newly created one, and your cert will now be accepted for future use. We just point InstallCert at our stunnel instance:

You can safely ignore the SSLHandshake errors. You should really run InstallCert on the machine you intend to test from (in my case the Windows box), but it was faster for me to create screencaps in OS X. Then InstallCert will ask you to if you want to accept the cert:

InstallCert will create a file called jssecacerts in the current working directory. You will want to copy that file over the actual keystore usually located in JAVAPATH/lib/security/cacerts.
Note: Backup the cacerts file before overwriting it.
This is where someone comments, “but all you had to do was edit java.security to say XXX and you could have disabled certificate validation”, and where I wish there was a phrase that meant both Thank You and I Hate You. If it turns out that I am correct, then I have to ask: Why on Earth isn’t this a configuration file option?
15 Comments
Thomas Ptacek | April 4th, 2007 | Filed Under: Bitching About Protocols, Uncategorized
Back | Top | Next
1.
Alice wants a.victim.org’s IP. She asks the DNS.

So, a.victim.org is 1.2.3.4. Simple enough? Let’s add a wrinkle:

The question, “what is a.victim.org?”, and the answer, “1.2.3.4!”, are
records inside of DNS messages. The DNS —- the whole distributed
database, that is —- is made up entirely of these records. The
records are keyed by name, type, and class, and contain bundles of
data.
A subtlety, which we’ll be returning to —- Alice asks for z.victim.org:

z.victim.org doesn’t exist. Alice doesn’t get a record; she gets an
error packet. There’s a difference.
Moving on. Alice didn’t really ask the DNS anything:

Alice’s stub resolver asks her cache to find out about a.victim.com
from the victim.com authority servers. The stub is her Mac’s built-in
resolver library, which her browser is linked to. The cache is the
nameserver SpeakEasy, her ISP, gave her. The authority is “named”, AKA
BIND, running on ns.victim.com.
2.
Enough remedial DNS. Back to DNSSEC. Mallory can spoof responses to
Alice’s DNS queries. We want to stop her. We use cryptography:

Sign the records (RR’s in the jargon) with a signature based on an RSA
keypair. Stick the public key in the DNS where Alice’s cache can find
it. Her cache gets a public key attached to victim.com and an
“a.victim.com is 1.2.3.4” RR signed under that public key.
If you’re with me so far then, with one important exception, you’ve
got the “service model” for DNSSEC —- meaning, what DNSSEC is trying
to accomplish. Caches can look at records and tell if they’re
valid. Mallory can’t forge records without subverting the keys.
How do we manage and protect those keys? Good question. Let’s
introduce some notation:

We can generate and store RSA keypairs. We can fingerprint keys
(public keys) by taking a hash or MAC of them, just like SSH and PGP
do. And we can use private keys to generate signatures of blobs (or
hashes of blobs) of data.
With that in mind:

Ok, breathe.
Alice’s cache ships preconfigured to trust a root key, which basically
never changes. Exactly the same way Alice’s browser works with SSL to
use Verisign’s CA. Again, let’s call that a “trust anchor”; it’s a
secure starting point for DNSSEC queries.
A.VICTIM.ORG. is linked from the root, to ORG, to VICTIM.ORG,
containing A.VICTIM.ORG. ORG and VICTIM are delegations (because
different people run the roots, ORG, and VICTIM).
In DNSSEC, authentication follows delegations. Sometimes. More on that later.
The root vouches for a key in ORG using a fingerprint record (a
Delegation Signer, or DS). Root’s voucher for ORG is signed under
root’s key, so Mallory can’t change it: Alice knows the root’s key and
now ORG’s key.
Repeat until you get the record you want. This is an authentication
chain.
3.
And it’s fine, as far as it goes, though you’ve got to remember that
it took something like 13 years to get here.
I’m describing RFC4033 DNSSECbis (bis! Still don’t believe me about
the invasion of the OSI-snatchers?) from 2006. The original DNSSEC
proposals date back to the early 90’s, when government contractor
TIS Labs (Marcus Ranum’s old haunt) convinced the DOD to let them try to
secure the DNS.
The DNSSEC attempt preceding RFC4033 put signatures in the wrong
place, so that if the key for COM ever got compromised, tens of
millions of DNS records would have to be replaced.
That proposal lived, as “the DNSSEC standard” until the end of 2001.
You’re right. It’s a cheap shot to attack the standards process itself
for being unstable and untenable. Paul Vixie does a much better job:
dnssec is the worst design-by-committee effort i’ve ever seen, both
in terms of how late it is, how fuzzy the goals have been, how often
the goals have changed, and how complicated and heavy it is now that
it is trying to be all-things-to-all-people.
—- Paul Vixie, about 5 months ago.
(I’m not sure if I agree or disagree with Vixie —- allowing for how
unqualified I am to make judgements on the IETF —- but I’m pretty
sure that the answer of having him and Jim Reid raise $1.6MM to create
a members-only “Shadow IETF” that costs $10k to “vote” was a step in the
wrong direction).
But whatever. Back to the protocol, as it exists today. I’ve got
something cool to show you. Bear with me, this is going to seem
redundant.
4.
Insecure DNS. The host “a” exists, and “z” doesn’t:

Now, secure DNS. The host “a” exists, and “z” doesn’t:

Uh-oh. DNSSEC protects records. “The” DNS. It doesn’t protect DNS
packets. Those are just a means to an end. So without magic, we
can’t distinguish between a “real” error and a fake one!
That’s sort of a problem. And I sincerely mean “sort of”.
For one thing, Mallory can deny service to Alice and Bob by forging
errors. But so what? In a DNSSEC world, Mallory can deny service to
the entire Internet from a small botnet by saturating DNS servers with
expensive crypto operations.
On the other hand, being able to forge errors also allows Mallory to
change the semantic meaning of some DNS zones. The best example is MX,
the mail exchanger record: MX tells Sendmail and Exchange where to
send your mail. Without an MX, mail goes to your hostname. So Mallory
can send mail to the wrong host.
Reasonable people disagree about whether this is all a real problem,
but the “consensus” is that DNSSEC needs to solve it. So we get
authenticated denial (or “provable non-existence”, PNE,
DNSSEC). Check this out:

You take all the RR’s in your zone. You sort them —- which requires
its own standard because crypto needs canonicalization —- and them
link the names of the RR’s together with another kind of record called
an NXT —- errr, sorry, NSEC. An NSEC links two DNS names together,
basically asserting “no name comes between these two in the sort”.
Now, when you ask for a record that doesn’t exist, the DNS can inform
you of that reliably. You get an unexpectedly wrong NSEC record back
from the query. It says, “look, your record falls in between two names
linked by an NSEC, in a gap where no name can be”. And that record is
signed, “proving” the nonexistence of the name.
And that’s fine, because —- oh wait, you in the back there, you have
something to say?
Oh. Crap. You’re right. Bad guys can just walk the NSEC chain to
list all the names in your zone. Yeah, that’s pretty much exactly the
same thing as allowing zone transfers. I know you’ve had zone
transfers blocked since 1998 —- yeah? IETF mailing list guy in the
front row? With your hand raised? What’s that?
Well, OK, sure, maybe all DNS names should be public. But IETF guy,
the names in your zone read like this:
decmultia.greybeard.com
vax-in-my-basement.greybeard.com
sun-ipx.greybeard.com
symbolics.greybeard.com
slackware.greybeard.com
knights-that-say-nee.greybeard.com
And that guy in the back? His names go something like this:
money0.secretcustomer0.bigbank.com
money0.secretcustomer1.bigbank.com
vulnerable.managementsystem.bigbank.com
payrollsystem.bigbank.com
linux-box.boss-not-supposed-to-know-about.bigbank.com
And let’s not even start talking about the guys who run COM. The RR’s
in COM right now are just a couple of tiny NS’s. They keep the whole
database resident in memory. But DNSSECbis requires them to set up
NSEC records for them, too. And sort them. And, by the way, something
I haven’t really pointed out yet about DNSSEC RR’s —- know how I’ve
been acting like they look like this:

Well, actually, they look like this:

RSA signatures are kind of painful that way. The COM guys better find
bigger boxes.
The IETF has a solution for this problem, which Ben Laurie helped
write. It’s not a “standard” yet, and so not really part of
DNSSECbis. But it’s funny, and not hard to explain. It’s called NSEC3.
Here’s the idea: turn the NSEC chain into a Unix password file. Make
the names into salted crypt(3)-style hashes. You can prove an NSEC3
record matches what you were looking for or not, but you can’t turn
the NSEC chain back into the zone dump. At least not without crack(8).
I have misgivings about this idea. You can scale password files up
with compute using adaptive hashing, because people don’t log in to
their computers very often —- but people use the DNS all the time,
so you can’t make a lookup step take 5 seconds.
Fortunately, there’s another IETF solution to the problem. It’s
called “minimum coverage NSEC”, also known as “whitelies”, involves
the servers forging NSEC records to trick people trying to dump the
zone, seems to require on-demand signing of RR’s (a no-no —- your
privkeys are supposed to be in a vault in Tuscon), and nobody is ever
going to deploy any of this so let’s move on.
At this point I’m reminded of a classic from the Western canon:
Scientist
Mr. Simpson, we don’t play God here.
Homer
What? You do nothing BUT play God. And I think your Octoparrot would agree.
Octoparrot
Squawk! Polly shouldn’t be!
One more wrinkle. This looks like a total non-starter for the COM
guys. So they were demanding an extension, informally known as
“opt-in”, which lets them mark whole stretches of the COM RR space as
insecure so they don’t have to run their name servers on Beowulf
clusters just to let 10 guys mess with DNSSECbis.
But none of these things are in the “standard”. Which is “finished”
and we’re supposed to deploy. NSEC? NSEC3? Whitelies? Opt-In? Or can
we just do away with authenticated denial altogether and go with
“signing only” DNSSECbis?
5.
5.0.
Another issue. DNSSECbis protects RR’s, which are like the nuclei of
DNSSEC cells. But the cell walls are still fragile, and other things
besides normal DNS rely on them —- for instance, DNS dynamic update,
which is its own debacle. Want secure dynamic update? That’s a
different standard, either called TSIG (which secures DNS the same way
DESLogin secured Telnet), or SIG(0), which uses public keys. These are
different standards than DNSSEC.
5.1.
Another issue, which may have been obvious:

Alice’s stub resolver library is not going to support DNSSECbis any
time soon (note to my Apple and Microsoft readers who spend money to
audit their OS and runtime code: Alice’s stub resolver library is not
going to support DNSSECbis any time soon. Get it?).
So DNSSECbis doesn’t protect the “last mile” between Alice and her
ISP. “But that’s OK, that last mile is behind a firewall!”
5.2.
Another issue: nobody knows when or where or how or who or why the
roots are going to be signed and who will own the key. Without
dignifying this “Homeland Security wants the root signing key”
controversey, let’s acknowledge that the dream of a solid
authentication chain running from a.victim.com all the way back
through COM to the root isn’t happening anytime soon.
That’s OK. The ISC, authors of BIND, have set up a parallel ICANN for
DNSSEC, and a protocol extension to match it. If the ICANN/IANA roots
won’t secure “a.victim.org”, DLV will secure
“a.victim.org.dlv.isc.org” for you. And all you have to do is trust
yet another server, this time run by the ISC. And also accept DLV as
part of the DNSSECbis standard, which it isn’t, yet.
Having fun yet? Anyone want to lay odds on DNSSECbisbis (or
whatever the CCITT folks do after “bis”) happening?
6.
Which, thankfully, brings me to the last part of my argument.
Have you ever set up an SSL certificate?
Have you ever set up a zone with an AXFR secondary in BIND?
These are not two great tastes that go together. But it gets worse. It
always does. Because here’s something else that you’ve probably done:
you’ve visited a totally legitimate HTTPS website that had an expired
or transiently broken SSL cert.
When that happens, you get a click-through warning, which you
dutifully ignore. That’s a part of the Internet that the DNSSEC people
don’t like. And I feel their pain. But.
When a browser sees an invalid SSL certificate, it has the option of
popping up a warning dialog that you can ignore. Now, this is what DNS
lookup code looks like in your applications now:
if(!(hp = gethostbyname("a.victim.com")))
fatality();
And, this is what DNS lookup code looks like in your application after
DNSSEC:
if(!(hp = gethostbyname("a.victim.com")))
fatality();
And, “fatality” is what you get if any piece of this DNSSEC puzzle
fails. All the signatures on all those records out there? They
expire and need to be renewed. And they have be kept in sync across
the whole system. And they have to be configured, by tens of thousands
of people of wildly differing skill levels.
That’s because the DNS interfaces on every host on the Internet have
no good way of signalling failure. In fact, because DNSSECbis won’t
extend down the “last mile”, like I mentioned, the protocol won’t
have a good way of signalling failure. Which means that all the
transient glitches you get with SSL, which is a vastly simpler and
smaller system, are total failures in DNS.
Still a believer? There’s more to come.
Back | Top | Next
42 Comments
Thomas Ptacek | April 3rd, 2007 | Filed Under: Bitching About Protocols, Uncategorized
Brenden Kuerbis at Internet Governance, a grad student at Syr, is blogging a series on what makes DNSSEC great. I’m looking forward to his arguments. Discovered via
the DNS ops list, where my posts are apparently considered a “troll thread”. Not at all surprised.
No Comments
Thomas Ptacek | April 3rd, 2007 | Filed Under: Bitching About Protocols, Uncategorized
Back | Top | Next
1.
Alice and Bob want to talk.

Mallory wants to get in on the action.

With unprotected IP and HTTP, Mallory can do that. In fact, it’s
really easy; Mallory doesn’t even have to be in the middle. We’ve
idealized Alice and Bob. But Alice needs to use the DNS to find Bob.

If Mallory can spoof the DNS, she can get between Alice and Bob. Mean
‘ol Mallory!

Alice is my mom. Bob is Bank of America. Mallory is the Russian
Mafia. I care a lot about this attack.
2.
So does everyone else, since, like, 1994, when someone installed
SunSniff on a machine plugged into a colo Ethernet link that was part
of the Internet backbone and sniffed everyone’s passwords. So, before
Bank of America got on the Internet, everyone solved this problem:

This is SSL/TLS. SSL/TLS is one solution to the problem of
eavesdroppers and man-in-the-middle attackers. It relies on
certificate authorities.
Alice is using a browser pre-configured with the public keys of
several trusted third parties. These public keys are “trust
anchors”. Bob arranges with one of these third parties to get
“certificate”, which says, “I’m really Bob, and here’s my public
key”. Bob’s server presents this certificate to Alice when she
connects, as part of the TLS handshake. Alice and Bob use their public
and private keys to agree on an ephemeral AES session key, which
protects all future communication between them.
This is a really, really nice protocol.
You don’t know it just to look at it, though. It relies on X.509,
which is an ASN.1 protocol. ASN.1 is to the Internet what
Pravda is to the GOP. SSL/TLS has its own record layer. Ew! It has a really
complicated handshake. Lots of negotiation. And the certificates are
hard to configure. And you have to talk to creepy Certificate
Authority companies who want you to pay for the privilege.
On the other hand, Mallory is clever and has a lot of ways to attack a
crypto protocol. And SSL/TLS accounts for all of them. Mallory will
fake messages try to get Alice and Bob to agree to an insecure version
of the protocol. She can’t; the handshake has a built-in integrity
check. Mallory will try to replay messages. Nope. Mallory will break
MD5 AND SHA1. Still no luck! The protocol uses both!
SSL/TLS says, as long as you can trust one trusted third party, who’s
only job is to protect cryptographic secrets, and who will certainly
go out of business if they are completely compromised, you’re
safe. (Well, OK, you have to trust your ability to read, and your
browser, too). And if you don’t want to trust a third party, you can set up
your own certificate authority.
SSL/TLS protects virtually all secure web transactions.
3.
Don’t like SSL/TLS? Ok, you have another option:

This is PGP/GPG. Alice and Bob can directly swap public keys. They can
use their private keys to generate messages that only they can read,
and that can only come from them. The difference is, instead of
trusting a certificate authority, they trust a file format. This is
web of trust, although that’s kind of an overblown name for “I can
read you a fingerprint of my public key over the phone so you know you
got the right one, and I know I have your key because my best friend
gave it to me”.
PGP/GPG protects virtually all secure email. We use GPG. Our secret
messages are decidedly worth intercepting. It works well.
4.
Don’t like PGP/GPG? Ok, you have another option:

This is SSH. Alice and Bob can trade public keys the first time they
talk to each other. They can use their private keys to generate
session keys that protect all future communications between them, just
like SSL/TLS. They know they have the right keys because they remember
the first time they kissed; if Mallory comes between them, her key
will necessarilly be different. This is called key continuity.
SSH protects virtually all secure Unix and router administration. Like
everyone else, we use SSH.
Note that in all three cases, I made no mention of the DNS. In all
three cases, Mallory continued to own the DNS. In fact, I put Mallory
right in the middle between Alice and Bob. That’s better than owning
the DNS. I gave Mallory the pipe. And Mallory still can’t win. Alice
and Bob have end-to-end protection.
5.
Mallory can still mess with Alice and Bob though. She can drop their
packets on the floor. Or worse! She can redirect their DNS messages!
This keeps Alice and Bob from talking to each other. Denial of
service!
This really skeeves the IETF DNS people out. DNS is involved, in some
way, in almost every transaction on the Internet. People should be
able to talk to each other, and trust that they’re talking to who they
think they are. Even if they don’t want to use TLS or GPG:

This is DNSSEC. Sort of. It protects the DNS sort of the same way TLS
protects the web: Alice and Bob have “trust anchors” that let them
verify public keys from DNS servers. Alice can trust results from the
DNS. Alice can find Bob, and Mallory can’t trick her.
At least, not that way. Please note the obvious problem
here. Securing the DNS protects DNS lookups. But Alice and Bob still
need another layer of security, because Mallory owns the pipe and can
see their packets. In practical terms, Mallory can grab Alice’s HTTP
cookies, log into the bank right after she does, and the idempotent
HTTP application on the bank’s server won’t do anything to stop her.
7.
This sucks! But it gets worse. Note the trust relationships in TLS,
GPG, and SSH:
In TLS, you have a trust a Certificate Authority, who gets
paid to protect your secrets.
In GPG, you have to trust your friends.
In SSH, you have to trust your memory.
But, going back to DNS 101, there isn’t just one DNS authority. DNS is
distributed. A lot. Each portion of the namespace is governed by a
different entity. You have to trust all of them.

And the people who manage domain namespace aren’t (typically) security
people.
In fact, DNS spoofing is pretty rare (there are much, much easier
attacks that are way more effective). But most of the time, when it
happens, it’s not because Mallory played packet tricks with Alice’s
DNS requests. Nope:

Mallory lived through the late ’90s and learned, from software like
BIND, how exploit scripts work. My browser trusts tens of Certificate
Authorities, and presumably they’re all reasonably hard to crack. But
there are tens of thousands of DNS servers, all responsible for
their own DNSSEC security. Mallory’s just gonna go own one of them up.
Now, DNSSEC is not retarded. Mallory can’t bust up Southern Illinois
University’s authority servers and spoof Bank of America. But there
are way more DNS servers than GPG and SSH keys. There may be more of
them than there are current TLS certificates. And a compromised DNS
server is more powerful than a single compromised certificate; it lets
you synthesize arbitrary names under the authority of the server.
DNSSEC does nothing to account for this attack, which is the most
likely vector Mallory will use to subvert the DNS.
Another attack DNSSEC does nothing to account for is
Denial of Service. Like I pointed out, if you’re using TLS, there’s nothing
Mallory can do to you except keep you from talking. But even if
Mallory doesn’t own the pipe, she can still mess with you by
saturating your DNS servers with requests (for instance, by making
them walk absurd and ambiguous chains of keys). DNSSEC is not a
lightweight protocol, and its authors explicitly exempted DOS from the
problems it contemplates. A confession: this isn’t my argument; it’s
Christian Huitema’s.
And DNS isn’t the only infrastructure protocol that connects Alice to
Bob. Even if you secure the DNS, Mallory can still go after:
DHCP
ARP
Anycast Routing
VLAN trunking protocols
IGPs like RIP and OSPF
EGPs (meaning, BGP4)
Successful attacks on any of these protocols —- which have actually
happened in the real world —- give Mallory the pipe again. Alice’s
DNS requests are secure, but her messages to Bob aren’t. In theory, we
should secure all of these protocols, too. But it took over 13 years
to agree on how to secure the DNS, and the DNS is simpler than some of
these protocols.
Finally, and to my mind most importantly, DNSSEC does nothing to
address the problem of insecure implementations. There’s some basic
remedial math my readers are pretty familiar with —- as is anyone who
read Schneier’s “Practical Cryptography”: more code = more complexity
= more bugs.
Look at the BIND security page; bugs that involve SIG, or EDNS, or
OpenSSL, or “validation”, or TSIG —- those are vulnerabilities caused
by DNSSEC code.
Alex Bligh made this point for me on the Namedroppers list:
I would suggest this [the DNS is already secure] is a minority view. Else we’d have spent the past
15 years fixing implementations as opposed to protocols.
Well, I know how I spent the last 15 (well, 13) years. And I guess I
know how Alex Bligh thinks he spent the last 15 years. You tell me
which was more important.
Back | Top | Next
37 Comments
Thomas Ptacek | April 2nd, 2007 | Filed Under: Bitching About Protocols, Uncategorized
Back | Top | Next
The head of the Internet Architecture Board has declared DNSSEC a
success. The DNSSEC RFCs are standards-tracked. The DNS Extensions
Working Group is winding down. Are we finally going to have a secure
domain name system?
No. I’ll tell you why I don’t think so:
I’ll argue that secure DNS doesn’t solve a real problem.
I’ll argue that it’s so complicated and expensive that
nobody will ever deploy it.
I’ll argue that it’s actually contrary to the design of
the Internet.
And, I’ll argue that it’s a huge waste of effort; in fact,
that the struggle to deploy DNSSEC will do more harm than good.
Let me get started. First, what makes you think we need a secure
domain name system?
Because DNS is insecure! Anybody can spoof a DNS response,
convincing my browser that my bank’s website is really running on some
mafia-controlled Linux box in Uzbekistan!
You’re right. DNS is totally insecure. You can’t trust results coming
from DNS.
And that’s a problem!
Not really. You don’t need to trust the DNS anymore. Real-world
applications aren’t supposed trust names. At least a few of those
applications really don’t, and they seem to work OK.
Want an example? Take my banking website. You can’t spoof it, even if
you do own up the DNS, because a third party has to cryptographically
attest to my browser that the server has a valid key. Spoofing is
prevented at the application layer, not the DNS.
But not every application does that! We can’t keep moving forward with no
security in such a core part of the Internet infrastructure.
I agree, in principle. The world would be a better place if the DNS
was secure. But in reality, it’s not worth the costs. DNSSEC —-
crypto-secured DNS —- is so complicated, unstable, and expensive that
it’s not worth the cost.
How can you say it’s unstable? Back that argument up with
evidence!
I can’t, which is part of my point. After over 12 years of earnest
development, there are still no mainstream deployments of DNSSEC. But
I can read an RFC, compare DNSSEC to other protocols, and predict what
the operator and user experience is going to be. And it seems like a
nightmare.
You know what? I don’t even agree in principle. DNSSEC is a bad thing, even
if it does work.
How could that possibly be?
It violates a fundamental design principle of the Internet.
Nonsense. DNSSEC was designed and endorsed by several of the
architects of the Internet. What principle would they be violating?
The end-to-end argument in system design. It says that you want to
keep the Internet dumb and the applications smart. But DNSSEC does the
opposite. It says, “Applications aren’t smart enough to provide
security, and end-users pay the price. So we’re going to bake security
into the infrastructure.”
What’s wrong with that? IPSEC says the same thing!
Look how well that turned out. But IPSEC is at least optional: it’s so
all-or-nothing that the only place anybody thinks to turn it on is VPN
links. But DNSSEC isn’t a VPN tool. It’s an anti-phishing
tool. Everybody’s going to have to deal with it, whether they have
better or simpler ideas for providing security or not —- whether they
even need security or not.
It doesn’t even solve the problem of securing the next wave of
applications. It can’t, because it doesn’t know what those
applications look like. But it’s a pretty safe bet that many of them
won’t even use the DNS.
Everything on the Internet uses DNS. The head of the IAB says so.
The head of the IAB didn’t design AOL Instant Messenger, far and away
the most important messaging application on the Internet. DNS doesn’t
tell me how to find my friends on AIM; AOL’s servers do. AIM isn’t
secure right now, but DNSSEC can’t change that. Only the IM developers can.
And they can do it without DNSSEC.
The head of the IAB didn’t design peer-to-peer file sharing, far and
away the biggest consumer of traffic on the Internet. DNS doesn’t tell
me how to find files on a P2P network: the P2P protocols do. P2P isn’t
secure right now, but DNSSEC can’t change that. Only the P2P
developers can. And they can do it without DNSSEC.
The head of the IAB didn’t design content distribution networks like
Akamai, which power many of the most important websites on the
Internet. Vanilla DNS doesn’t tell me what mirror to fetch content off
of; Akamai’s traffic directors do. I don’t know if Akamai is secure or
not, but I’m pretty sure DNSSEC isn’t the deciding factor.
If you think the future of the Internet involves things like overlay
networks, peer-to-peer distributed systems, or large-scale web
applications like Google and YouTube, you have to ask yourself: where
does DNSSEC fit here? These things are happening independently of
DNSSEC. They have to be: nobody, not even the IETF, thinks DNSSEC is
going to go mainstream in the next 3 years.
There’s more to the Internet than the web. Maybe these people know
better than you do. Some of them have been fighting spam and phishing
for over a decade. What have you done?
Probably not as much as they have. I’m a mercenary. A creepy security
researcher. You probably don’t want to take my word for how to design
the Internet.
But you probably don’t want to take their word for it either. There
are huge financial implications to how the DNS is architected. A lot
is at stake. And despite the billions of dollars spent every year on
security, despite the near universal staffing of security teams at
every enterprise in the Fortune 500, there’s no detectable market
demand for DNSSEC.
DNSSEC gets in the way. It distracts us from real problems that need
to get solved. It also substitutes a bunch of IETF people for the judgement and expertise of the market, which actually has a track record in solving security
problems. Some of the loudest IETF participants have no
qualifications other than willingness to spend time on mailing lists
and at conferences.
You’re an asshole.
Indubitably. But convince me —- wait, no, just convince my readers!
—- that I’m wrong about this. You just heard my case. I’ll repeat
it. Then I’ll go into detail on each point. Again, I’m saying:
DNSSEC solves a non-problem.
DNSSEC is too complicated to deploy.
DNSSEC breaks the Internet.
DNSSEC wastes time, energy, and money.
If you want to argue, post a comment. I won’t stop you. If you kick my
ass, I’ll put it on the front page. But right now, I think you’re the
opposite of right.
Silence
Hello? You there?
Silence
Oh well. I’d better get writing.
Back | Top | Next
37 Comments
Thomas Ptacek | November 30th, 2006 | Filed Under: Bitching About Protocols, Reversing, Uncategorized
‘Tis the season, apparently. Cool new project and excellent blog post
from libnids author and Eastern European reversing psychopath Rafal
Wojtczuk, now at MCAF’s AVERT labs. He’s announced UMSS, the User Mode
Single-Stepper, a tool for tracing the execution of Win32
binaries.
Refresher: single-stepping stops a program after each individual CPU
instruction, usually to record them. It’s usually done with a
debugger; on Intel, you do it by setting the “trap flag”, which tells
the CPU to generate exceptions after each instruction.

The problem here is, each instruction traps to the kernel, which then
transfers control to another process, which then transfers back to the
kernel to find out what happened. A single user/kernel (u/k)
transition is expensive: network programmers, who execute thousands of
instructions between I/O operations, still try to minimize
them. Debugger single-stepping involves multiple u/k context switches
per instruction. It’s just nightmarishly slow.
Rafal’s project speeds this up by 2 orders of magnitude by single
stepping entirely in userland. How he does it is, he continuously
rewrites the “next” instruction on the fly to transfer control to a
handler function.

This is similar to what Detours does in that Rafal is swapping out
instructions with handler jumps. But Detours only instruments the
prologues of each function. UMSS instruments every instruction, on the
fly. This is tricky, because to do that for each instruction, you have
to know where the next instruction is. It’s not always “the next
instruction in memory”, because of jumps. It’s not always “the target
of a jump”, because jumps are conditional. It’s not always even
possible to look at an instruction and know the jump target, because
jumps can be indirected through registers.
UMSS solves this problem in two ways:
it uses an embedded disassembler to decode jumps with static targets, and peeks at the condition flags to figure out whether jumps will be taken.
it has a simple and clever heuristic for indirected jumps: just switch
back to kernel-assisted debugging for that instruction. The
overwhelming majority of the instruction stream doesn’t need it, so
you still get the huge speedup.
Why is this stuff important? To be honest, I don’t know. The “state of
the art” in tracing programs right now is in instrumenting basic
blocks, which are the ~10-20 instruction chunks that functions are
composed of. For reversing purposes, this level of detail is usually
more than enough. Clearly for malware research, where code is
deliberately designed to be unclear, instruction-by-instruction detail
is critical. I’d love for someone to tell me how I could exploit fast
single-stepping to get a different project done.
The bigger story is the apparent renaissance we’re experiencing in
binary program manipulation. 7 years ago, technology like Detours,
PaiMei, and UMSS would have been the closely-guarded crown jewels of
security companies. Now they’re free side-projects.
8 Comments