10670355 2003-09-10 23:29 +0159 /170 rader/ Jedi/Sector One <j@c9x.org>
Importerad: 2003-09-11 01:18 av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <28952>
Ärende: Buffer overflow in MySQL
------------------------------------------------------------
From: Jedi/Sector One <j@c9x.org>
To: bugtraq@securityfocus.com
Message-ID: <20030910213018.GA5167@c9x.org>


Product : MySQL
Date    : 10/09/2003
Author  : Frank Denis <j@pureftpd.org>


   ------------------------[ Product description ]------------------------

  From the web site :

  MySQL is the world's most popular open source database, recognized
for its speed and reliability.

  Today MySQL is the most popular open source database server in the
world with more than 4 million installations powering websites,
datawarehouses, business applications, logging systems and more.

  Home page : http://www.mysql.com/


      ------------------------[ Vulnerability ]------------------------

  Passwords of MySQL users are stored in the "User" table, part of
the "mysql" database, specifically in the "Password" field.

  In MySQL 4.0.x and 3.23.x, these passwords are hashed and stored as
a 16 characters long hexadecimal value, specifically in the
"Password" field.

  Unfortunately, a function involved in password checking misses
correct bounds checking. By filling a "Password" field a value wider
than 16 characters, a buffer overflow will occur.


      ------------------------[ Implications ]------------------------

  Anyone with global administrative privileges on a MySQL server may
execute arbitrary code even on a host he isn't supposed to have a
shell on, with the privileges of the system account running the MySQL
server.


	 ------------------------[ Details ]------------------------
	 
  The get_salt_from_password() function defined in sql/password.c
takes an arbitrary long hex password and returns an arbitrary long
binary array with the previous decoded values :

void get_salt_from_password(ulong *res,const char *password)
{
	res[0]=res[1]=0;
	if (password)
	{
		while (*password)
		{
			ulong val=0;
			uint i;
			for (i=0 ; i < 8 ; i++)
			val=(val << 4)+char_val(*password++);
			*res++=val;
		}
	}
	return;
}

  This function is called sql/sql_acl.cc to check for access control.
  
  It is passed the raw content of the Password field from the User
table of the mysql database.

  The process aborts if then length is not a multiple of 8 but this
is the only check before get_salt_from_password() is actually called.

  The overflow occurs on a local ACL_USER instance in acl_init() and
successful exploitation of that bug is trivial on some platforms. On
most Linux systems the return address needs about 444 bytes to get
overwritten.

  Harmless proof of concept :
  
  > USE mysql;
  > ALTER TABLE User CHANGE COLUMN Password Password LONGTEXT;
  > UPDATE User SET Password =
'123456781234567812345678123456781234567812345678123456781234567812345678
 123456781234567812345678123456781234567812345678123456781234567812345678
 123456781234567812345678123456781234567812345678123456781234567812345678
 12345678123456781234567812345678...' WHERE User = 'abcd';
  > FLUSH PRIVILEGES;
  
  [Connection lost]
  
  mysqld_safe/safe_mysqld log :
  
030806 21:05:43  mysqld restarted
030806 21:05:43  mysqld restarted
030806 21:05:43  mysqld restarted
030806 21:05:43  mysqld restarted

  MySQL log : tons of

mysqld got signal 11; This could be because you hit a bug. It is also
possible that this binary or one of the libraries it was linked
against is corrupt, improperly built, or misconfigured. This error
can also be caused by malfunctioning hardware.  We will try our best
to scrape up some info that will hopefully help diagnose the problem,
but since we have already crashed, something is definitely wrong

  Confirmed on OpenBSD 3.3-RELEASE, FreeBSD 4.8-STABLE and Gentoo
Linux 1.4.


    ------------------------[ Affected versions ]------------------------
	 
  All versions of MySQL up to and including 4.0.14 are likely to be
vulnerable.

  All versions of MySQL up to and including 3.0.57 are also likely to
be affected.


       ------------------------[ Workarounds ]------------------------
	 
  None.
  
  But to mitigate the impact of this kind of vulnerability never let
