Radius Authentication Server

by: burt rosenberg
at: university of miami


Unpickable?

Radius Authentication Server Project

We implement a simple Radius Authentication server, mostly compliant with the protocol given RFC 2865: Remote Authentication Dial In User Service

Specific Objectives

Man Page



NAME
    mini-radius
    
SYNOPSIS
    mini-radius [-vR -k shared-key -p port] -h host username password
    mini-radius [-vLR -k shared-key -p port] password-file
    
DESCRIPTION
    
    The program runs as either client or server, depending on the whether the -h option
    is present. If server, the password-file is opened and the servers listens on the
    port of authentication requests. If client, the given username password is 
    authenticated to the server/port as given in the option, and YES or NO is 
    printed, according to the result.
    
    The protocol is described in RFC 2865, simplified for only password authentication.
    The access-request (code 1) packet sent by the client has two attributes, user-name
    (code 1) and user-password (code 2); and the response is either an access-accept 
    (code 2) or an access-reject (code 3).
    
    The protocol is modified so that the client does not send the password, but the
    MD5 hash of the password. This simplifies our program by keeping the password attribute
    a fixed size; it also does not reveal the length of the password.
    
    The password file on the server stores MD5 hashes of the MD5 hash of the password,
    hence the authentication on the server is proof that the client knows the preimage
    of the has in the password file.
    
OPTIONS
    -k the shared key for encrypting, the default is pa55word0
    -p the port the server listens (is listening) on, the default is 1812
    -h the radius server hostname
    -v Verbose. Helpful debugging output to stdout. 
    -R no randomness. The stream of random bytes used by the program is 
       set to 1, 2, 3, ... 
    -L when run as a server, do not loop; answer one full request and terminate
    
FILE FORMAT
    Username/Passwords are stored in file on the server. It is of the format
    
    (name:passwordhash\n)+
    
    where name is a non-empty strings from (a-z, A-Z, 0-9)* and password hash is
    hexidecimal encoded, by default the MD5 hash of the password known to the user.   

BUGS
    The MD5 is not secure and should not be used.
    
    The username is not included in the reply packet and therefore not involved in 
    the response authenticator. Since the encryption is malleable it is possible
    the server is authenticating the user of the attackers choice.
    
    The RFC allows a username attribute, but not the password attribute, in 
    the reply packet, and perhaps should be required.
    
    Passwords in password file must be of format exactly [0-9a-f]{32}.

HISTORY
    First introduced in Spring 2017.

LAST UPDATED 
    26 March 2023

Detailed description

This is a simple one round protocol, consisting of the client leading off with a UDP packet to the server, and the server responding with a UDP packet back to the client. The server port is well-known, and the client port is ephemeral.

The initial packet from client to server is an Access-Request followed by an User-Name attribute and an User-Password attribute, in any order.

The response packet from server to client is an Access-Accept or an Access-Reject, as the case may be, with no attributes.

The Cryptography

The client must be assured that the server response is authentically from the server, and has not been replayed, modified, or forged. A form of Message Authentication Code (MAC) is used to cryptographically attest to the authenticity and integrity of the response.

The MAC is a signature on the return message based on a secret shared between the client and the server. Knowledge of the secret is required to correctly compute the MAC, it is exponentially unlikely to guess the MAC, and computationally infeasible to forge a MAC if the secret is unknown. It is important to calculate this MAC precisely. The formula is in Section 3, paragraph Response-Authenticator.


      Response Authenticator

         The value of the Authenticator field in Access-Accept, Access-
         Reject, and Access-Challenge packets is called the Response
         Authenticator, and contains a one-way MD5 hash calculated over
         a stream of octets consisting of: the RADIUS packet, beginning
         with the Code field, including the Identifier, the Length, the
         Request Authenticator field from the Access-Request packet, and
         the response Attributes, followed by the shared secret.  That
         is, ResponseAuth =
         MD5(Code+ID+Length+RequestAuth+Attributes+Secret) where +
         denotes concatenation.

