笔记 & WP

小米AX9000路由器漏洞复现

Word count: 1.5kReading time: 6 min
2024/05/29

前言

由于昨天写的文章没有保存,今天又又又要重新来一遍 干!

之前就想对IOT设备进行一些复现,已经漏洞挖掘,虽说之前已经复现过TendaDlink的一些历史漏洞,但毕竟也是好几年前的,现在想着从新一些的漏洞,通过复现了解一下大佬们的挖掘思路

所以本文主旨为复现,主要参考文章

固件

固件下载

小米有固件下载的官网

这里也是用winmt师傅给的链接直接下载就行

固件解压

关于固件解密这块,我还没有涉略过,但好在小米的固件没有加密,我们可以跟随着文章的思路进行解压

1
binwalk -Me miwifi_ra70_firmware_cc424_1.0.168.bin

然后我们可以得到一个xxx.ubi,再通过

1
ubireader_extract_images 2B4.ubi

ubifs-root分解出来三个文件,我们需要的是其中的xxx-ubi_rootfs.ubifs,使用binwalk再次解压

1
binwalk -Me img-870537086_vol-ubi_rootfs.ubifs

这样我们就得到SquashFS文件系统

Lua

这个文件是我第一次遇见,根据查找知道了一些它的用处

Lua 是一种轻量级的高级编程语言,广泛用于嵌入式系统开发、游戏开发、脚本编写以及其他领域。Lua 是一种功能强大、高效且灵活的语言,并且它对于嵌入到其他程序中非常方便

然后

在物联网(IoT)设备的固件中,Lua 通常用作嵌入式脚本语言,用于实现设备的控制逻辑、配置和定制功能

反正先画个概念

Lua反编译

小米的前端是lua编写的,并且小米对lua的解释器进行了魔改,所以我们无法用正常的Lua的反编译工具

但是有大佬专门针对小米固件做出来了unluac_miwifiluadec_miwifi

这里我也使用的是unluac_miwifi

同时也用这个文章来看,安装完成后,这里也是修改一下winmt师傅的脚本即可

1
2
3
4
5
6
7
8
9
import os

res = os.popen("find ./ -name *.lua").readlines()

for i in range(0, len(res)) :
path = res[i].strip("\n")
cmd = "java -jar /home/kaijia/unluac_miwifi/build/unluac.jar " + path + " > " + path + ".dis"
print(cmd)
os.system(cmd)

关于Lua的分析,我们后面再说,现在解决一下系统模拟的问题

系统模拟

qemu安装aarch64这个文章好用,大致跟我之前写的差不多,但是这个命令可以直接copy(懒人欣喜)

看架构 一般我都是通过checksec文件来知道它是用什么架构的

上面那个文章,只是把系统给安装好了,但是它qemu启动的网络是以用户模式,所以我们不能直接访问(就是我们无法直接访问qemu的机子),下面就要研究一下(之前我研究的现在有些问题)

qemu网络配置

待解决 太奇怪了

文件系统打包

1
tar -cvf AX_90000.tar squashfs-root

通过wget传到qemu虚拟机上

然后使用tar解压

固件分析

在固件模拟前,我们需要先对固件分析一下,通过/etc/init.d/mihttpd文件可以知道大致的启动流程

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
55
56
57
58
59
60
61
62
63
#!/bin/sh /etc/rc.common

START=22

USE_PROCD=1

FCG_PROCESS_NUM="2"
NGINX="/usr/sbin/mihttpd"
SPAWN_FCGI="/usr/bin/spawn-fcgi"
FCGI="/usr/bin/fcgi-cgi"
FCGI_PORT="8960"
CONFIG_FILE="/etc/mihttpd/mihttpd.conf"

env_init() {
echo "env_init"
mkdir -p /tmp/mihttpd/lock

mkdir -p /tmp/mihttpd/
mkdir -p /tmp/mihttpd/body
mkdir -p /tmp/mihttpd/cache
mkdir -p /tmp/mihttpd/fastcgi
mkdir -p /tmp/mihttpd/inforoot
mkdir -p /tmp/mihttpd/log
mkdir -p /tmp/mihttpd/luaroot
mkdir -p /tmp/mihttpd/preload
mkdir -p /tmp/mihttpd/proxy
mkdir -p /tmp/mihttpd/run
mkdir -p /tmp/mihttpd/temp
chmod -R 777 /tmp/mihttpd
}

start_service() {

env_init
# start fcgi-cgi first
procd_open_instance
procd_set_param command $SPAWN_FCGI -a 127.0.0.1 -p $FCGI_PORT -U nobody -C 0 -F $FCG_PROCESS_NUM -- $FCGI -c 2
procd_set_param respawn
procd_close_instance
echo "start fcgi-cgi by spawn-fcgi."

procd_open_instance
procd_set_param command $NGINX -c $CONFIG_FILE
procd_set_param file $CONFIG_FILE
procd_set_param respawn
procd_close_instance
echo "start nginx ok."
}

stop_service() {
# stop nginx first
service_stop $NGINX
echo "stop nginx by procd ok."

# stop fcgi-cgi
# service_stop $FCGI
echo "stop fcgi-cgi ok."
}

stop_fcgi() {
killall -s 9 fcgi-cgi >/dev/null 2>&1
killall -s 9 luci >/dev/null 2>&1
}

大致的服务是由/usr/sbin/mihttpd/usr/bin/fcgi-cgi来实现的,我们先看一下mihttpd大致什么

可以发现mihttpd是实际上是sysapihttpd的链接,然后发现如果我们直接启动程序,虽然会启动对应端口,但实际上会对我们的请求进行拒绝

经过了一两天的研究,发现问题是在配置文件中,我们先看默认文件,通过mihttpd -h即可查看到

然后我们分析,这个文件,因为之前报错一直有0.0.0.1:65535,所以很明显的看到了这个

怀疑是否是这个问题,然后把注释去掉运行,通过浏览器访问,有了对应的页面回显,说明我们nginx服务开启成功了

但是根据启动文件,我们mihttpd真正的配置文件是在这里/etc/mihttpd/mihttpd.conf,根据我们上面分析的去掉对应的注释

redirect这里是一个重定向的作用,根据自己的理解 0.0.0.1:65535是我们正常请求时的请求一个接收的端口(虚拟出来的),但是程序对非法的端口不进行接收,所以我们这里修改配置文件重定向就可以了

然后我们根据配置文件修改,然后进行启动

然后就可以发现

有内容了,但是也有报错

/dev/nvram

NVRAM(Non-Volatile Random Access Memory)是一种非易失性随机存取存储器,它能够在断电时保存数据。固件模拟与NVRAM有关系,因为在进行固件模拟时,我们需要模拟整个嵌入式系统的运行环境,包括系统配置信息、参数和状态等。这些信息通常存储在NVRAM中,并在系统启动时被读取

这里我是用nvram-faker解决的

这里目前的模拟问题大致解决了

然后从winmit师傅上了解到了,如何绕过初始化配置

未完…

CATALOG
  1. 1. 前言
  2. 2. 固件
    1. 2.1. 固件下载
    2. 2.2. 固件解压
    3. 2.3. Lua
    4. 2.4. Lua反编译
  3. 3. 系统模拟
    1. 3.1. qemu网络配置
    2. 3.2. 文件系统打包
    3. 3.3. 固件分析