Backport vulnerability in RouterOS compromises hundreds of thousands of devices





The ability to remotely downgrade devices based on RouterOS (Mikrotik) threatens hundreds of thousands of network devices. The vulnerability is associated with the poisoning of the DNS cache of the Winbox protocol and allows you to download outdated (with resetting the password by default) or modified firmware on the device.







Vulnerability Details



The RouterOS terminal supports a resolution command for DNS lookups.



image



This request is processed by a binary named resolver. Resolver is one of many binaries that are connected to the RouterOS Winbox protocol. At a high level, “messages” sent to the Winbox port can be routed to various binaries in RouterOS based on an array-based numbering scheme.



By default, RouterOS has the DNS server feature disabled.



image



However, even with the server function disabled, the router maintains its own DNS cache.



image



When we make a request using winbox_dns_request, for example, example.com, the router will cache the result.



image



Since we can specify the DNS server through which the request should go, entering the wrong addresses is trivial. For example, you can configure the implementation of the DNS server from Philip Klaus to always respond with an A record containing the IP address 192.168.88.250.



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()
      
      





Now, if you look up example.com using Winbox, you can see that the router’s DNS cache has been poisoned.



image



Of course, poisoning example.com is not very useful, as the router will not actually use it. However, the router needs access to upgrade.mikrotik.com, cloud.mikrotik.com, cloud2.mikrotik.com and download.mikrotik.com. And thanks to another mistake, it is possible to poison them all at once.



 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()
      
      





The router requests one permission, and we provide five back. The router caches all of these responses incorrectly.



image



Obviously, this attack is also useful if the router acts as a DNS server, since it allows attacking the clients of the router.



This attack also allows exploiting a more serious vulnerability: downgrade or backport the RouterOS version. The attacker recreates the logic of the update server, including changelog, and makes RouterOS accept the outdated (vulnerable) version as current. The danger here lies in the fact that when the version is updated, the administrator password is reset to the default value - an attacker can log in with an empty password!





The attack is quite working, despite the fact that the author implements several more vectors, including those related to embedding a backdoor in the firmware , but this is already a redundant technique and it is illegal to use it for illegitimate purposes.



Protection



Simply disabling Winbox protects against these attacks. Despite the convenience of administering through Winbox, it is better to use the SSH protocol.



All Articles