[UNIX] MySQL Authentication Scheme Bypass

From: SecuriTeam (support_at_securiteam.com)
Date: 07/07/04

  • Next message: SecuriTeam: "[UNIX] Content-Type XSS Vulnerability in Multiple Webmail Programs"
    To: list@securiteam.com
    Date: 7 Jul 2004 16:18:09 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.
    http://www.securiteam.com/mailinglist.html

    - - - - - - - - -

      MySQL Authentication Scheme Bypass
    ------------------------------------------------------------------------

    SUMMARY

    The <http://www.mysql.com> MySQL "database server is the world's most
    popular open source database". A bug allows a remote user to authenticate
    and get access to the database completely bypassing the normal
    authentication mechanism and without providing the DB user's password.

    DETAILS

    Vulnerable Systems:
     * MySQL version 4.1 and prior

    Immune Systems:
     * MySQL versions 4.1.3 and 5.0

    By submitting a carefully crafted authentication packet, it is possible
    for an attacker to bypass the password authentication mechanism. From
    check_connection (sql_parse.cpp), line ~837:
     /*
        Old clients send null-terminated string as password; new clients send
        the size (1 byte) + string (not null-terminated). Hence in case of
    empty
        password both send '\0'.
      */
      uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
        *passwd++ : strlen(passwd);

    Provided 0x8000 is specified in the client capabilities flags, the use can
    specify the passwd_len field of their choice. For this attack, 14h (20)
    bytes will be chosen, the length of a SHA-1 hash string. Several checks
    are now carried out to ensure that the user is authenticating from a host
    that is permitted to connect. Provided these checks are passed, the
    following code is executed:
     /* check password: it should be empty or valid */
            if (passwd_len == acl_user_tmp->salt_len)
            {
              if (acl_user_tmp->salt_len == 0 ||
                  acl_user_tmp->salt_len == SCRAMBLE_LENGTH &&
                  check_scramble(passwd, thd->scramble, acl_user_tmp->salt) ==
    0 ||
                  check_scramble_323(passwd, thd->scramble,
                                     (ulong *) acl_user_tmp->salt) == 0)
              {
                acl_user= acl_user_tmp;
                res= 0;
              }
            }

    The check_scramble function fails, but within the check_scramble_323()
    function we see:
    my_bool
    check_scramble_323(const char *scrambled, const char *message,
                       ulong *hash_pass)
    {
      struct rand_struct rand_st;
      ulong hash_message[2];
      char buff[16],*to,extra; /* Big enough for check */
      const char *pos;

      hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
      randominit(&rand_st,hash_pass[0] ^ hash_message[0],
                 hash_pass[1] ^ hash_message[1]);
      to=buff;
      for (pos=scrambled ; *pos ; pos++)
        *to++=(char) (floor(my_rnd(&rand_st)*31)+64);
      extra=(char) (floor(my_rnd(&rand_st)*31));
      to=buff;
      while (*scrambled)
      {
        if (*scrambled++ != (char) (*to++ ^ extra))
          return 1; /* Wrong password */
      }
      return 0;
    }

    At this point, the user has specified a 'scrambled' string that is as long
    as they wish. In the case of the straightforward authentication bypass,
    this is a zero-length string. The final loop compares each character in
    the 'scrambled' string against the string that mysql knows is the correct
    response, until there are no more characters in 'scrambled'. Since there
    are no characters *at all* in 'scrambled', the function returns '0'
    immediately, allowing the user to authenticate with a zero-length string.

    In addition to the zero-length string authentication bypass, the
    stack-based buffer 'buff' can be overflowed by a long 'scramble' string.
    The buffer is overflowed with characters output from my_rnd(), a pseudo
    random number generator. The characters are in the range 0x40..0x5f. On
    some platforms, arbitrary code execution is possible, though the exploit
    is complex and requires either brute force, or knowledge of at least one
    password hash.

    Vendor Status:
    MySQL AB were contacted on June 1st and a patch in the source code was
    available on June 2nd. Upgrade to the newer versions of MySQL in order to
    mitigate this vulnerability.

    Since the attack requires the attacker to know at least the username of
    the user to authenticate as, changing the default names of the users might
    be a simple workaroun. In addition, any access retrictions on connections
    (such as IP addresses) can be applied since the attacker has to be able to
    access the account in question from the attacking host.

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:nisr@nextgenss.com>
    NGSSoftware Insight Security Research.

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[UNIX] Content-Type XSS Vulnerability in Multiple Webmail Programs"

    Relevant Pages