Since there have been some questions relating to the security of RADIUS
attribute hiding mechanisms, I thought I'd post a summary of RADIUS
attribute hiding mechanisms, describing their vulnerabilities in more
detail.
First, some background on the Request and Response Authenticators and the
shared secret.
RFC 2865 Section 3 on the Request Authenticator:
In Access-Request Packets, the Authenticator value is a 16
octet random number, called the Request Authenticator. The
value SHOULD be unpredictable and unique over the lifetime of a
secret (the password shared between the client and the RADIUS
server), since repetition of a request value in conjunction
with the same secret would permit an attacker to reply with a
previously intercepted response. Since it is expected that the
same secret MAY be used to authenticate with servers in
disparate geographic regions, the Request Authenticator field
SHOULD exhibit global and temporal uniqueness.
The Request Authenticator value in an Access-Request packet
SHOULD also be unpredictable, lest an attacker trick a server
into responding to a predicted future request, and then use the
response to masquerade as that server to a future Access-
Request.
Section 3 also defines the RADIUS Response Authenticator:
ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
[BA] In practice, maintaining global and temporal uniqueness over the
lifetime of a shared secret is a tall order. Some NAS devices do not
have sufficient entropy on boot to provide temporal uniqueness. When
the same shared secret is used across dozens or even thousands of
devices (a common deployment scenario), global and temporal uniqueness
can become very difficult to satisfy. In retrospect, it would have made
more sense to mix a globally unique quantity (such as NAS-Identifier
or NAS-IP-Address) in subsequent calculations, including in the
Response Authenticator, so as to make global uniqueness more likely.
Here is what RFC 2865, Section 3 has to say about the shared secret:
The secret (password shared between the client and the RADIUS
server) SHOULD be at least as large and unguessable as a well-
chosen password. It is preferred that the secret be at least 16
octets. This is to ensure a sufficiently large range for the
secret to provide protection against exhaustive search attacks.
The secret MUST NOT be empty (length 0) since this would allow
packets to be trivially forged.
[BA] At IETF60, we discussed the consequences of violating this
prescription, namely that the Response Authenticator becomes subject
to dictionary attack.
The encryption algorithm for the User-Password attribute is described in
RFC 2865, Section 5.1:
Call the shared secret S and the pseudo-random 128-bit Request
Authenticator RA. Break the password into 16-octet chunks p1, p2,
etc. with the last one padded at the end with nulls to a 16-octet
boundary. Call the ciphertext blocks c(1), c(2), etc. We'll need
intermediate values b1, b2, etc.
b1 = MD5(S + RA) c(1) = p1 xor b1
b2 = MD5(S + c(1)) c(2) = p2 xor b2
. .
. .
. .
bi = MD5(S + c(i-1)) c(i) = pi xor bi
The String will contain c(1)+c(2)+...+c(i) where + denotes
concatenation.
[BA] Note that the first block of the keystream b1 is based solely on the
shared secret and the Request Authenticator, and does not include any
NAS-specific information (e.g. NAS-Identifier or NAS-IP-Address).
Thus, if the Request Authenticator is not temporally and globally
unique for a given shared secret, the keystream will repeat.
This can be exploited in a number of ways. When two identical Response
Authenticators are found on the same NAS, or on two different NASes that
are known to share the same secret S, the ciphertexts can be XOR'd
yielding the XOR of the first clearext password blocks. This can assist
an attacker in guessing the user passwords; once those are determined
the keystream b1 is also known.
Another way is via a known-plaintext attack, where an attacker attempts
authentication with password p, and then collects the ciphertext c,
allowing the keystream b to be calculated. If the Request
Authenticator ever repeats, the attacker can use the known value of b1 and
the c1 collected from the User-Password attribute to calculate the first
16 octets of the password p1.
Note that both of these attacks do not require the attacker to compromise
the password S.
RFC 2548, Section 2.4.2: MS-MPPE-Send-Key
Call the shared secret S, the pseudo-random 128-bit Request
Authenticator (from the corresponding Access-Request packet) R,
and the contents of the Salt field A. Break P into 16 octet
chunks p(1), p(2)...p(i), where i = len(P)/16. Call the
ciphertext blocks c(1), c(2)...c(i) and the final ciphertext C.
Intermediate values b(1), b(2)...c(i) are required. Encryption
is performed in the following manner ('+' indicates
concatenation):
b(1) = MD5(S + R + A) c(1) = p(1) xor b(1) C = c(1)
b(2) = MD5(S + c(1)) c(2) = p(2) xor b(2) C = C + c(2)
. .
. .
. .
b(i) = MD5(S + c(i-1)) c(i) = p(i) xor b(i) C = C + c(i)
The resulting encrypted String field will contain
c(1)+c(2)+...+c(i).
On receipt, the process is reversed to yield the plaintext String.
[BA] In the situation where a known plaintext attack has been carried out
and the keystream b1=MD5 (S + R) has been determined, the above salt
construction does not help much, since the MD5 calculation can be
continued using the salt field A, which is sent in the clear. Therefore,
an attacker can determine the first 16 octets of the Tunnel-Password,
using the calculated keystream b1'=MD5(S + R + A).
RFC 2868, Section 3.5: Tunnel-Password
Call the shared secret S, the pseudo-random 128-bit Request
Authenticator (from the corresponding Access-Request packet) R,
and the contents of the Salt field A. Break P into 16 octet
chunks p(1), p(2)...p(i), where i = len(P)/16. Call the
ciphertext blocks c(1), c(2)...c(i) and the final ciphertext C.
Intermediate values b(1), b(2)...c(i) are required. Encryption
is performed in the following manner ('+' indicates
concatenation):
b(1) = MD5(S + R + A) c(1) = p(1) xor b(1) C = c(1)
b(2) = MD5(S + c(1)) c(2) = p(2) xor b(2) C = C + c(2)
. .
. .
. .
b(i) = MD5(S + c(i-1)) c(i) = p(i) xor b(i) C = C + c(i)
The resulting encrypted String field will contain
c(1)+c(2)+...+c(i).
On receipt, the process is reversed to yield the plaintext String.
[BA] The Tunnel-Password attribute utilizes the same construction as the
MS-MPPE-Send-Key attribute, and therefore has the same weakness.
SUMMARY
In order to prevent forgeries and keystream recovery, RADIUS requires that
the Request Authenticator be globally and temporally unique. However,
in practice implemenations and deployments often do not satisfy this
requirement. Due to deficiencies in the construction of the Response
Authenticator and attribute hiding algorithms, the problem is magnified.
To address these problems, future attribute hiding algorithms would be
wise to do one or more of the following:
a. Utilize a well-analyzed keywrap mechanism based on a block cipher,
rather than the add-hoc stream ciphers used in RADIUS.
b. Mix in NAS-specific attributes into the calculation, ensuring global
uniqueness.
c. Utilize randomness from two parties (RADIUS client + RADIUS server).
A minimum of 128-bit nonces are recommended.
--
to unsubscribe send a message to radiusext-request@ops.ietf.org with
the word 'unsubscribe' in a single line as the message text body.
archive: <http://psg.com/lists/radiusext/>