MikroTik RouterOS CVE-2023-32154 认证前RCE漏洞分析
MikroTik作为网络基础设施供应商,其产品和RouterOS被广泛采用。目前,至少有超过 300 万台设备在线运行 RouterOS。该漏洞是Pwn2Own上orange团队利用的漏洞,达到了认证前RCE。且该漏洞存在了9年未被发现,基本影响了RouterOS6版本和7版本中的大多数设备。 0x00 CVE信息 What this issue affects: The issue affects devices running MikroTik RouterOS versions v6.xx and v7.xx with enabled IPv6 advertisement receiver functionality. You are only affected if one of the below settings is applied: 通过官方描述,得知漏洞存在于ipv6的RA协议中。 Router Advertisement(RA)是IPv6协议中的一种控制消息,用于告知网络中其他设备关于路由器的存在和IPv6地址分配信息。RA消息通常由网络中的路由器定期广播,以便其他设备可以获取路由器的信息并使用IPv6协议与其通信。 在RouterOS中,RA功能是路由器的一个基本功能,它可以通过配置路由器的接口参数来启用。当启用RA功能后,路由器将会在指定的接口上定期广播RA消息,使得其他IPv6设备可以通过接收这些消息来自动配置自己的IPv6地址和路由信息。 0x01 前置知识 IPV6 SLAAC 所谓 IPV6 SLAAC 即 Stateless address autoconfiguration,无状态地址自动配置。这里我们需要了解几个概念。 路由器请求RS(Router Solicitation)报文:很多情况下主机接入网络后希望尽快获取网络前缀进行通信,此时主机可以立刻发送RS报文,网络上的设备将回应RA报文。 路由器通告RA(Router Advertisement)报文:每台设备为了让二层网络上的主机和设备知道自己的存在,定时都会组播发送RA报文,RA报文中会带有网络前缀信息,及其他一些标志位信息。 我们的电脑可以通过路由器发送的RA来接收ipv6前缀从而配置ipv6地址,同样的我们也可以向路由器发送RA来对路由器的ipv6地址和一些其他信息(比如DNS)进行配置。 通过分析这个协议我们可以发现,在这种场景中,路由器其实是一个既充当了客户端,又充当了服务端的功能。其他的客户端可以给路由器发送配置,路由器会将这些配置存储。而路由器本身又会作为客户端存在,把自身的配置向其他设备进行广播。而作为客户端情况存在往往会疏于检查从而存在漏洞。 0x02 漏洞分析 在RouterOS7.9版本中,找到负责RA协议处理的二进制radvd进行bindiff,发现新版本的patch主要在下面这段代码(以下是在7.9版本中未修复的代码) while ( v21 != a2 + 1 ) { v9 = sub_804E434(v8);Mikrotick if ( (_BYTE)v9 ) { v10 = operator<<(&unk_80554C0, "adding DNS server option, address=", v9, v9); v11 = operator<<(v16, v21 + 3, v10, v21 + 3); v12 = operator<<(v11, v20, v17, v18); endl(v12); } v19 = v21[4]; v13 = v21[5]; v14 = v21[6]; *(_DWORD *)(a1 + v3) = v21[3]; *(_DWORD *)(a1 + v3 + 12) = v14; *(_DWORD *)(a1 + v3 + 4) = v19; *(_DWORD *)(a1 + v3 + 8) = v13; v3 += 16; tree_iterator_base::incr((tree_iterator_base *)&v21); } 可以看到这段逻辑循环终止条件是v21这个vector到末尾,并且在循环过程中会把vector中的内容向a1上拷贝。其实再向上追一下可以发现a1是上层函数中的一个栈上的变量且大小是固定的。因此只要这个vector中的内容足够大便可以造成栈溢出。...