基于libupnp的upnp安全
字数 1643 2025-08-06 20:12:41

基于libupnp的UPnP协议安全分析

0x00 UPnP协议概述

协议栈

UPnP(Universal Plug and Play)即插即用协议,设计目的是让设备接入网络后能自动发现并相互通信。基于TCP/UDP和HTTP协议,协议栈如下:

  1. 底层:IP、TCP、UDP
  2. 传输层:HTTPU(基于UDP的HTTP)、HTTPMU(组播HTTP)、HTTP(常规HTTP)
  3. 协议层:SSDP(简单服务发现协议)、SOAP(简单对象访问协议)、GENA(通用事件通知架构)
  4. 描述层:XML格式的设备和服务描述

libupnp在传统UPnP实现基础上集成了HTTP处理、XML处理、HTTP服务器、SSDP处理等功能。

关键标识

  1. UUID:通用唯一识别码,格式为8-4-4-16的十六进制数
  2. UDN:单一设备名,基于UUID,表示一个设备
  3. URN:统一资源名称,唯一标识实体但不提供位置信息
  4. Mx:1-5之间的值,表示最大等待应答秒数
  5. ST:Search Target,表示搜索的节点类型

SSDP协议

SSDP(简单服务发现协议)是UPnP的发现协议,设备加入网络时会发送广播包:

M-SEARCH * HTTP/1.1  
Host: 239.255.255.250:1900  
MAN: "ssdp:discover"  
MX: 10  
ST: ssdp:all

响应包示例:

HTTP/1.1 200 OK
CACHE-CONTROL: max-age=120
ST: uuid:75802409-bccb-40e7-8e6c-40a5ef100e92
USN: uuid:75802409-bccb-40e7-8e6c-40a5ef100e92
LOCATION: http://192.168.100.1:24795/rootDesc.xml
...

SCPD描述

LOCATION字段指向的XML文件描述设备信息,包含:

  • 设备类型、友好名称、制造商信息
  • 服务列表(serviceList):
    • serviceType:服务类型
    • SCPDURL:服务描述文件
    • controlURL:控制URL
    • eventSubURL:事件订阅URL

SOAP控制

基于TCP的XML格式控制协议,请求示例:

POST /control/url HTTP/1.1
CONTENT-TYPE: text/xml;charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:serviceType:v#actionName"

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <u:actionName xmlns:u="urn:schemas-upnp-org:service:serviceType:v">
           <argumentName>in arg value</argumentName>
        </u:actionName>
    </s:Body>
</s:Envelope>

GENA订阅&事件

订阅请求格式:

SUBSCRIBE publisher_path HTTP/1.1
HOST: publisherhost:publisher_port
CALLBACK: <deliveryURL>
NT: upnp:event

事件通知格式:

NOTIFY delivery_path HTTP/1.1
NT: upnp:event
NTS: upnp:propchange
SID: uuid:subscription-UUID
...

0x01 攻击面分析

常见漏洞类型

  1. 数据包处理漏洞

    • 边界检查不严格导致缓冲区溢出
    • 如CVE-2012-5958在strncpy时长度计算错误
  2. 变量过滤不严格

    • 直接传入system等危险函数导致命令注入
    • 如CVE-2017-17215、CVE-2020-15893
  3. XML解析问题

    • XML递归错误
    • XXE注入
  4. 信息泄露和越权控制

    • 缺乏身份验证机制
    • 任意设备可控制网络中的所有UPnP设备

libupnp漏洞分析

CVE-2016-6255

  • 影响版本:libupnp < 1.6.21
  • 漏洞描述:通过未注册处理程序的POST请求实现任意文件写入
  • 漏洞位置:webserver回调函数中的文件处理逻辑
  • 修复方式:添加全局宏限制POST操作权限

CVE-2016-8863

  • 影响版本:libupnp < 1.6.21
  • 漏洞描述:gena_device.c中create_url_list函数的堆溢出
  • 触发方式:发送包含无效URI的SUBSCRIBE请求
  • 漏洞原理:URL计数与分配空间不一致导致越界写入

其他UPnP实现漏洞

CVE-2020-9373

  • 影响设备:Netgear R6400等
  • 漏洞类型:SSDP处理中的栈溢出
  • 漏洞位置:strcpy到固定大小缓冲区
  • 利用方式:构造超长SSDP请求触发溢出

CVE-2021-27239

  • 影响设备:Netgear设备
  • 漏洞类型:MX头处理中的缓冲区溢出
  • 漏洞原理:strncpy长度参数可控

0x02 安全建议

  1. 及时更新libupnp到最新版本
  2. 对UPnP服务进行严格的输入验证
  3. 避免在UPnP服务中使用危险函数(system等)
  4. 在网络边界禁用UPnP服务
  5. 实施最小权限原则,限制UPnP服务的文件系统访问

