2023年7月,VulCheck研究人员披露MikroTik RouterOS存在高危漏洞CVE-2023-30799,可针对50万余个RouterOS系统发起大规模攻击。该漏洞最开始发现于2022年6月,被命名为FOISted。当时并没有分配CVE编号,猜测是因为只对x86虚拟机有影响,没有关于MikroTik 硬件设备的利用,并且需要admin管理员权限。2022年10月,RouterOS稳定版6.49.7中对该漏洞进行修复。对于RouterOS Long-term版本,直到漏洞发现者衍生出新的基于 MIPS 架构的利用链,并获得路由器的root shell后,在2023年7月份发布的6.49.8版本进行了修复。本文首先对RouterOS的IPC消息机制和身份验证过程进行简单介绍,然后对CVE-2023-30799的漏洞原理及利用方式进行分析。
1.1 IPC消息传递和处理
研究过程中,通过对web管理登录页面进行抓包测试,发现数据是加密的。通过github上的一些开源工具可以进行解密,解密后是一种nova message类型的数据。Nova Message消息是一种类型化的键值映射,具有两种形式。伪Json形式和二进制数据流的形式,两者代表的意义相同。下图左边是伪Json形式,右边是数据流格式,数据流形式以M2开头,容易识别。下面以一组伪Json格式消息来进行介绍,其中黄颜色的前置一位表示value的类型。例如bool类型,32位、64位的整数类型,字符串类型等七种。第七种表示nova message类型,表示该消息可以进行嵌套,大写表示该种类型的数组。除了前置类型不一样外,后面属于正常的Json格式key:value。每个消息的key具有特殊含义。其中比较重要的几个,例如0xFF0001为SYS_TO,表示发送消息到目标二进制程序;0xFF0002代表SYS_FROM,表示发送消息的源程序;0xFF0007表示执行的SYS_CMD。使用两个键值对Uff0001:[13,7]和Uff0007:0xfe000d来说明其中的含义。前置U表示value的值是32位的整数数组,key为ff0001表示SYS_TO,说明该消息要发送到目标为[13,7]的程序。这里的value=[13,7],分别代表了目标程序的id和handler id。第二个键值对中value类型一样,ff0007表示执行的命令SYS_CMD,0xfe000d根据上表映射为get函数。上面提到的程序id和handler id是哪里来的呢?在/nova/etc/loader目录下有一个x3规范类型的配置文件system.x3。经过解密如下所示:程序路径后的第一个参数13就是程序的id。Handler id存在对应路径的二进制程序里面,在程序中通过nv::Looper::addHandler函数进行注册。这种注册类似于程序初始化,初始化后的程序可以被调用。/nova/bin/user函数中注册了handler id为1-8的处理程序,下图仅展示4-8。了解了IPC消息组成,下面以一个示例描述进程间通信的整个流程,示例中foo(id=12)要向bar/sub(id=34,handler id=50)程序发送消息。(1)foo函数构造SYS_FROM:[]和SYS_TO:[34,50]的nova message,并发送给loader函数;(2)Loader函数根据SYS_TO中的第一个参数将消息发送给id=34的bar程序,然后将第一个参数删除,最后将发送方的程序id放入SYS_FROM,为后面的消息返回做准备;(3)Bar函数根据SYS_TO中的第二个参数将消息发送给handler id=50的sub程序,并将SYS_TO的第二个参数删除,这时SYS_TO值为空,bar/sub开始执行处理消息。(4)处理完后,bar/sub函数构造SYS_FROM:[]和SYS_TO:[12]的nova message发送到bar程序;(5)Bar程序将sub的handler id插入SYS_FROM中,并将消息发送给loader;(6)Loader将识别到的源程序bar的id插入SYS_FROM中,删除SYS_TO中的第一个参数,然后将消息发送到foo函数,这时SYS_TO为0,foo开始执行处理消息。1.2 身份验证
RouterOS有两种方式去连接,一种是web页面,另一种是使用winbox。其中www程序监听在80端口,mproxy程序监听在8291端口。两者使用的协议也有所区别,www使用标准椭圆曲线 Diffie-Hellman (ECDH) 协议,使用Curve25519 椭圆曲算法生成共享密钥,该密钥随后用于生成 RC4 传输和接收流密钥;mproxy使用椭圆曲线安全远程协议(EC-SRP5)进行身份验证,具体细节这里不做研究。本文漏洞验证使用web页面验证,该协议仅使用在客户端和服务端握手阶段,握手成功后使用伪json格式进行正常通信。
该漏洞的完整利用包括权限提升和代码注入两个部分。先构造一个控制权限的数据包提权到root,然后可以通过组件的注册操作触发到漏洞代码将传入的数据当作指针进行处理,可直接劫持函数的流程。下面对两个漏洞进行分析。2.1权限提升漏洞
该漏洞原因在于RouterOS允许GUI页面复选框来修改某些权限,而在内部,是通过发送一条带有组合位掩码值的消息来指示权限级别。通过GUI的普通管理员权限不能发送权限大于 0x7FFFE的消息,但是我们可以使用脚本发送权限为 0xFFFFFFFF的消息来进行提权,让普通用户变成超级管理员用户。2.2 代码注入漏洞
该漏洞的原因是RouterOS进程可以注册“Nova Handlers”(nv::Handlers),这是一个附属组件,能够处理和响应自己的请求。当第一次加载Servlet时,它自身需要在www程序中进行注册。这个过程是通过将IPC消息发送到www程序来执行。在这个过程中它将从获取的消息中提取一个地址作为函数指针。即控制该条消息就可以控制PC寄存器到任意的地址执行代码,攻击者可以构造合理的ROP链条完成利用。
利用该漏洞是在管理员用户权限下进行,并且该系统默认开启ftp功能。在利用之前可以将一个可用的shell程序busybox和startup程序上传到RouterOS。startup程序功能创建一个可用的shell程序sh,然后使用telnetd开启后门。因为漏洞代码属于www程序向www内部发送消息,这个过程只能以最高权限用户才能触发,所以在劫持程序流之前,必须先进行提权。完成提权的过程较简单,构造一条如下所示修改权限的数据包发送到设备。其中U2=0xFFFFFFFF,表示将admin普通用户权限提升为超级管理员用户。发送完该消息后,普通用户权限提升至超级用户权限,此时可以触发到代码注入漏洞。直接向漏洞程序发送构造好的ROP利用链,执行startup程序开启后门,获取shell。[1]https://margin.re/2022/06/pulling-mikrotik-into-the-limelight/[2]https://margin.re/2022/02/mikrotik-authentication-revealed/[3]https://github.com/MarginResearch/mikrotik_authentication[4]https://vulncheck.com/blog/mikrotik-foisted-revisited[5]https://github.com/MarginResearch/resources/blob/f4b09f2a9fab3a044cd6ebbda438c9b3e06097e3/documents/Pulling_MikroTik_into_the_Limelight.pdf
文章来源: https://mp.weixin.qq.com/s?__biz=MzkyMzAwMDEyNg==&mid=2247539674&idx=1&sn=0cf514706ab56c69bcfa8f40f4a771cd&chksm=c1e9d78bf69e5e9d3f5df3afd863da0fcbd445ba2cb4bd1c9da214b0fdd204b10e9e5375da6b&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh