Cisco RV340仿真

漏洞介绍

Cisco RV340在2023年爆出了一个CVE-2023-20073漏洞,该漏洞是由于文件上传时授权执行机制不充分造成的,攻击者可通过向受影响设备发送伪造的 HTTP 请求来利用此漏洞。成功利用漏洞后,攻击者可向受影响设备上传任意文件。需要研究该漏洞,首先得对Cisco RV340固件进行仿真。
在CVE官网上可以搜素到CVE-2023-20073漏洞的相关信息
在这里插入图片描述
Cisco RV340、RV340W、RV345 和 RV345P Dual WAN Gigabit VPN 路由器中基于 Web 的管理界面中存在一个漏洞,未经身份验证的远程攻击者可将任意文件上传到受影响的设备。

环境搭建

固件下载

在思科官网(https://software.cisco.com/download/home/286287791/type/282465789/release/1.0.03.29)中下载最新的RV340固件。
在这里插入图片描述

文件系统提取

下载好固件后,拖入虚拟机中,使用binwalk进行固件解析
使用常用的-Me参数

binwalk -Me RV34X-v1.0.03.29-2022-10-17-13-45-34-PM.img

在这里插入图片描述

中间会报一些编码上的错误,但是不妨碍我们对文件系统进行提取
提取后,可以在ubifs-root文件夹中看到文件系统
在这里插入图片描述

网络环境搭建

通过qemu进行固件模拟时,免不了和宿主机进行通信,需要配置一定的网络环境,一般的方法是设置一个网桥,开一个接口,将这个接口给qemu,然后流量的发送都通过这个网桥。示意图如下:
在这里插入图片描述

具体创建命令如下,一般都是通用的:

#!/bin/sh
#sudo ifconfig eth0 down                 # 首先关闭宿主机网卡接口
sudo brctl addbr br0                     # 添加一座名为 br0 的网桥
sudo brctl addif br0 ens33                # 在 br0 中添加一个接口
sudo brctl stp br0 off                   # 如果只有一个网桥,则关闭生成树协议
sudo brctl setfd br0 1                   # 设置 br0 的转发延迟
sudo brctl sethello br0 1                # 设置 br0 的 hello 时间
sudo ifconfig br0 0.0.0.0 promisc up     # 启用 br0 接口
sudo ifconfig ens33 0.0.0.0 promisc up    # 启用网卡接口
sudo dhclient br0                        # 从 dhcp 服务器获得 br0 的 IP 地址
sudo brctl show br0                      # 查看虚拟网桥列表
sudo brctl showstp br0                   # 查看 br0 的各接口信息
sudo tunctl -t tap0 -u root              # 创建一个 tap0 接口,只允许 root 用户访问
sudo brctl addif br0 tap0                # 在虚拟网桥中增加一个 tap0 接口
sudo ifconfig tap0 0.0.0.0 promisc up    # 启用 tap0 接口
sudo brctl showstp br0

注意:如果是eth0的话,则需要将ens33全部换成eth0。
可以在命令行中一条一条输入,也可以将所有命令写入一个sh文件,例如net.sh,接着给文件赋予可执行权限chmod +x net.sh,最后执行文件./net.sh即可
在这里插入图片描述
在这里插入图片描述

运行net.sh后,可以使用ifconfig看到配置的信息
在这里插入图片描述

启动qemu环境

首先需要明确,需要仿真的环境类型是什么。
查看bin文件下的busybox类型
在这里插入图片描述

可以看到文件系统是arm架构,小端序列。
在https://people.debian.org/~aurel32/qemu/armhf/上下载对应的启动文件
在这里插入图片描述

qemu启动命令如下:

sudo qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress \
  -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 \
  -append "root=/dev/mmcblk0p2" -net nic -net tap,ifname=tap0,script=no,downscript=no \
  -nographic -smp 4

命令解释如下:

  1. qemu-system-arm是qemu中用于模拟ARM架构的系统。
  2. -M参数指定需要模拟的硬件平台,这里指定为VEXPRESS-A9,是一个ARM Cortex-A9处理器
  3. -kernel参数指定加载的linux内核,vmlinuz-3.2.0-4-vexpress是一个针对VEXPRESS-A9架构的3.2.0-4版本的内核
  4. -initrd参数指定初始RAM磁盘(initrd)的文件
  5. -drive参数设置虚拟硬盘,if=sd 表示使用SCSI设备接口,file=debian_wheezy_armhf_standard.qcow2 指定了硬盘映像文件的路径。
  6. root=/dev/mmcblk0p2 指定了根文件系统的设备,在这里是一个模拟的MMC(内存卡)设备。
  7. -net nic参数添加网络接口控制器,即NIC
  8. -net tap参数配置了一个虚拟网络接口,tap0 是接口的名称。script=no,downscript=no 表示不使用网络启动脚本。
  9. -nographic 表示不使用图形界面,即以命令行模式运行。
    10.-smp参数用于启动SMP(对称多处理),并指定虚拟机有4个CPU核心

执行启动脚本,等待一段时间后,进入linux内核系统,账号密码均为root
在这里插入图片描述

通过ifconfig查看下IP地址,发现IP地址配置没了
在这里插入图片描述

没关系,再配置一下,注意要和ens33在同一网段下,并且不要和br0网卡配置成相同的IP地址

ifconfig eth0 192.168.74.140/24

在这里插入图片描述

主机和模拟环境互相测试一下网络连通性
主机ping虚拟环境:
在这里插入图片描述

虚拟环境ping主机:
在这里插入图片描述

两边都可以ping通。

固件模拟

主机和仿真环境内外都可以互相通信之后,下一步就是将文件系统上传至虚拟环境,并运行

上传文件系统

首先将解包出来的文件系统使用tar命令压缩,接着使用scp命令上传到环境中,中途需要输入qemu环境的密码

tar -czvf rootfs.tar.gz rootfs
scp -r rootfs.tar.gz root@192.168.74.140:/root/

注意将IP地址替换成自己的
在这里插入图片描述

上传完成后,就可以在虚拟环境中看到压缩后的文件系统了
在这里插入图片描述

使用tar命令进行解压

tar -xzvf rootfs.tar.gz

启动文件系统

接下来进行仿真时要先用chroot命令创建隔离的文件系统环境。但这会导致无法在隔离的文件系统中访问原本的/proc和/dev目录,因为它们是特殊的虚拟文件夹(用于提供系统信息和设备的访问)

为了让qemu环境正常运行,需将原本qemu的/proc和/dev目录挂载到新创建的隔离环境中。

chmod -R 777 rootfs
cd rootfs/
mount --bind /proc proc
mount --bind /dev dev
chroot . /bin/sh

这个时候,文件系统就算是成功启动起来了,但是这只是一个空壳,我们还需要一些服务,方便后续进行调试。
在/etc/init.d目录中,存放了大量的启动服务和停止服务的脚本,发现有nginx服务。
在这里插入图片描述

尝试开启nginx服务,这样,就可以通过web界面来进行路由器访问了。
使用命令/etc/init.d/nginx start开启nginx服务
通过web访问IP地址,发现页面加载出错
在这里插入图片描述

回到控制台,发现显示一大堆错误

/ # /etc/init.d/nginx start
uci: Entry not found
chown: /var/firmware: No such file or directory
chown: /var/3g-4g-driver: No such file or directory
chown: /var/in_certs: No such file or directory
chown: /var/signature: No such file or directory
chown: /var/language-pack: No such file or directory
chown: /var/configuration: No such file or directory
FAILED: confd_load_schemas(addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2413
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
touch: /tmp/stats/certstats.tmp: No such file or directory
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
cp: can't stat '/tmp/stats/certstats.tmp': No such file or directory
FAILED: confd_load_schemas(addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2413
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
touch: /tmp/stats/certstats.tmp: No such file or directory
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
cp: can't stat '/tmp/stats/certstats.tmp': No such file or directory
FAILED: confd_load_schemas(addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2413
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
touch: /tmp/stats/certstats.tmp: No such file or directory
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
cp: can't stat '/tmp/stats/certstats.tmp': No such file or directory
Collected errors:
 * opkg_conf_load: Could not create lock file /var/lock/opkg.lock: No such file or directory.
nginx: [emerg] open() "/var/lock/nginx.lock.accept" failed (2: No such file or directory)
uci: Entry not found
/ # [uWSGI] getting INI configuration from /etc/uwsgi/blockpage.ini
[uWSGI] getting INI configuration from /etc/uwsgi/upload.ini
[uWSGI] getting INI configuration from /etc/uwsgi/jsonrpc.ini
*** Starting uWSGI 2.0.15 (32bit) on [Thu Apr 25 03:19:57 2024] ***
compiled with version: 4.8.3 on 17 October 2022 13:32:49
*** Starting uWSGI 2.0.15 (32bit) on [Thu Apr 25 03:19:57 2024] ***
compiled with version: 4.8.3 on 17 October 2022 13:32:49
os: Linux-3.2.0-4-vexpress #1 SMP Debian 3.2.51-1
nodename: debian-armhf
os: Linux-3.2.0-4-vexpress #1 SMP Debian 3.2.51-1
machine: armv7l
nodename: debian-armhf
machine: armv7l
clock source: unix
clock source: unix
pcre jit disabled
pcre jit disabled
detected number of CPU cores: 4
detected number of CPU cores: 4
current working directory: /
detected binary path: /usr/sbin/uwsgi
current working directory: /
detected binary path: /usr/sbin/uwsgi
setgid() to 33
*** Starting uWSGI 2.0.15 (32bit) on [Thu Apr 25 03:19:57 2024] ***
compiled with version: 4.8.3 on 17 October 2022 13:32:49
os: Linux-3.2.0-4-vexpress #1 SMP Debian 3.2.51-1
nodename: debian-armhf
machine: armv7l
clock source: unix
setgid() to 33
pcre jit disabled
detected number of CPU cores: 4
current working directory: /
detected binary path: /usr/sbin/uwsgi
setgid() to 33
setuid() to 33
setuid() to 33
your processes number limit is 961
your processes number limit is 961
your memory page size is 4096 bytes
your memory page size is 4096 bytes
setuid() to 33
detected max file descriptor number: 1024
detected max file descriptor number: 1024
your processes number limit is 961
lock engine: pthread robust mutexes
lock engine: pthread robust mutexes
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
thunder lock: disabled (you can enable it with --thunder-lock)
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address 127.0.0.1:9001 fd 3
uwsgi socket 0 bound to TCP address 127.0.0.1:9000 fd 3
uwsgi socket 0 bound to TCP address 127.0.0.1:9003 fd 3
your server socket listen backlog is limited to 100 connections
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
your mercy for graceful operations on workers is 60 seconds
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 128512 bytes (125 KB) for 1 cores
mapped 128512 bytes (125 KB) for 1 cores
*** Operational MODE: single process ***
*** Operational MODE: single process ***
initialized CGI path: /www/cgi-bin/upload.cgi
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 2560)
initialized CGI mountpoint: /blocked.php = /www/cgi-bin/blockpage.cgi
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 2559)
mapped 321280 bytes (313 KB) for 4 cores
*** Operational MODE: preforking ***
initialized CGI mountpoint: /jsonrpc = /www/cgi-bin/jsonrpc.cgi
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 2558)
spawned uWSGI worker 1 (pid: 2561, cores: 1)
spawned uWSGI worker 1 (pid: 2562, cores: 1)
spawned uWSGI worker 1 (pid: 2563, cores: 1)
spawned uWSGI worker 2 (pid: 2564, cores: 1)
spawned uWSGI worker 3 (pid: 2565, cores: 1)
spawned uWSGI worker 4 (pid: 2566, cores: 1)

其中的一个报错引起人注意:

FAILED: confd_load_schemas(addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2413

confd系统调用失败,init.d下也有一个confd脚本,那就先运行confd,执行命令/etc/init.d/confd start
发现还是报错:

/ # /etc/init.d/confd start
uci: Entry not found
cp: can't stat '/etc/ssl/private/Default.pem': No such file or directory
Failed reading '/tmp/dropbear_host_key'
TRACE Connected (maapi) to ConfD
attaching to init session...
TRACE MAAPI_ATTACH  --> CONFD_OK
TRACE MAAPI_DELETE /avc-meta-data --> CONFD_OK
TRACE MAAPI_LOAD_CONFIG_FILE  --> CONFD_OK
TRACE Connected (maapi) to ConfD
attaching to init session...
TRACE MAAPI_ATTACH  --> CONFD_OK
TRACE MAAPI_DELETE /device-os-types --> CONFD_OK
TRACE MAAPI_LOAD_CONFIG_FILE  --> CONFD_OK
TRACE Connected (maapi) to ConfD
attaching to init session...
TRACE MAAPI_ATTACH  --> CONFD_OK
TRACE MAAPI_DELETE /webfilter-meta-data --> CONFD_OK
TRACE MAAPI_LOAD_CONFIG_FILE  --> CONFD_OK
0
uci: Entry not found
uci: Entry not found
CDB boot error: Init transaction failed to validate: /confd_dyncfg:confdConfig: Need read access to one of the files ./ssh/ssh_host_dsa_key and ./ssh/ssh_host_rsa_key defined for /confdConfig/aaa/sshServerKeyDir
0
*** Error in `ucicfg_hook': double free or corruption (out): 0x017b9018 ***
Aborted (core dumped)
connection refused (start_phase2)
uci: Entry not found
uci: Entry not found
uci: Entry not found
FAILED: confd_load_schemas(addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2413
FAILED: confd_load_schemas(addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2413
uci: Entry not found
uci: Entry not found
FAILED: maapi_connect(ms, addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2432
FAILED: maapi_connect(ms, addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2432
FAILED: maapi_connect(ms, addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2432
FAILED: maapi_connect(ms, addr, addrlen), Error: system call failed (24): Connection refused, in function run, line 2432

其中一条显示证书未找到

cp: can't stat '/etc/ssl/private/Default.pem': No such file or directory

在整个文件的代码中搜索/etc/ssl/private/,有一个文件叫做generate_default_cert,即生成默认证书,正好是我们需要的。

运行generate_default_cert命令

报错如下:

/ # generate_default_cert
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
uci: Entry not found
cp: can't stat '/tmp/etc/config/certificate': No such file or directory
touch: /tmp/stats/certstats.tmp: No such file or directory
/usr/bin/certscript: line 1: can't create /tmp/stats/certstats.tmp: nonexistent directory
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
cp: can't stat '/tmp/stats/certstats.tmp': No such file or directory
Default

网上搜索了一下发现是uci读取的一个配置文件不存在,配置文件存放在/etc/config/目录中,再次搜索该目录,发现/etc/init.d/boot文件中有两行代码,用来来创建路径。
在这里插入图片描述

所以需要执行/etc/init.d/boot boot,启动一下boot服务。
执行情况如下:

/ # /etc/init.d/boot boot
uci: Entry not found
uci: Entry not found
uci: Entry not found
mount: mounting debugfs on /sys/kernel/debug failed: No such file or directory
Mounting mnt partitions..mount: mounting /dev/mtdblock9 on /mnt/configcert failed: No such device
mount: mounting /dev/mtdblock10 on /mnt/avcsign failed: No such device
mount: mounting /dev/mtdblock11 on /mnt/webrootdb failed: No such device
mount: mounting /dev/mtdblock12 on /mnt/license failed: No such device
done.
uci: Parse error (option/list command found before the first section) at line 2492, byte 1
 create_meta_data_xml begin
 meta_data_gen_state: 0
 meta_data_gen_state: 1
 create_meta_data_xml end

还是会显示一些错误,不过已经不影响服务正常启动了。

最终,整个服务的启动流程如下:

/etc/init.d/boot boot
generate_default_cert
/etc/init.d/confd start
/etc/init.d/nginx start

成功启动后,通过网页访问qemu的IP地址,可以看到路由器界面
在这里插入图片描述
登录账号和密码均为cisco
在这里插入图片描述
至此,RV340固件仿真完毕。

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值