libupnp多个缓冲区溢出漏洞 | ZeroBox Vulnerability Database

libupnp多个缓冲区溢出漏洞

受影响系统:

sourceforge libupnp

描述:


BUGTRAQ  ID: 57602
CVE(CAN) ID: CVE-2012-5958,CVE-2012-5959,CVE-2012-5960,CVE-2012-5961,CVE-2012-5962,CVE-2012-5963,CVE-2012-5964,CVE-2012-5965

libupnp是UPnP设备可移植的SDK,提供了API和开源代码。

libupnp 1.6.18之前版本SSDP解析模块中的unique_service_name函数没有对数据执行正确的边界检查而存在多个缓冲区溢出漏洞,攻击者可利用这些漏洞在受影响设备内执行任意代码。

<*来源:HD Moore

链接:https://community.rapid7.com/docs/DOC-2150
*>

测试方法:


警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

metasploit提供了以下漏洞信息及测试方法

————————————
问题代码
————————————

// version 1.3.1 of the Portable SDK for UPnP Devices
// upnp/src/ssdp/ssdp_server.c
// cmd变量接收外部输入
// 结构体Evt包含多个固定长度的缓冲区
int unique_service_name( IN char *cmd, IN SsdpEvent * Evt ) {
char *TempPtr, TempBuf[COMMAND_LEN], *Ptr, *ptr1, *ptr2, *ptr3;
int CommandFound = 0;
if( ( TempPtr = strstr( cmd, “uuid:schemas” ) ) != NULL )
{
ptr1 = strstr( cmd, “:device” );
if( ptr1 != NULL ) {
ptr2 = strstr( ptr1 + 1, “:” );
} else {
return -1;
}
if( ptr2 != NULL ) {
ptr3 = strstr( ptr2 + 1, “:” );
} else {
return -1;
} if( ptr3 != NULL ) {
sprintf( Evt->UDN, “uuid:%s”, ptr3 + 1 );         // CVE-2012-5961
} else {
return -1;
}
ptr1 = strstr( cmd, “:” );
if( ptr1 != NULL ) {
strncpy( TempBuf, ptr1, ptr3 – ptr1 );             // CVE-2012-5958
TempBuf[ptr3 – ptr1] = ‘\0’;
sprintf( Evt->DeviceType, “urn%s”, TempBuf );     // CVE-2012-5962
} else {
return -1;
}
return 0;
}
if( ( TempPtr = strstr( cmd, “uuid” ) ) != NULL )
{
//printf(“cmd = %s\n”,cmd);
if( ( Ptr = strstr( cmd, “::” ) ) != NULL ) {
strncpy( Evt->UDN, TempPtr, Ptr – TempPtr );     // CVE-2012-5959
Evt->UDN[Ptr – TempPtr] = ‘\0’;
} else {
strcpy( Evt->UDN, TempPtr );                     // CVE-2012-5963
}
CommandFound = 1;
}
if( strstr( cmd, “urn:” ) != NULL && strstr( cmd, “:service:” ) != NULL ) {
if( ( TempPtr = strstr( cmd, “urn” ) ) != NULL ) {
strcpy( Evt->ServiceType, TempPtr );             // CVE-2012-5964
CommandFound = 1;
}
}
if( strstr( cmd, “urn:” ) != NULL && strstr( cmd, “:device:” ) != NULL ) {
if( ( TempPtr = strstr( cmd, “urn” ) ) != NULL )
{
strcpy( Evt->DeviceType, TempPtr );             // CVE-2012-5965
CommandFound = 1;
}
}
if( CommandFound == 0 )
{
return -1;
}
return 0;
}

// version 1.6.17
// cmd变量接收外部输入
// 结构体Evt包含多个固定长度的缓冲区
int unique_service_name(char *cmd, SsdpEvent *Evt)
{
char TempBuf[COMMAND_LEN];
char *TempPtr = NULL;
char *Ptr = NULL;
char *ptr1 = NULL;
char *ptr2 = NULL;
char *ptr3 = NULL;
int CommandFound = 0;
size_t n = (size_t)0;
if (strstr(cmd, “uuid:schemas”) != NULL)
{
ptr1 = strstr(cmd, “:device”);
if (ptr1 != NULL)
ptr2 = strstr(ptr1 + 1, “:”);
else
return -1;
if (ptr2 != NULL)
ptr3 = strstr(ptr2 + 1, “:”);
else
return -1;
if (ptr3 != NULL)
{
if (strlen(“uuid:”) + strlen(ptr3 + 1) >= sizeof(Evt->UDN))
return -1;
snprintf(Evt->UDN, sizeof(Evt->UDN), “uuid:%s”, ptr3 + 1);
}
else
return -1;
ptr1 = strstr(cmd, “:”);
if (ptr1 != NULL)
{
n = (size_t)ptr3 – (size_t)ptr1;
strncpy(TempBuf, ptr1, n);                             // CVE-2012-5958
TempBuf[n] = ‘\0’;
if (strlen(“urn”) + strlen(TempBuf) >= sizeof(Evt->DeviceType))
return -1;
snprintf(Evt->DeviceType, sizeof(Evt->DeviceType), “urn%s”, TempBuf);
}
else
return -1;
return 0;
}
if ((TempPtr = strstr(cmd, “uuid”)) != NULL)
{
if ((Ptr = strstr(cmd, “::”)) != NULL)
{
n = (size_t)Ptr – (size_t)TempPtr;
strncpy(Evt->UDN, TempPtr, n);                         // CVE-2012-5959
Evt->UDN[n] = ‘\0’;
}
else
{
memset(Evt->UDN, 0, sizeof(Evt->UDN));
strncpy(Evt->UDN, TempPtr, sizeof(Evt->UDN) – 1);
}
CommandFound = 1;
}
if (strstr(cmd, “urn:”) != NULL && strstr(cmd, “:service:”) != NULL)
{
if ((TempPtr = strstr(cmd, “urn”)) != NULL)
{
memset(Evt->ServiceType, 0, sizeof(Evt->ServiceType));
strncpy(Evt->ServiceType, TempPtr, sizeof(Evt->ServiceType) – 1);
CommandFound = 1;
}
}
if (strstr(cmd, “urn:”) != NULL && strstr(cmd, “:device:”) != NULL)
{
if ((TempPtr = strstr(cmd, “urn”)) != NULL)
{
memset(Evt->DeviceType, 0, sizeof(Evt->DeviceType));
strncpy(Evt->DeviceType, TempPtr, sizeof(Evt->DeviceType) – 1);
CommandFound = 1;
}
}
if ((TempPtr = strstr(cmd, “::upnp:rootdevice”)) != NULL)
{
/* Everything before “::upnp::rootdevice” is the UDN. */
if (TempPtr != cmd)
{
n = (size_t)TempPtr – (size_t)cmd;
strncpy(Evt->UDN, cmd, n);                             // CVE-2012-5960
Evt->UDN[n] = 0;
CommandFound = 1;
}
}
if (CommandFound == 0)
return -1;
return 0;
}

————————————
POC of CVE-2012-5958
可发送下述请求包触发CVE-2012-5958
————————————

M-SEARCH * HTTP/1.1
Host:239.255.255.250:1900
ST:uuid:schemas:device:AAAA[…]AAAA:anything
Man:”ssdp:discover”
MX:3

建议:


厂商补丁:

sourceforge
———–
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://pupnp.sourceforge.net/