COMMAND

    MySQL

SYSTEMS AFFECTED

    All versions are vulnerable on all platforms.

PROBLEM

    Robert van der Meulen found following.  Below you find a  security
    advisory  Robert  wrote  concerning  a  vulnerability found in all
    mysql server versions, including the latest one.

    There exists a vulnerability in the password checking routines  in
    the latest versions of the  MySQL server, that allows any  user on
    a host that is allowed to connect to the server, to skip  password
    authentication, and access databases.  For the exploit to work,  a
    valid username for the mysql  server is needed, and this  username
    must have access to the database server, when connecting from  the
    attacking host.

    A  snippet  of  code  from  the  mysql  code,  explaining password
    authentication:

        >From mysql-3.22.26a/sql/password.c:
        /* password checking routines */
        /*****************************************************************************
          The main idea is that no password are sent between client & server on
          connection and that no password are saved in mysql in a decodable form.

          On connection a random string is generated and sent to the client.
          The client generates a new string with a random generator inited with
          the hash values from the password and the sent string.
          This 'check' string is sent to the server where it is compared with
          a string generated from the stored hash_value of the password and the
          random string.

        <cut>
        *****************************************************************************/

    The problem is, that in the comparison between the 'check' string,
    and the string generated from  the hash_value of the password  and
    the   random   string,   the   following   code   is   used  (from
    mysql-3.22.26a/sql/password.c):

          while (*scrambled)
          {
            if (*scrambled++ != (char) (*to++ ^ extra))
              return 1;                                 /* Wrong password */
          }

    'scrambled'  represents  the  'check'  value,  and (*to++ ^ extra)
    walks  trough  the  hash_value.   Suppose  a  client  would send a
    _single_  character  to  the  server  as  the  'check' string.  Of
    course the server should notice  the check string is not  the same
    length as  the check  string needed,  and give  a password  error.
    Because no such checks are done,  when a check string of length  1
    is passed to the server, only  one character is compared.  So  the
    only thing that remains  to know if we  want to peek in  someone's
    MySQL database, is a technique to find out the first character  of
    the server-side check string.

    The string that's used for the comparison is generated using  some
    random data, so  two following authenticate-actions  will probably
    use  different  check-strings.   After  looking  at the algorithm,
    generating  the  check  string,  it  becomes  clear that there are
    actually only 32 possibilities  for each character.   In practice,
    this means that  if you connect,  sending one single  character as
    the check string, you will be in in about 32 tries maximum.

    Hosts  in  the  access  list  (by  default  any  host, on a lot of
    distributions  and  servers)  can  connect  to  the  MySQL server,
    without a password, and access (often sensitive) data _as long  as
    the attacker has a valid username for the database server_.   This
    vulnerability  also  incorporates  a  MySQL  DoS  attack,  as  the
    attacker can  shutdown database  servers and  delete data,  if she
    logs in with the MySQL management account.

    Robert has an  exploit available, but  to defer script  kiddies he
    will not release it (yet).  If above explanation is understood, an
    exploit should be easy enough...

SOLUTION

    The official patch to fix this follows:

    *** /my/monty/master/mysql-3.23.10-alpha/sql/sql_parse.cc	Sun Jan 30 10:42:42 2000
    --- ./sql_parse.cc	Wed Feb  9 16:05:49 2000
    ***************
    *** 17,22 ****
    --- 17,24 ----
      #include <m_ctype.h>
      #include <thr_alarm.h>

    + #define SCRAMBLE_LENGTH 8
    +
      extern int yyparse(void);
      extern "C" pthread_mutex_t THR_LOCK_keycache;

    ***************
    *** 188,195 ****
          end=strmov(buff,server_version)+1;
          int4store((uchar*) end,thd->thread_id);
          end+=4;
    !     memcpy(end,thd->scramble,9);
    !     end+=9;
      #ifdef HAVE_COMPRESS
          client_flags |= CLIENT_COMPRESS;
      #endif /* HAVE_COMPRESS */
    --- 190,197 ----
          end=strmov(buff,server_version)+1;
          int4store((uchar*) end,thd->thread_id);
          end+=4;
    !     memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1);
    !     end+=SCRAMBLE_LENGTH +1;
      #ifdef HAVE_COMPRESS
          client_flags |= CLIENT_COMPRESS;
      #endif /* HAVE_COMPRESS */
    ***************
    *** 268,273 ****
    --- 270,277 ----
        char *user=   (char*) net->read_pos+5;
        char *passwd= strend(user)+1;
        char *db=0;
    +   if (passwd[0] && strlen(passwd) != SCRAMBLE_LENGTH)
    +     return ER_HANDSHAKE_ERROR;
        if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
          db=strend(passwd)+1;
        if (thd->client_capabilities & CLIENT_INTERACTIVE)

    MySQL 3.22.32 fixes a couple  of possible security holes in  MySQL
    3.22 including this one.  3.23.x is also out.

    For FreeBSD do one of the following:

        1) Upgrade  your  entire  ports  collection  and  rebuild  the
           mysql322-server port.
        2) Reinstall a new package obtained from:
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-3-stable/databases/mysql-server-3.22.32.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-current/databases/mysql-server-3.22.32.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-4-current/databases/mysql-server-3.22.32.tgz
        3) download a  new port skeleton  for the mysql322-server  port
           from:
           http://www.freebsd.org/ports/
           and use it to rebuild the port.
        4) Use the portcheckout utility to automate option (3)  above.
           The     portcheckout     port      is     available      in
           /usr/ports/devel/portcheckout  or   the  package   can   be
           obtained from:
           ftp://ftp.freebsd.org/pub/FreeBSD/ports/packages/devel/portcheckout-2.0.tgz

    For Turbo Linux see:

        rpm -Fv ftp://ftp.turbolinux.com/pub/updates/6.0/security/MySQL-3.22.32-1.i386.rpm

    The source rpm can be downloaded here:

        ftp://ftp.turbolinux.com/pub/updates/6.0/SRPMS/MySQL-3.22.32-1.src.rpm

    Note:  You  must  rebuild  and  install  the  rpm if you choose to
    download and install the srpm.   Simply installing the srpm  alone
    WILL NOT CLOSE THE SECURITY HOLE.