the server run with "root" privileges. Create a dedicated user and
add the
--user=<dedicated user> command-line switch to start the daemon. Or edit
your "my.cnf" file to achieve similar results. There is no loss of
functionnality when the server runs without root privileges.


	   ------------------------[ Fix ]------------------------

  The following patch (applies fine to 4.0.14, should also work on
earlier releases with minor fuzz) fixes the bug :

--- mysql-4.0.14-old/sql/sql_acl.cc	2003-07-18 16:57:25.000000000
+0200
+++ mysql-4.0.14/sql/sql_acl.cc	2003-09-10 23:21:13.559759576 +0200
@@ -233,7 +233,7 @@
 		      "Found old style password for user '%s'. Ignoring user. (You may want to restart mysqld using --old-protocol)",
 		      user.user ? user.user : ""); /* purecov: tested */
     }
-    else if (length % 8)		// This holds true for passwords
+    else if (length % 8 || length > 16)		// This holds true for passwords
     {
       sql_print_error(
 		      "Found invalid password for user: '%s@%s'; Ignoring user",


      ------------------------[ Vendor status ]------------------------
	 
  MySQL AB has been informed of this vulnerability on Wed, 6 Aug 2003.
  
  The issue was confirmed and fixed in the developpment tree the next
day.
  
  [side note: the MySQL developpment team is not only very reactive,
the guys are also extremely nice]

  MySQL 4.0.15, which includes a fix for this vulnerability and other
unrelated bugs, is now available for download from the following
location :

  http://www.mysql.com/downloads/mysql-4.0.html


-- 
 __  /*-      Frank DENIS (Jedi/Sector One) <j@42-Networks.Com>     -*\  __
 \ '/    <a href="http://www.PureFTPd.Org/"> Secure FTP Server </a>    \' /
  \/  <a href="http://www.Jedi.Claranet.Fr/"> Misc. free software </a>  \/
(10670355) /Jedi/Sector One <j@c9x.org>/--(Ombruten)
Kommentar i text 10680251 av Konstantin Tsolov <ktsolov@etel.bg>
10680251 2003-09-11 13:41 +0300 /43 rader/ Konstantin Tsolov <ktsolov@etel.bg>
Importerad: 2003-09-13 00:43 av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <28988>
Kommentar till text 10670355 av Jedi/Sector One <j@c9x.org>
Ärende: Re: Buffer overflow in MySQL
------------------------------------------------------------
From: Konstantin Tsolov <ktsolov@etel.bg>
To: bugtraq@securityfocus.com
Message-ID: <200309111341.29638.ktsolov@etel.bg>


managed to replicate on 4.0.13 (custom made) running on slack8.1 with
mysql.mysql.

3.23.51 (the distro mysql version) also proved vulnerable.

nb: just make sure you have a backup copy of your mysql db when
testing this harmless proof of concept on your production server :-)

> successful exploitation of that bug is trivial on some platforms. On most
> Linux systems the return address needs about 444 bytes to get overwritten.
>
>   Harmless proof of concept :
>   > USE mysql;
>   > ALTER TABLE User CHANGE COLUMN Password Password LONGTEXT;
>   > UPDATE User SET Password =
>
> '123456781234567812345678123456781234567812345678123456781234567812345678
>  123456781234567812345678123456781234567812345678123456781234567812345678
>  123456781234567812345678123456781234567812345678123456781234567812345678
>  12345678123456781234567812345678...' WHERE User = 'abcd';
>
>   > FLUSH PRIVILEGES;
>
>   [Connection lost]

-- 

"Talk is cheap because supply always exceeds demand."
		-- source unknown

+------------------------------------------------------+
| Konstantin Tsolov             ktsolov at etel dot bg |
| Systems Administrator - VoIP                         |
| eTel Ltd.                                www.etel.bg |
| Sofia, Bulgaria                                      |
+------------------------------------------------------+
(10680251) /Konstantin Tsolov <ktsolov@etel.bg>/(Ombruten)