1、概述
最近关注了Cisco的一个命令注入漏洞,命令注入之后进而导致远程代码执行,编号为:CVE-2020-3453:
漏洞存在于固件版本低于V1.0.03.19的RV340系列路由器中,当前最新版本为1.0.03.20已修复了此漏洞。RV340系列路由器可为小型企业提供防火墙和高速上网服务:
2、环境配置
从官网分别下载存在漏洞和最近已修复漏洞两个版本的固件:
固件为.img格式,与常见的.bin文件貌似有一些些区别?直接使用7z一路解压,当得到fw.gz时继续解压,最终结果如下:
可得到一个较大的openwrt-comcerto2000-hgw-rootfs-ubi_nand.img文件,由此可知此型号的路由器固件是基于openwrt开发而来?OpenWRT是一个高度模块化、高度自动化的嵌入式Linux系统,拥有强大的网络组件和扩展性,常常被用于工控设备、电话、小型机器人、智能家居、路由器以及VOIP设备中。文件系统为ubi,与常见bin格式的Squashfs文件系统相比,Squashfs有更好的压缩性。嵌入式领域常用的文件系统有Romfs、Cramfs、Ramfs、jffs2,yaffs2,logfs,ubifs等,几种文件系统的性能分析如下所示
使用binwalk对文件openwrt-comcerto2000-hgw-rootfs-ubi_nand.img文件进行分析,最终可得到文件系统中的全部内容:
可知目标平台为:ARM 32位 小端。尝试使用qemu虚拟机运行固件,却得到如下错误:
未找到根本原因,最终并没有将固件模拟运行成功。
3、漏洞分析
文件系统中有大量文件,目标分析文件为upload.cgi,至于为什么选择了这个文件呢,可能是纯属巧合吧。如何看看最近的更新修改了哪些内容呢?两个版本的upload.cgi程序有何异同呢?可使用bindiff这个工具,bindiff可集成在IDA或ghidra中的插件,在官网:https://www.zynamics.com/software.html下载最新版的bindiff6.msi安装,配合IDA7.0使用。工具在安装过程中需要指定IDA的目录,安装完之后在IDA工具栏的File菜单看到BinDiff的标签。由于对比肯定是需要两个文件,先使用IDA分析一个程序并保存成idb,然后再用IDA开另一个程序,点击标签栏的BinDiff并选择开始保存的idb文件,Matched Functions页面即可看到两个文件代码对比的结果了:
可以看到有两个函数不同:sub_12394和sub_11500,将鼠标移至函数上->右击-> View flow graphs,可打开bindiff程序,进入图形化的函数对比界面,界面使用了不同颜色标注:
其中:绿色代表相同的基本块,黄色代表修改的基本块,红色代表删掉的基本块,灰色代表新加的基本块。
既然重点函数已经对比出来了,直接使用IDA打开,到目标函数处详细分析即可:
通过函数对比,很快可以定位到漏洞产生地方:最终代码执行的位置位为system函数,system所执行的命令来源于sprintf函数,而此处的参数输入由用户所控制,当函数中未能对参数做正确的判断与过滤(如未对&和|符号进行过滤),则可进行命令注入。右边函数显示漏洞修补的方式即为接收参数后,在命令执行前进行正则匹配判断,由此过滤掉了&和|等符号。
上述位置说明了命令注入是存在的,沿着问题点向上继续追溯函数,看看都由那些相关参数,来到函数sub_1150的调用点sub_10D84处:
要使函数执行流程能进入sub_1150,则需构造v15,v16,v17三个参数,三个参数各自代表的含义往上看即可确定。函数执行从v3判断开始,v3为HTTP_COOKIE,即正常情况下,用户须先进行登录/认证,方可执行其他后续操作,但通过分析发现,即使未登录,即在v3为空的情况下,函数执行流程直接进入到if( haystack ),即只要保持v13的值不为空,函数执行流程仍然可以抵达sub_1150中,进而通过一系列参数构造,使得用户拼接的参数进入system函数中执行,最终造成了远程代码执行。
参考资料:
[1]https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-rv-osinj-rce-pwTkPCJv
[2] https://quentinkaiser.be/exploitdev/2020/10/01/patch-diffing-cisco-rv110/