0x03 测试工具

  1. Miranda:轻量级UPnP测试工具
  2. CallStranger:测试CVE-2020-12695漏洞
  3. upnpclient:Python3 UPnP通信客户端
  4. 自定义Python脚本:模拟SSDP发现和SOAP请求

示例发现脚本:

import socket

ANY = "0.0.0.0"
DES_IP = "239.255.255.250"
PORT = 1900
xml_str = b'M-SEARCH * HTTP/1.0\r\n' \
    + b'HOST: 239.255.255.250:1900\r\n' \
    + b'MAN: "ssdp:discover"\r\n' \
    + b'MX: 3\r\n' \
    + b'ST: ssdp:all\r\n\r\n'

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ANY, PORT))
s.sendto(xml_str, (DES_IP, PORT))
while True:
    try:
        data, address = s.recvfrom(2048)
        print(address, data)
    except:
        pass

0x04 参考资源

  1. UPnP协议官方文档
  2. libupnp源码和漏洞公告
  3. 设备厂商安全公告
  4. 漏洞利用数据库(Exploit-DB)
  5. 相关技术博客和分析文章
基于libupnp的UPnP协议安全分析 0x00 UPnP协议概述 协议栈 UPnP(Universal Plug and Play)即插即用协议,设计目的是让设备接入网络后能自动发现并相互通信。基于TCP/UDP和HTTP协议,协议栈如下: 底层:IP、TCP、UDP 传输层:HTTPU(基于UDP的HTTP)、HTTPMU(组播HTTP)、HTTP(常规HTTP) 协议层:SSDP(简单服务发现协议)、SOAP(简单对象访问协议)、GENA(通用事件通知架构) 描述层:XML格式的设备和服务描述 libupnp在传统UPnP实现基础上集成了HTTP处理、XML处理、HTTP服务器、SSDP处理等功能。 关键标识 UUID :通用唯一识别码,格式为8-4-4-16的十六进制数 UDN :单一设备名,基于UUID,表示一个设备 URN :统一资源名称,唯一标识实体但不提供位置信息 Mx :1-5之间的值,表示最大等待应答秒数 ST :Search Target,表示搜索的节点类型 SSDP协议 SSDP(简单服务发现协议)是UPnP的发现协议,设备加入网络时会发送广播包: 响应包示例: SCPD描述 LOCATION字段指向的XML文件描述设备信息,包含: 设备类型、友好名称、制造商信息 服务列表(serviceList): serviceType:服务类型 SCPDURL:服务描述文件 controlURL:控制URL eventSubURL:事件订阅URL SOAP控制 基于TCP的XML格式控制协议,请求示例: GENA订阅&事件 订阅请求格式: 事件通知格式: 0x01 攻击面分析 常见漏洞类型 数据包处理漏洞 : 边界检查不严格导致缓冲区溢出 如CVE-2012-5958在strncpy时长度计算错误 变量过滤不严格 : 直接传入system等危险函数导致命令注入 如CVE-2017-17215、CVE-2020-15893 XML解析问题 : XML递归错误 XXE注入 信息泄露和越权控制 : 缺乏身份验证机制 任意设备可控制网络中的所有UPnP设备 libupnp漏洞分析 CVE-2016-6255 影响版本:libupnp < 1.6.21 漏洞描述:通过未注册处理程序的POST请求实现任意文件写入 漏洞位置:webserver回调函数中的文件处理逻辑 修复方式:添加全局宏限制POST操作权限 CVE-2016-8863 影响版本:libupnp < 1.6.21 漏洞描述:gena_ device.c中create_ url_ list函数的堆溢出 触发方式:发送包含无效URI的SUBSCRIBE请求 漏洞原理:URL计数与分配空间不一致导致越界写入 其他UPnP实现漏洞 CVE-2020-9373 影响设备:Netgear R6400等 漏洞类型:SSDP处理中的栈溢出 漏洞位置:strcpy到固定大小缓冲区 利用方式:构造超长SSDP请求触发溢出 CVE-2021-27239 影响设备:Netgear设备 漏洞类型:MX头处理中的缓冲区溢出 漏洞原理:strncpy长度参数可控 0x02 安全建议 及时更新libupnp到最新版本 对UPnP服务进行严格的输入验证 避免在UPnP服务中使用危险函数(system等) 在网络边界禁用UPnP服务 实施最小权限原则,限制UPnP服务的文件系统访问 0x03 测试工具 Miranda :轻量级UPnP测试工具 CallStranger :测试CVE-2020-12695漏洞 upnpclient :Python3 UPnP通信客户端 自定义Python脚本:模拟SSDP发现和SOAP请求 示例发现脚本: 0x04 参考资源 UPnP协议官方文档 libupnp源码和漏洞公告 设备厂商安全公告 漏洞利用数据库(Exploit-DB) 相关技术博客和分析文章