Setting up an SSTP (Secure Socket Tunneling Protocol) connection earlier, I encountered a vaguely reminiscent problem. [SSTP allows virtual private network – VPN – connections between clients running Vista Service Pack 1 and later and servers running Windows Server 2008 and later, using HTTP over SSL, usually on port 443. Port 443 is the usual HTTPS port, and creating a VPN over just that port and no other allows it to operate over most firewalls.]
The connection just didn’t seem to want to take, even though I had already followed the step-by-step instructions for setting up the SSTP server. I thought I had resolved the issue originally by ensuring that I installed the certificate (it was self-signed) in the Trusted Roots certificate store. [If the certificate was not self-signed, I would have ensured that the root certificate itself was installed in Trusted Roots]
The first thing I did was to check the event viewer on the client, where I found numerous entries.
I found error -2147023660 in the Application event log from RasClient. This translates to 0x800704D4, ERROR_CONNECTION_ABORTED. That was pretty much the same information I already had, that the connection was being prevented from completing. So I visited the server to see if there was more information there.
On the server, I couldn’t find any entries from the time around when I was trying to connect. Not too good, because of course that’s where you’re going to look. In some cases, particularly errors that Microsoft thinks are going to happen too frequently, the conditions are checked at boot-time, and an error reported then, rather than every time the service is called on to perform an action.
Fortunately, it hadn’t been that long since I last booted (and I had a hint or two from the RRAS team at Microsoft), so my eyes were quickly drawn to an Event with ID 24 in the System Log, sourced at Microsoft-Windows-RasSstp. The text said:
The certificates bound to the HTTPS listener for IPv4 and IPv6 do not match. For SSTP connections, certificates should be configured for 0.0.0.0:Port for IPv4, and [::]:Port for IPv6. The port is the listener port configured to be used with SSTP.
Note that this happens even if your RRAS server isn’t configured to offer IPv6 addresses to clients.
So, here’s some documentation on event ID 24 :
This is one of those nasty areas where there is no user interface other than the command-line. Don’t get me wrong, I love being able to do things using the command line, because it’s easy to script, simple to email to people who need to implement it, and it works well with design-approve-implement processes, where a designer puts a plan together that is approved by someone else and finally implemented by a third party. With command-line or other scripts, you can be sure that if the script didn’t change on its way through the system, then what was designed is what was approved, and is also what was implemented.
But it’s also easy to get things wrong in a script, whereas a selection in a UI is generally much more intuitive. It’s particularly easy to get long strings of hexadecimal digits wrong, as you will see when you try and follow the instructions above. Make sure to use copy-and-paste when assembling your script, and read the output for any possible errors.
I’ve read some debate about the top 25 programming mistakes as documented by the CWE (Common Weakness Enumeration) project, in collaboration with the SANS Institute and the MITRE . That the list isn’t complete, that there are some items that aren’t in the list, but should be, or vice-versa.
I think we should look at the CWE top-25 as something like the PCI Data Security Standard – it’s not the be-all and end-all of security, it’s not universally applicable, it’s not even a “gold standard”. It’s just the very bare minimum that you should be paying attention to, if you’ve got nowhere else to start in securing your application.
As noted by the SANS Institute, the top 25 list will allow schools and colleges to more confidently teach secure development as a part of their classes.
I personally would like to see a more rigorous taxonomy, although in this field, it’s really hard to do that, because in large part it’s a field that feeds off publicity – and you just can’t get publicity when you use phrases like “rigorous taxonomy”. Here’s my take on the top 25 mistakes, in the order presented:
“These weaknesses are related to insecure ways in which data is sent and received between separate components, modules, programs, processes, threads, or systems.”
“The weaknesses in this category are related to ways in which software does not properly manage the creation, usage, transfer, or destruction of important system resources.”
“The weaknesses in this category are related to defensive techniques that are often misused, abused, or just plain ignored.”
Glaringly absent, as usual, is any mention of logging or auditing.
Protections will fail, always, or they will be evaded. When this happens, it’s vital to have some idea of what might have happened – that’s impossible if you’re not logging information, if your logs are wiped over, or if you simply can’t trust the information in your logs.
Maybe I say this because my own “2ndAuth” tool is designed to add useful auditing around shared accounts that are traditionally untraceable – or maybe it’s the other way around, that I wrote 2ndAuth, because I couldn’t deal with the fact that shared accounts are essentially unaudited without it?
Of course, that leads to other subtleties – the logs should not provide interesting information to an attacker, for instance, and you can achieve this either by secreting them away (which makes them less handy), or by limiting the information in the logs (which makes them less useful).
Another missing issue is that of writing software to serve the user (all users) – and not to frustrate the attacker. [Some software reverses the two, frustrating the user and serving the attacker.] We developers are all trained to write code that does stuff – we don’t tend to get a lot of instruction on how to write code that doesn’t do stuff.
Another mistake, though it isn’t a coding mistake as such, is the absence of code review. You really can’t find all issues with code review alone, or with code analysis tools alone, or with testing alone, or with penetration testing alone, etc. You have to do as many of them as you can afford, and if you can’t afford enough to protect your application, perhaps there are other applications you’d be better off producing.
Other mistakes that I’d like to face head-on? Trusting the ‘silver bullet’ promises of languages and frameworks that protect you; releasing prototypes as production, or using prototype languages (hello, Perl, PHP!) to develop production software; feature creep; design by coding (the design is whatever you can get the code to do); undocumented deployment; fear/lack of dead code removal (“someone might be using that”); deploy first, secure later; lack of security training.
Every so often, someone on one of the security mailing lists to which I subscribe will post a frothing rant from someone who has discovered their own personal “magic bullet” which solves all their security woes. This time, it’s a guy who was convinced that Microsoft’s recent out-of-band Internet Explorer patch MS08-078 is actually a conspiracy by Microsoft (and the government, of course) to invade your computer.
Okay, now aside from the point that, technically, Microsoft “pwns” your computer if you run their OS, and they don’t need to install patches to continue to do so; aside from the Ballmer defence (“If we were actually evil, don’t you think we’d be doing a better job at it?”; aside from that and many other considerations, what evidence did this guy have that the patch is a conspiracy?
Gibson Research’s ShieldsUp site reported that his system was “Fully Stealthed”.
[For those of you non-geeks reading the blog, that means that his firewall was closed up so tight that his system was not responding to any attempt to connect.]
Many other people have made, or will make, the obvious note that the patch is for a browser client bug, whereas the firewall ignoring all incoming requests only protects against server-related bugs, so I’ll leave it to those people to discuss that.
My concern is that Gibson is still pitching the idea that “Fully Stealthed” is a good idea.
TCP/IP, the network protocol on which much of the Internet is currently based, is designed around certain error reporting mechanisms that keep the system able to route around trouble.
One of these mechanisms is the TCP RST (reset) flag. The reset flag a great tool, as it says in a single bit “I received this packet, but I can completely guarantee that it’s not meant for me”. Another similar mechanism is the “ICMP Host Unreachable” response, which says “You appear to be trying to send a packet through me to another machine, but although I’m not a bad place to send that packet through, I can’t seem to reach that machine just now”.
When you’re “Fully Stealthed” (or completely non-responsive, if you prefer), it’s like you’re a black hole, and neither the TCP RST flag nor the ICMP Host Unreachable errors are returned from your system.
That’s great, right, because it means that your attackers can’t tell you’re there? It’s like you’re a black hole, no one can see you, right?
That sounds good in theory, except that even black holes can be seen, because they don’t act like the empty space that might otherwise be there.
Similarly, a “Fully Stealthed” machine gives away its presence by occupying an IP address that will not respond at all when you try to contact it. Very much like a black hole, it’s clear that it’s there, because if there was nothing there, the upstream routers would be passing back ICMP Unreachable messages.
OK, so maybe they know that I’ve got a machine here, at this IP address, but it’s safe, because it’s Fully Stealthed – Stealth just sounds so cool, especially since it’s a verbed noun! It’s alright that I look like a hole to the rest of the Internet, because nobody can do anything to me!
The attacker can pretend to be you, because there’s nothing you’re going to say about it.
Let me qualify that – of course, the attacker can’t use your password if he doesn’t know it, nor can he use your private keys. But he can use another thing that some sites use as part of the proof that you are who you claim to be.
He can use your IP address.
A few things prevent this normally:
So, number 1 and 3 aren’t always a barrier – number 2 is definitely a barrier if the attacker needs to maintain the connection for more than a few fractions of a second, as the RST from the spoofed IP address will cause the server to drop the connection and ignore what the attacker is trying to do.
So, this is a valuable protection that a “fully-stealthed” firewall is going to throw away for you – the ability to spot when someone is spoofing your IP address, and to respond back to say “uh, that isn’t me – stop talking to him”.
A firewall should behave as if the machine is present but disinterested, and should actively refuse misguided connection attempts and responses, not merely ignore them. There’s a big difference between the two behaviours. Don’t use the sensationalist terminology of a poor substitute for an expert as a replacement for understanding of your risks and threats.
To an uninformed reader, the advisory (and especially the paper) doesn’t make a whole lot of sense, as with most cryptography documents. If there’s an attack on a cryptographic technology, doesn’t that mean it’s broken and we should stop using it?
Not really, no. We should stop using, or shore up, those components that have an increased vulnerability.
First, let’s remember that cryptography is necessarily full of mathematical theory and that it is very much a developing field. If I say something along the lines of “magic happens here”, please accept that at face value. It means that there is something hugely full of mathematical complexity that I don’t understand, but which has been assessed by mathematicians who know more than I do about the subject.
So, a little background, and an explanation of the attack, before we get to the mitigations.
Every time you use HTTPS (HTTP over SSL / TLS), there’s an identifying exchange – at the very least, the server identifies itself to you, and possibly you identify yourself to the server. In SSL, this is almost always done using certificates – strictly speaking, X.509 certificates.
A certificate is a list of statements about the identity of the party it represents, followed by a mathematically-derived encrypted value called a “signature”. The signature is based on a hash function, which is chosen to be resistant to attack. Typical hash functions are MD5, SHA1, and the “SHA-2” family which are identified by the number of bits of output they produce (i.e. how well they uniquely represent the original information to be hashed). The signature is the hash of the identity statements, encrypted using the issuer’s private key. This means that anyone can decrypt the hash, but in doing so, they will recognise both that only the issuer can have created the signature, and that the identity claims made in the certificate are accepted as valid by the issuer.
This allows you to trust the owner of the certificate, on the basis that you trust the issuer. Sometimes you don’t know if you can trust the issuer, either, and so you have to find out if you can trust the issuer – by looking at their certificate, seeing what claims it made, and what other issuer signed it, and so on, up a “chain of trust”, until you either meet a certificate you do trust, or you meet a certificate that is “self-signed” – that is, that it claims to be its own issuer, and has no other signatory.
So, from this description, you should be able to envisage a chain of trust, where the “leaf certificate” of the site whose identity you want to verify, is signed by an intermediate certificate authority (CA), which may in turn be signed by an intermediate CA, and so on, until you meet a certificate that is signed by a “root CA” – a self-signed certificate whose trust you can use as a basis for trusting the leaf certificate.
Many root CAs are installed by default in operating systems, or applications that use SSL, with the intent that you should be able to trust all certificates issued by those CAs, because they take adequate steps to verify the certificates they issue, and because they use modern technology.
There’s nothing surprising about this attack to those of us who follow cryptography news. One of the problems with hashes is that it is possible to generate two paired documents, that have different content, but whose hash is the same. It has been known since 2004 that you can generate such colliding documents using MD5 as a hash without quite as much effort as the “brute force” technique of trying to generate documents and see if they match. From that, we have (or should have) predicted that this attack was possible, though not easy.
The attack is this – the attacker requests a bona fide web-site, or email (or any other) certificate from a reputable certificate authority. The certificate request is generated along with a second ‘shadow’ certificate – the two differ in areas chosen by the attacker, and with sufficient care to make sure that the issued certificates will both match the same signature.
This gives two certificates, which each appear to have been issued by the certificate authority, but only one of which actually contains information that was seen by the certificate authority.
The method of attack beyond this point will depend on what the shadow certificate was. The simplest way to attack this would be to have both certificates be web site certificates (or both be email certificates, etc), so that you could ask the CA for a certificate for your own name, but wind up with a certificate for someone else’s name – a big company or an important individual, say. That’s useful, but it only gives you one usable certificate per request. Keep that up, and you are sure to be detected.
The method outlined in the research paper, however, goes a step further than that – the certificate request that the CA sees is, as before, a simple web site certificate request. But the shadow certificate is designed to be that of an intermediate CA itself. Once this attack is successful, you can use the intermediate CA to issue any number of web site, email, code-signing, and even other CA certificates. Because these certificates chain up through your bogus intermediate CA, and then to a trusted root, they too will be trusted.
There are several defences to consider, and I’ll address them from the perspective of various different parties.
First of all, all certificate authorities need to move to stop using MD5 when signing other people’s certificates. They should have stopped doing this some time ago, as it was clear that the generation of colliding certificate requests was an ever-increasing possibility. Also on the way out should be SHA1 (although that does mean older systems and software may have issues, because they may not be able to support newer SHA-based hash and signature algorithms). Note that this (particularly the dropping of SHA1) is a recommendation that should be followed with glacial slowness, over years, rather than days. We’re not that broken yet.
Even if the CA continues to use MD5 and SHA1, they can adequately protect against this attack by using non-predictable serial numbers when generating the certificate signatures. This is essentially the area where the CA can most easily and most effectively prevent this attack from succeeding, relying as it does on being able to predict precisely the contents of the returned certificate. This will continue to work so long as the attackers can only generate two colliding paired documents – if there is ever a sustainable attack that allows creating a document that matches the hash of another document without generating them together, this too will be a cause to doubt those certificates.
Another defence against this (but not the simpler form of the attack) is to ensure that you use different CAs to issue leaf certificates than you use to issue intermediate CA certificates, and that you set limits on how long the chain may be as signed by your CAs. That way, a leaf certificate request cannot be used to create a shadow intermediate CA certificate, because verification of the chain will fail because of length constraints.
Check your certificate requests, and make sure that you have not seen a large number of certificate requests from substantially the same source, in an attempt to generate a desired serial number. Offer your existing customers, if they are worried about MD5-signed certificates, the option to replace their certificates with certificates signed by other hash schemes.
There’s really not anything the web-site owner can do, beyond checking any reports of hijacked sessions, or web sites not appearing to be correctly identified, and then taking legal action to remove such pretender sites when they are found.
One thing that can be done is to champion the use of Enhanced Validation (EV) SSL Certificates, as specified by the Browser Forum. These certificates are required to use a chain that has no MD5 signatures in anything other than the root CA. Push the message to your customers and users that the green bar indicates a higher level of trustworthiness. You’ve not only identified yourself to the CA’s satisfaction, but your CA and you are committed to a more up-to-date technical configuration.
Ask your CA if you need to take action with your existing certificates – if they are signed by using MD5 hashes, it may be that some customers will refuse to accept your certificates. Your CA may have a reasonable offer on replacing your certificates with ones signed by SHA1 or other hashes.
These are the guys that really matter – because if they can be fooled, then the attack has succeeded.
The first thing that has to be drummed into web-site users’ heads is that a certificate error message should be reason for you to stop your visit to the web site with the error, and to not place any orders with them, or supply it with your private information (password, personal details, etc) until you have resolved with their technical support what the issue is. This step alone is something that I have emphasised before, and I emphasise it again now, not because it is the best fix for this issue (because a clever attacker will try to produce a certificate that doesn’t error), but because it’s something that protects against the far easier attacks, and it is still not a habit that users have gotten into.
Next, keep up-to-date with patches. If there are interesting ways to block this at the browser, those will be distributed through security patches to your browser or other applications. If you use a lot of OpenSSL-based applications, keep looking for updates to those; if you use a lot of CryptoAPI-based apps, updates should come to you automatically through Windows Update.
Read Microsoft’s Security Advisory, as well as entries on the Microsoft Security Response Center Blog and the Microsoft Security Vulnerability Research & Defense Blog.
Consider, if you already verify certificate chains yourself, adding or documenting features to refuse chains that flow through CA certificates signed with MD5; also to refuse chains that flow through CA certificates with too much ‘cruft’ (this attack uses the “Netscape Comment” field and fills it with binary that doesn’t look very comment-like).
Make sure that your verification routines check for chain length constraints, as well as corrupt or absent revocation list locations. Again, this attack had no space to put a valid CRL location in place.
If you develop IDS solutions, you may want to try and check for an SSL negotiation that includes certificates signed by intermediate CAs that are themselves signed by using the MD5 hash algorithm – although this is a little complex to track, it shouldn’t be completely impossible.
This is a proof of concept of a theoretical attack, and has generated some interest because it’s a shoe we’ve been waiting to see drop. Repeating the work with the information supplied by Sotirov et al would require a lot of significant and serious mathematics. I know that’s not something to make it impossible, but I think it’s enough to suggest that the sort of people with enough resources to hire advanced mathematicians would find it cheaper and easier to just use something more like social engineering to achieve the effect of having visitors trust your web site.
In several months, the tools will become more widely available, but by then, CAs should be smart enough to stop using MD5, and be considering a move to SHA256 and above. And if they aren’t, I’m sure there will be further advisories with instructions on which root CAs to remove from your trusts.
This is a thoroughly interesting attack, and exciting to people like me. That shouldn’t be taken as an indication that the world is about to collapse, or that you can’t go on trusting HTTPS the way you currently do. Even though we now have the ‘perfect storm’ of a serious DNS flaw backed with a way to subvert SSL, it doesn’t appear to be in use at the present, and with the information on how this attack was achieved, it’s possible for a root CA to comb back through their records and find suspicious behaviours that match this attack.
Link: Verisign’s statement (they own RapidSSL, the CA that was the subject of this attack).