The RADIUS (Remote Authentication Dial-In User Service) protocol is at the core of today’s network infrastructure. Although the protocol was first designed in 1991 — during the era of dial-up internet — it remains the de facto standard lightweight authentication protocol used for remote access for users and administrators to networked devices. RADIUS is supported by “essentially every switch, router, access point, and VPN concentrator product sold in the last twenty years” (source).
In RADIUS, a NAS (Network Access Server) acts as a client that verifies an end user’s credentials via RADIUS requests to a central server.
The RADIUS client and server share a fixed secret.
The server responds with an accept or reject message (called Access-Accept
and Access-Reject
, respectively). Requests and responses may contain labeled fields called “attributes” that specify various parameters such as username and password in a request, or network access in a response.
Request packets include a value called a Request Authenticator
that is essentially a random nonce. Response packets include a value called a Response Authenticator
value that is intended to integrity-protect server responses.
The Response Authenticator
is computed as
\[ \mathtt{MD5} ( \mathtt{Code} || \mathtt{ID} || \mathtt{Length} || \mathtt{Request\ Authenticator} || \mathtt{Packet\ Attributes} || \mathtt{Shared\ Secret}), \]
where, as the figure below shows, \(\mathtt{ID}\) and \(\mathtt{Request\ Authenticator}\) are random values that are in the request; \(\mathtt{Code}\), \(\mathtt{Length}\), and \(\mathtt{Packet\ Attributes}\) are values in the server response, and \(\mathtt{Shared\ Secret}\) is the fixed shared secret that client and server know, but which is unknown to the attacker.
In our paper, we give an attack against this ad hoc RADIUS Response Authenticator
“MAC” construction.
Our attack allows a man in the middle between the RADIUS client and server to forge a valid Access-Accept
response to a failed authentication request. The attacker does this by injecting a malicious Proxy-State
attribute into a valid client request. This Proxy-State
attribute is guaranteed to be echoed back by the server in its response. The attacker constructs the Proxy-State
so that the Response Authenticator
values between the valid response and the response the attacker wishes to forge will be identical.
This forgery will cause the NAS to grant the adversary access to network devices and services without the adversary guessing or brute forcing passwords or shared secrets.
The MD5 collision attack that we exploit is a version of the chosen-prefix collision from Stevens et al.. A chosen-prefix collision allows us, given distinct prefixes \(P_1\) and \(P_2\), to efficiently compute gibberish blocks \(G_1\) and \(G_2\) such that \(\mathtt{MD5}(P_1 || G_1 ) = \mathtt{MD5}(P_2 || G_2)\). Having done so, the structure of MD5 means that we can then append any fixed suffix \(S\) and the resulting messages still have colliding MD5 hashes: \(\mathtt{MD5}(P_1 || G_1 || S) = \mathtt{MD5}(P_2 || G_2 || S)\).
In summary, the following figure illustrates our attack when RADIUS is used with PAP, the Password Authentication Protocol.
Access-Request
, which includes a 16-byte random value called Request Authenticator
.Access-Request
(including the random Request Authenticator
) to predict the format of the server response (which will be an Access-Reject
as the entered password is incorrect). Then the adversary computes an MD5 collision between the predicted Access-Reject
and an Access-Accept
response that it would like to forge. This results in binary gibberish strings
\(\mathtt{RejectGibberish}\) and \(\mathtt{AcceptGibberish}\) such that
\(\mathtt{MD5}(\mathtt{Access\text{-}Reject || RejectGibberish})\)
equals \(\mathtt{MD5}(\mathtt{Access\text{-}Accept || AcceptGibberish})\).Access-Request
packet, disguised as a Proxy-State
attribute.Access-Request
checks the user password, decides to reject the request, and responds with an Access-Reject
packet. As the RADIUS protocol mandates that the Proxy-State
attributes are included in responses, \(\mathtt{RejectGibberish}\) is attached to the response. In addition, the server computes and sends a Response Authenticator
, which is essentially
\(\mathtt{MD5}(\mathtt{Access\text{-}Reject || RejectGibberish || SharedSecret})\),
for its Access-Reject
response, to prevent tampering. The attacker does not know the value of \(\mathtt{SharedSecret}\) and cannot predict or verify the MD5 hash.Response Authenticator
to the client.Access-Accept
sent by the adversary verifies with the Response Authenticator
, without the adversary knowing the shared secret. Hence, the RADIUS client believes the server approved this login request and grants the adversary access.This description is simplified. In particular, we had to do cryptographic work to split the MD5 collision gibberish across multiple properly formatted Proxy-State
attributes, and to optimize and parallelize the MD5 collision attack to run in minutes instead of hours. Please read our paper for a comprehensive description.