漏洞信息
CVE-2019-10999 是一个典型的栈溢出漏洞。根据公开披露的基础信息,攻击者在已登录的情况下,可以通过向设备的 wireless.htm 页面发送一个超长的 WEPEncryption 参数,导致目标函数发生栈溢出,进而执行任意命令。
本次分析选取存在该漏洞的 D-Link DCS-932L v2.17.01 版本设备作为目标。我们将通过固件解包、静态代码分析和动态调试复现该漏洞,并深入探讨其成因与防御机制。
本文针对 CVE-2019-10999 漏洞进行了详细分析与复现。该漏洞存在于 D-Link DCS-932L 设备的 web 服务器中,攻击者可通过发送超长 WEPEncryption 参数触发栈溢出。文章利用 Shambles Desktop 工具对固件进行静态代码分析,定位到 strcpy 函数处的风险,并通过动态调试模拟设备运行环境,验证了参数过长导致 pc 寄存器被篡改的过程。最后提出了输入验证、使用安全函数及开启保护机制等修复建议,旨在提升嵌入式设备的安全性。

CVE-2019-10999 是一个典型的栈溢出漏洞。根据公开披露的基础信息,攻击者在已登录的情况下,可以通过向设备的 wireless.htm 页面发送一个超长的 WEPEncryption 参数,导致目标函数发生栈溢出,进而执行任意命令。
本次分析选取存在该漏洞的 D-Link DCS-932L v2.17.01 版本设备作为目标。我们将通过固件解包、静态代码分析和动态调试复现该漏洞,并深入探讨其成因与防御机制。
首先使用 Shambles Desktop 工具打开下载的固件包。利用其在线解包功能将固件解包并抽取文件系统。固件包的内容将以可视化的文件目录树形式展现,方便后续分析。同时,Shambles Cloud 会对解包信息进行初步分析,确定设备型号、厂商、芯片架构及设备类型等信息。
经分析,该设备为 D-Link 的 MIPS 芯片架构嵌入式摄像头设备。在文件管理器中搜索关键字 alphapd,这是 CVE 漏洞信息中提到的 Web 服务器可执行文件。
在反编译窗口中搜索 WEPEncryption 关键字,结果返回多处匹配信息。结合右侧代码风险检测窗口的检测结果,发现两处信息多次提到 sub_43b7c0 附近的地址。代码风险检测直接指出了 strcpy 相关的栈溢出风险。
因此,sub_43b7c0+1b4 处存在问题的可能性较大。双击跳转至 strcpy(&var30, v2) 处查看汇编代码。
汇编代码显示该处确实是一个 strcpy 调用。按 F5 快捷键切换到伪代码视图(pseudo view)查看反编译代码。第 25 行将 v2 的内容拷贝到栈变量 &var30 的地址。第 11~19 行的逻辑表明:当 p0 内存地址中不存在 WEPEncryption 参数时,不进行有效操作并直接返回;而当存在该参数时,websGetVar 返回 WEPEncryption 的参数内容。
结合 CVE 信息及函数名含义,推测 sub_43b7c0 是处理网络请求参数 WEPEncryption 的函数。为了验证这一猜测,需要证明当针对 wireless.htm 发送带有 WEPEncryption 参数的网络请求时,sub_43b7c0 会被执行,这需要动态模拟运行固件。
strcpy 函数是 C 语言标准库中用于字符串复制的函数,但它不具备边界检查能力。如果源字符串长度超过目标缓冲区的大小,就会发生缓冲区溢出。在嵌入式系统中,由于资源受限,开发者常因疏忽或性能考虑使用此类函数,从而埋下安全隐患。
在本例中,用户输入的 WEPEncryption 参数被直接传递给 strcpy,且目标缓冲区位于栈上。攻击者通过构造超长参数,可以覆盖栈上的返回地址,从而劫持程序控制流。
按照静态分析的结论,进入动态验证流程。利用 Shambles Desktop 的固件仿真模拟功能(Virtual Machine,简称 VM)对该固件进行动态调试。
进入仿真模拟功能后,需要将文件管理模块切换到云端模式下,在右侧工具栏 VM 管理工具中点击新建,选择 alphapd 所在的文件系统建立一个模拟器。在文件管理器中选中 alphapd 所在的文件系统,右键打开终端(文件系统终端),此时固件的文件系统已被挂载。
在新打开的文件系统终端输入 /bin/alphapd 启动服务,初始会报错 cannot open pid file。搜索该错误信息,定位到代码段中的引用,推断缺失的文件应为 /var/run/alphapd.pid。
手动创建该文件后再次运行,又出现等待 nvram_daemon 的错误。继续创建 /var/run/nvramd.pid 文件。此时仍报错 Can't get lan ip from sysinfo!。
错误原因是 nvram_bufget 无法获取 IPAddress 信息。Shambles 的模拟环境支持从配置文件初始化设备参数配置。全局搜索 IPAddress 关键字,排除可执行文件、sh 文件及 cgi 文件后,锁定 RT2860_default_vlan 为设备参数配置文件。
Shambles 的模拟环境在 /shambles 目录下预置了 libnvram.so,可以从配置文件加载设备参数信息。将 RT2860_default_vlan 拷贝到 libnvram.so 所在目录,重命名为 nvram.ini。运行时需要预加载 libnvram.so,输入命令:
LD_PRELOAD=/shambles/libnvram.so /bin/alphapd
运行结果显示 alphapd 成功启动,并输出了 IP 地址等配置信息。一般 alphapd 默认的 Web 服务端口是 80,设置端口转发访问 http://127.0.0.1:80,浏览器界面显示正常,默认 admin 密码为空,证明 Web 服务正常运行。
结合静态分析结论,首先验证 alphapd 是否可以响应针对 wireless.htm 的请求。在电脑本机命令行输入:
curl http://127.0.0.1/wireless.htm?WEPEncryption=FEWFEW
返回信息正常,说明 alphapd 响应带有 WEPEncryption 参数的请求。
以调试模式启动 alphapd。在 Shambles Desktop 的 alphapd 反编译界面点击调试配置,把 libnvram.so 配置为预加载库。启动调试,事件日志窗口返回的日志与文件系统终端运行一致。
在 sub_43b7c0 函数 return 处打断点(断点 2),该位置对应 jr 指令,会将 ra 寄存器中的值拷贝到 pc 寄存器。ra 存储的是 strcpy 调用函数 sub_43b7c0 执行完成后的跳转地址。
测试 1: 发送正常长度的 WEPEncryption 参数请求。调试进程停在断点 1 和断点 2,执行完成后,pc 寄存器内容为正常的指令地址,网络请求正常返回。
测试 2: 发送超长参数的 WEPEncryption 请求。调试进程同样停在断点 1 和断点 2,但执行完成后,pc 寄存器内容被修改为某个内存地址,而非正常的指令地址。此时继续执行,alphapd 崩溃,说明栈已被破坏。
两次测试结果对比说明,发送带有 WEPEncryption 参数的网络请求会执行 strcpy,该函数将用户输入变量拷贝到栈内存。攻击者通过构造超长参数,可以修改 pc 寄存器内容,使其指向任意指令地址,从而执行任意命令攻击。
至此,CVE-2019-10999 在 Shambles 平台上重现完成。
该漏洞属于远程代码执行(RCE)类漏洞。一旦攻击者利用成功,可以在未授权的情况下获得设备的最高权限。对于摄像头等 IoT 设备,这意味着攻击者可以窃取视频流、篡改设备配置,甚至将其纳入僵尸网络发起更大规模的攻击。
WEPEncryption 的长度不超过缓冲区定义的大小。strcpy 等不安全的字符串处理函数,改用 strncpy 或 snprintf 等带长度限制的函数。本文详细分析了 D-Link DCS-932L 设备的 CVE-2019-10999 漏洞。通过静态分析定位到 strcpy 函数调用点,利用 Shambles Desktop 搭建仿真环境进行动态调试,成功复现了栈溢出过程。该案例展示了嵌入式固件开发中常见的字符串处理安全隐患。安全开发人员应重视输入数据的合法性校验,采用更安全的编程实践,以防止类似漏洞的产生。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online