Any authentication protocol that exposes credentials while in transit over the network is potentially vulnerable to eavesdropping attacks, which are also called sniffing attacks after the colloquial term for network protocol analyzers. A replay attack usually is built upon eavesdropping and involves the use of captured credentials by an attacker to spoof the identity of a valid user.
Figure 4-3
Password-guessing attempts against Windows IIS result in these events written to the Security Log.Unfortunately, some of the most popular web authentication protocols do expose credentials on the wire. We’ll talk about common attacks against popular web authentication protocols in the following sections.
Basic We’ve already seen how HTTP Basic authentication can be vulnerable to password guessing. Now we’ll talk about another weakness of the protocol. In order to illustrate our points, we’ll first give you a bit of background on how Basic works.
Basic authentication begins when a client submits a request to a web server for a protected resource, without providing any authentication credentials. In response, the server will reply with an access denied message containing a WWW-Authenticate
header requesting Basic authentication credentials. Most web browsers contain routines to deal with such requests automatically by prompting the user for a username and a password, as shown in Figure 4-4. Note that this is a separate operating system window instantiated by the browser, not an HTML form.
Once the user types in his or her password, the browser reissues the requests, this time with the authentication credentials. Here is what a typical Basic authentication exchange looks like in raw HTTP (edited for brevity). First, here’s the initial request for a resource secured using Basic authentication:
GET /test/secure HTTP/1.0
The server responds with an HTTP 401 Unauthorized (authentication required) message containing the WWW-Authenticate: Basic header:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="luxor"
This causes a window to pop up in the client browser that resembles Figure 4-4. The user types his or her username and password into this window and clicks OK to send it via HTTP:
GET /test/secure HTTP/1.0
Authorization: Basic dGVzdDp0ZXN0
Note that the client has essentially just re-sent the same request, this time with an
Authorization header. The server then responds with another “unauthorized” message if the credentials are incorrect, a redirect to the resource requested, or the resource itself, depending on the server implementation.
Wait a second—where are the username and password? Per the Basic authentication spec, the authentication credentials are sent in the Authorization header in the response from the client and the credentials are encoded using the Base64 algorithm. Those unfamiliar with Base64 may, at first glance, believe it is a type of encryption due to the rather opaque encoded form. However, because Base64 is a type of encoding, it is trivial to decode the encoded values using any number of readily available utilities or scripting languages. A sample Perl script has been provided here to illustrate the ease with which Base64 can be manipulated:
#!/usr/bin/perl # bd64.pl
# decode from base 64 use MIME::Base64;
print decode_base64($ARGV[0]);
Let’s run this bd64.pl decoder on the value we saw in our previous example of Basic authentication in action:
C:\bd64.pl dGVzdDp0ZXN0
test:test
As you can see, Basic authentication is wide open to eavesdropping attacks, despite the inscrutable nature of the value it sends in the Authorization header. This is the protocol’s most severe limitation. When used with HTTPS, the limitation is mitigated. However, client-side risks associated with Basic authentication remain because there is no inactivity timeout or logout without closing the browser.
Digest Digest authentication, described in RFC 2617, was designed to provide a higher level of security than Basic. Digest authentication is based on a challenge-response authentication model. This technique is commonly used to prove that someone knows a secret, without requiring the person to send the secret across an insecure communications channel where it would be exposed to eavesdropping attacks.
Digest authentication works similarly to Basic authentication. The user makes a request without authentication credentials and the web server replies with a WWW- Authenticate header indicating credentials are required to access the requested resource. But instead of sending the username and password in Base64 encoding as with Basic, the server challenges the client with a random value called a nonce. The browser then uses a one-way cryptographic function to create a message digest of the username, the password, the given nonce value, the HTTP method, and the requested URI. A message digest function, also known as a hashing algorithm, is a cryptographic function that is easily computed in one direction and should be computationally infeasible to reverse. Compare this hashing method with Basic authentication that uses the trivially decodable Base64 encoding. Any hashing algorithm can be specified within the server challenge; RFC 2617 describes the use of the MD5 hash function as the default.
Why the nonce? Why not just hash the user’s password directly? Although nonces have different uses in other cryptographic protocols, the use of a nonce in Digest authentication is similar to the use of salts in other password schemes. It is used to create a larger key space to make it more difficult for someone to perform a database or precomputation attack against common passwords. Consider a large database that can store the MD5 hash of all words in the dictionary and all permutation of characters with less than ten alphanumeric characters. The attacker would just have to compute the MD5 hash once and subsequently make one query on the database to find the password associated with the MD5 hash. The use of the nonce effectively increases the key space and makes the database attack less effective against many users by requiring a much larger database of prehashed passwords.
Digest authentication is a significant improvement over Basic authentication, primarily because cleartext authentication credentials are not passed over the wire. This makes Digest authentication much more resistant to eavesdropping attacks than Basic authentication. However, Digest authentication is still vulnerable to replay attacks because the message digest in the response will grant access to the requested resource even in the absence of the user’s actual password. But, because the original resource request is included in the message digest, a replay attack should only permit access to the specific resource (assuming Digest authentication has been implemented properly).
Other possible attacks against Digest authentication are outlined in RFC 2617. Microsoft’s implementation of Digest authentication requires that the server have access to the cleartext version of the user’s password so digests can be calculated. Thus, implementing Digest authentication on Windows requires that user passwords be stored using reversible encryption, rather than using the standard one-way MD4 algorithm.
For those of you who like to tinker, here’s a short Perl script that uses the Digest::MD5 Perl module from Neil Winton to generate MD5 hashes:
#!/usr/bin/perl # md5-encode.pl # encode using MD5
use Digest::MD5 qw(md5_hex); print md5_hex($ARGV[0]);
This script outputs the MD5 hash in hexadecimal format, but you could output binary or Base64 by substituting qw(md5) or qw(md5_base64) at the appropriate spot in line 4. This script could provide a rudimentary tool for comparing Digest authentication strings to known values (such as cracking), but unless the username, nonce, HTTP method, and the requested URI are known, this endeavor is probably fruitless.
MDcrack, an interesting tool for cracking MD5 hashes, is available from Gregory Duchemin (see the “References & Further Reading” section at the end of this chapter for a link).