pwn2own上orange团队利用的漏洞,认证前rce。但是经过我自己的实验发现是非默认配置,且前置条件比较多。
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 漏洞分析
找到负责RA协议处理的二进制,radvd进行bindiff,发现新版本的patch主要在下面这段代码
1 | while ( v21 != a2 + 1 ) |
可以看到这段逻辑循环终止条件是v21这个vector到末尾,并且在循环过程中会把vector中的内容向a1上拷贝。其实再向上追一下可以发现a1是上层函数中的一个栈上的变量且大小是固定的。因此只要这个vector中的内容足够大便可以造成栈溢出。
在后续版本中,这部分逻辑检测了vecotr上的总容量要小于栈上的大小,后续又将栈上的变量直接改为了动态分配的vector,永绝后患。
在上层函数中,a1变量对应v126,可见这段代码整体逻辑就是把vecotr上的DNS server option拷贝到栈上组成一个包,然后发送出去。其他的关于RA的配置信息也是如此构造。
1 | message.msg_name = v129; |
根据对ipv6协议的学习,我们可以通过先向Mikrotik发送通过发送路由器通告RA(Router Advertisement)报文去把DNS server option这个vector设置的很大。然后再路由器请求RS(Router Solicitation)报文)来让Mikrotik把自身的配置通告给邻居设备来触发这段逻辑的执行。
0x 02 漏洞触发
首先需要设置路由器可以接收RA报文,默认其实是不接受的
1 | ipv6/settings/ set accept-router-advertisements=yes |
查找RFC构造NS和NA报文来触发漏洞,这里我选择scapy,scapy在文档中均有对RA和RS报文的实现。我们对RS报文原封不动,修改RA报文的extion部分的DNS server option即可
根据rfc6106,DNS server option格式如下
1 | 0 1 2 3 |
0x03 poc
最终构造poc如下
1 | from scapy.all import * |