Anatomy of a vulnerability - cURL web download toolkit holed by authentication bug

You may not have heard of cURL, but you've probably used software that uses it.
It's an open-source programming toolkit that helps you deal with writing client-side code that deals with URLs.
In the words of the project itself, "cURL groks those URLs."
It's popular because it's a URL Swiss Army knife, making it easy to handle popular protocols like HTTP, SMTP, POP3 and many more. It also supports uploads, downloads, authentication, proxies, cookies and SSL/TLS.
It even supports Gopher, if you remember that far back.
One risk with an all-singing, all-dancing library, of course, is that there's more code to go wrong.
And sometimes, even obscure bits of code you thought you'd never use might get triggered. Worse still, they might be triggerable by external circumstances you never predicted.
That's the curly problem here.
The vulnerable code was introduced in the 7.26.0 release, when support for DIGEST_MD5 authentication was added to the cURL software.
DIGEST_MD5 is an rudimentary way of allowing you to login over an unencrypted connection, for example to an HTTP or POP3 server, without sending your actual password.
The server sends a random challenge string, or nonce, together with a bunch of other authentication-related data; you reply with a cryptographic hash of your password mixed up with that server-supplied data:

So a cracker who sniffs your reply can't directly recover your password from it, and since the challenge is random and varies every time you log in, the cracker can't re-use your reply later.
As an aside: avoid using DIGEST_MD5 authentication. Encrypt the entire session using TLS instead.
A cracker who sniffs a DIGEST_MD5 reply can't re-use it directly, but he can use it to try to recover your password offline using a dictionary attack.
TLS not only prevents this, but also keeps the entire transaction secret, including the contents of your web session or email. That's a much better security outcome.
Here's the buggy code from a vulnerable version of cURL:

In C, the management and use of memory is left up to the programmer. You can use library code to help you deal safely with variable-length data, such as user-supplied text strings, or you can deal directly with memory yourself.
Above, the programmer has done the latter.
Firstly, he allocates a series of fixed-length memory blocks on the stack.
Then he copies text strings supplied by the caller of the function into those blocks, but be uses the system functions strcpy() and strcat(), which stand for "string copy" and "string concatentate" (tack one string on the end of another) respectively.
In modern code, you should never use those functions, because you can't limit how much data they copy.
They simply duplicate every byte from the input string into the output string, until a NUL (zero) byte has been found. A NUL is how the end of a text string is denoted in C.
So, if the server sends too much data in its authentication challenge, for example an overly-long realm string (the contents of which can be whatever the server chooses), this function will stuff too much data into the buffer it uses to compute the authentication response.
A buffer overflow will result, and in this case, since the destination data blocks were allocated automatically on the stack, the function will crash when it ends.
That's because the stack also stores the address in memory from which the function was called, so the cURL software can return there when it's finished. The return address is overwritten in the above code if the string response get over-filled.

Author: Paul Ducklin
Source and read more:

0 yorum: