TRENDnet 无线摄像头 TV-IP512WN 栈溢出漏洞分析

阅读量225269

|

发布时间 : 2021-01-14 15:00:41

x
译文声明

本文是翻译文章,文章原作者 payatu,文章来源:payatu.com

原文地址:https://payatu.com/blog/munawwar/trendNet-wireless-camera-buffer-overflow-vulnerability

译文仅供参考,具体内容表达以及含义原文为准。

 

CVE ID: CVE-2020-12763

漏洞描述

TRENDnet(趋势网络) ProView Wireless camera TV-IP512WN 1.0R 1.0.4 版本中的 RTSP 数据包在处理过程存在缓冲区溢出漏洞。攻击者可利用该漏洞执行代码或导致拒绝服务。漏洞发生在 /sbin 目录下的二进制文件 rtspd 中,该文件主要负责处理设备接收到的 RTSP 连接。当文件在解析 RTSP header 的 “Authorization: Basic” 字段时,由于字段内容的长度不确定,程序又没有对拷贝到栈上的内容长度进行检查限制,因此可能会导致缓冲区溢出,更严重的是该漏洞无需登录授权便可以触发。

在探讨技术细节前请注意以下几点:

1、漏洞是在该型号产品最新版本的固件中发现的。
2、漏洞已经上报厂商 TRENDnet。
3、TRENDnet 认为该产品已停产,所以拒绝漏洞验证。

 

漏洞产品

厂商: TRENDnet
影响产品:ProView Wireless N Network Camera TV-IP512WN (Version v1.0R)
固件:FW_TV-IP512P_512WN(1.0.4).zip
SHA-1:B27998BBB4C8503E9314730F504E389B56AD6F6C
产品链接:https://www.trendnet.com/support/support-detail.asp?prod=175_TV-IP512WN

 

产品图片

 

固件详情

 

漏洞分析

需要澄清的一点是,受新冠疫情影响,我很难买到这次分析用的无线摄像头设备,也就无法实际触发该漏洞,所以我是通过静态分析发现的这个漏洞。为方便读者理解,我会把反编译后的代码截图放到文章里,并对大部分函数和变量进行了重命名。

这次漏洞是典型的 CWE-120 栈溢出错误,错误可被利用于远程执行代码(RCE)或拒绝服务(DOS)攻击。溢出发生在 sbin 目录下的二进制文件 rtspd,该文件主要负责处理设备接收到的 RTSP 连接请求。

函数 parse_auth_header(address 0x11a18)解析 Authorization: Basic header 的时候会发生栈溢出,函数被调用时传入两个缓冲区参数,第一个存放 RTSP header,第二个用来存放解析后获得的 header 值,下图为反编译后的函数代码。

图 A:校验头解析函数 parse_auth_header 反汇编代码

我们来试着理解下这个函数:

  1. 1、如上图代码所示,10-17 行是一个循环,从缓冲区第一个字符开始搜索 header 字符串 “Authorization: Basic”,如果找到就断开循环,然后将指针 src_buf_ptr 前移 0x15 个字节(长度刚好指向 header 值的内容)。
    2、调用 strstr 函数查找换行符 “\r\n”,返回一个 char 指针 newline_ptr。
    3、将前面两个指针相减,获得的差值便是 Authorization: Basic header 值的长度。
    4、函数 memcpy 把 src_buf_ptr 指针指向的 header 值内容拷贝到缓冲区 dest_buf 里面,程序执行到这一步时可能会发生溢出错误,因为程序没有检查 dest_buf 的长度是否足够容纳 header 值的内容,如果内容过长的话就会导致 dest_buf 缓冲区溢出,接下来我会证明这一点。

先来看下传给函数的参数是什么。
将地址为 0x11ae8 的函数重命名为 check_authentication,函数中调用了parse_auth_header 函数,请看下图的反汇编代码。

图 B:check_authentication 函数反汇编代码

可以看到,parse_auth_header 是在第 35 行被调用的,第一个参数来自调用函数check_authentication 的最后一个指针参数 param_4(此处原文作者描述和所给图片有出入,所以稍有修改),第二个参数是一个 char 型指针,指向的缓冲区大小为 64,希望你能明白这里的问题所在:

传入 parse_auth_header 的第二个缓冲区参数大小是固定的(64 个字节),而当函数拷贝数据时又没有校验数据长度是否在缓冲区大小范围内。

发现这个问题并不难,但我们怎么知道函数处理的数据是来自 socket 呢?问得好,先找到调用 check_authentication 的函数,重命名为 is_client_authenticated,下图为反汇编后的函数代码:

图 C:函数 is_client_authenticated 的反汇编代码

check_authentication 函数在第 23 行被调用,根据其返回值,程序会判断下一行的 if 代码块是否执行。if 代码块(24-35 行)除了在控制台输出文件名和函数名,还会将一行拼接有 RTSP/1.0 401 Unauthorized 内容的字符串作为 send 函数的参数,而 send 函数用于向 socket 写入数据,这就证明了之前的一系列函数是在做权限校验工作,如果 Authorization Basic header 内容过长的话,就会触发溢出漏洞。

继续探究,找到所有 is_client_authencticate 函数的调用,这能帮助我们更好地了解程序何时进行权限校验,请看下面的函数调用情况:

图 D

图 E

图 F

图 G

图 H

图 I

如上图代码所示,当触发摄像头的暂停,设置,播放,拆分等功能时,程序就会调用函数 is_client_authencticate,以检查收到的功能请求授权是否合法,返回值为 0 表示校验通过,然后实现功能,否则程序直接返回。

这篇 维基百科 介绍了 RTSP 的协议格式,进一步印证了上面我们看到的图 D – 图 I 中的各个功能。

另外需要注意的一点是,由于这个 bug 是在解析 Authorization header 时触发的,也就意味着无需授权就能够执行 RCE,这在很大程度上加剧了漏洞的严重性。

 

结论

我们看到了数据包解析代码里一个小小的 bug 就能导致缓冲区溢出,也见识了攻击者是怎样绕过权限校验触发漏洞的,虽然还没法写出一个行之有效的 PoC 来证明 RCE ,但是我会在文章第二部分试着搭建 qemu 环境,模拟运行二进制文件,通过创建远程 socket 连接的方式实现 RCE,触发漏洞,然后大功告成!

From 新概念研究中心

本文翻译自payatu.com 原文链接。如若转载请注明出处。
分享到:微信
+10赞
收藏
自由在高处
分享到:微信

发表评论

Copyright © 北京奇虎科技有限公司 三六零数字安全科技集团有限公司 安全KER All Rights Reserved 京ICP备08010314号-66