The password is encrypted using a Vernon Cipher, see the User-Password attribute, section 5.2.

      On transmission, the password is hidden.  The password is first
      padded at the end with nulls to a multiple of 16 octets.  A one-
      way MD5 hash is calculated over a stream of octets consisting of
      the shared secret followed by the Request Authenticator.  This
      value is XORed with the first 16 octet segment of the password and
      placed in the first 16 octets of the String field of the User-
      Password Attribute.

A pseudo-random pad (key stream) is needed for the Vernum cipher. The pad is computed by both the client and server by hasing the concatenation of secret shared key and the Request-Authenticator by the MD5 hash function. The MD5 hash function is cryptographically strong — i.e. there is strong circumstantial evidence that the function acts as if it is assigning a randomly chosen output for each input.

The openssl library has the MD5 function, see [man 3 md5].

Authentication Logic

The system includes a double hashing of the password that the user has memorized. The first is just a convenience hash. Call the the password-hash. Windows has the NT-Hash that is how the password is stored in the SAM. It is not the same system as the unix hash.

The second has is the unix-type hash, and the result of the second has is stored in the password file. Proof of identity is that the hash of what is received from the client matches this hash in the password file.

                                                         ______
                                   request              /  pw  |
                                   packet  +--+         | file |
                                           |  |         +------+  
                                           |  |             |     
                                      +-+  |  |   +-+       | 
                                      |/|  |  |   |/|    +-----+    +-----+
user-name   ------------------------->|/| ======> |/|--->| SEL |--->| ==? |---> Y/N
                                      |/|  |  |   |/|    +-----+    +-----+
                                      +-+  |  |   +-+                  ^
                                           |  |                        |
                                      +-+  |  |   +-+                  |
                +-----+    +-----+    |/|  |  |   |/|    +-----+    +----+
user-passwd --->| MD5 |--->| ENC |--->|/| ======> |/|--->| ENC |--->| MD5 |
                +-----+    +-----+    |/|  |  |   |/|    +-----+    +----+
                             ^ ^      + +  |  |   +-+      ^ ^
                             | |           |  |            | |
                shared-key --+ |      +-+  |  |   +-+      | +-- shared-key
                               |      |/|  |  |   |/|      |
auth request    ---------------+----->|/| ======> |/|------+
                                      |/|  |  |   |/|
                                      +-+  |  |   +-+
                                           |  |
   MD5 - hash function                     |  |   the request packet includes user-name,
   ENC - encryption                        +--+   encrypted user-passd, auth request
   SEL - select pw by username                    chosen randomly, and the header: code,
                                                  ID and length.

MAC Calculation

  
            +-+  |  |   +-+     +-------+    +-+     |  |   +-+   
    ACC_REQ |/|  |  |   |/|     | Auth  |    |/|     |  |   |/| ACC_ACE/ACC_REJ
         Id |/| ======> |/|     | Dec-  |    |/|---+------->|/| Id
     Length |/|  |  |   |/|     | ision |    |/|   | |  |   |/| Length
            +-+  |  |   +-+     +-------+    +-+   | |  |   +-+
                 |  |                              | |  |
                 |  |              +---------------+ |  | 
            +-+  |  |              |   ++            |  |   +-+
            | |  |  |              |   | \           |  |   | |
    Request | |  |  |     128      +-->|  \   128    |  |   | | Response
  Authenti. | | ==========/===========>|MD5\ ==/===========>| | Authenticator
            | |  |  |         +------->|   /         |  |   | |
            | |  |  |         |        |  /          |  |   | | 
            +-+  |  |  +------------+  | /           |  |   +-+
                 |  |  | shared key |  ++
   +----------+  |  |  +------------+
   | username | -------------------------> attributes
   +----------+  |  |                      in 
   +----------+  |  |                      any
   | pw (enc) | -------------------------> order
   +----------+  |  |

The Attributes

Requests from client to server and responses from server to client can carry additional information in the sequence of attributes following the fixed format of the beginning of the packet. In our case, the request includes the user-name and password attribute, and the response carries no attributes.

The attributes have a common format, and can occur in any order. In our implementation the type will be either 1 for username or 2 for password.

    0                   1                   2
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
   |     Type      |    Length     |  String ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Refer to the RFC for more information. But I note,
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

Author: Burton Rosenberg
Created: 28 March 2017
Last Update: 3 April 2023