diff --git a/scripts/mikrotik-routeros-brute.nse b/scripts/mikrotik-routeros-brute.nse new file mode 100644 index 000000000..97b292c63 --- /dev/null +++ b/scripts/mikrotik-routeros-brute.nse @@ -0,0 +1,100 @@ +description = [[ +Performs brute force password auditing against Mikrotik RouterOS devices with the API RouterOS interface enabled. + +Additional information: +* http://wiki.mikrotik.com/wiki/API +]] + +--- +-- @usage +-- nmap -p8728 --script mikrotik-routeros-brute +-- +-- @output +-- PORT STATE SERVICE REASON +-- 8728/tcp open unknown syn-ack +-- | mikrotik-routeros-brute: +-- | Accounts +-- | admin:dOsmyvsvJGA967eanX - Valid credentials +-- | Statistics +-- |_ Performed 60 guesses in 602 seconds, average tps: 0 +-- +-- @args mikrotik-routerous-brute.threads sets the number of threads. Default: 1 +-- +--- + +author = "Paulino Calderon " +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"discovery", "brute"} + +local shortport = require "shortport" +local comm = require "comm" +local brute = require "brute" +local creds = require "creds" +local stdnse = require "stdnse" +local openssl = stdnse.silent_require "openssl" + +portrule = shortport.portnumber(8728, "tcp") + +Driver = +{ + new = function(self, host, port, options ) + local o = { host = host, port = port, options = options } + setmetatable(o, self) + self.__index = self + o.emptypass = true + return o + end, + + connect = function( self ) + self.s = nmap.new_socket("tcp") + self.s:set_timeout(self.options['timeout']) + return self.s:connect(self.host, self.port, "tcp") + end, + + login = function( self, username, password ) + local status, data, try + data = bin.pack("cAx", 0x6,"/login") + + --Connect to service and obtain the challenge response + try = nmap.new_try(function() return false end) + try(self.s:send(data)) + data = try(self.s:receive_bytes(50)) + stdnse.print_debug(1, "%s:Response #1:%s", SCRIPT_NAME, data) + local _, _, ret = string.find(data, '!done%%=ret=(.+)') + + --If we find the challenge value we continue the connection process + if ret then + stdnse.print_debug(1, "%s:Challenge value found:%s", SCRIPT_NAME, ret) + local md5str = bin.pack("xAA", password, bin.pack("H", ret)) --appends pwd and challenge + local chksum = stdnse.tohex(openssl.md5(md5str)) + local user_l = username:len()+6 --we add six because of the string "=name=" + local login_pkt = bin.pack("cAcAcAx", 0x6, "/login", user_l, "=name="..username, 0x2c, "=response=00"..chksum) + try(self.s:send(login_pkt)) + data = try(self.s:receive_bytes(50)) + stdnse.print_debug(1, "%s:Response #2:%s", SCRIPT_NAME, data) + if data then + if string.find(data, "message=cannot") == nil then + local c = creds.Credentials:new(SCRIPT_NAME, self.host, self.port ) + c:add(username, password, creds.State.VALID ) + end + end + end + return false, brute.Error:new( "Incorrect password" ) + end, + + disconnect = function( self ) + return self.s:close() + end +} + +action = function(host, port) + local result + local thread_num = stdnse.get_script_args(SCRIPT_NAME..".threads") or 1 + local options = {timeout = 5000} + local bengine = brute.Engine:new(Driver, host, port, options) + + bengine:setMaxThreads(thread_num) + bengine.options.script_name = SCRIPT_NAME + _, result = bengine:start() + return result +end diff --git a/scripts/script.db b/scripts/script.db index 385749073..6315ea75b 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -284,6 +284,7 @@ Entry { filename = "memcached-info.nse", categories = { "discovery", "safe", } } Entry { filename = "metasploit-info.nse", categories = { "intrusive", "safe", } } Entry { filename = "metasploit-msgrpc-brute.nse", categories = { "brute", "intrusive", } } Entry { filename = "metasploit-xmlrpc-brute.nse", categories = { "brute", "intrusive", } } +Entry { filename = "mikrotik-routeros-brute.nse", categories = { "brute", "discovery", } } Entry { filename = "mmouse-brute.nse", categories = { "brute", "intrusive", } } Entry { filename = "mmouse-exec.nse", categories = { "intrusive", } } Entry { filename = "modbus-discover.nse", categories = { "discovery", "intrusive", } } @@ -379,6 +380,7 @@ Entry { filename = "rsync-brute.nse", categories = { "brute", "intrusive", } } Entry { filename = "rsync-list-modules.nse", categories = { "discovery", "safe", } } Entry { filename = "rtsp-methods.nse", categories = { "default", "safe", } } Entry { filename = "rtsp-url-brute.nse", categories = { "brute", "intrusive", } } +Entry { filename = "s7-info.nse", categories = { "discovery", "intrusive", } } Entry { filename = "samba-vuln-cve-2012-1182.nse", categories = { "intrusive", "vuln", } } Entry { filename = "servicetags.nse", categories = { "default", "discovery", "safe", } } Entry { filename = "sip-brute.nse", categories = { "brute", "intrusive", } } @@ -432,6 +434,7 @@ Entry { filename = "socks-open-proxy.nse", categories = { "default", "discovery" Entry { filename = "ssh-hostkey.nse", categories = { "default", "discovery", "safe", } } Entry { filename = "ssh2-enum-algos.nse", categories = { "discovery", "safe", } } Entry { filename = "sshv1.nse", categories = { "default", "safe", } } +Entry { filename = "ssl-ccs-injection.nse", categories = { "safe", "vuln", } } Entry { filename = "ssl-cert.nse", categories = { "default", "discovery", "safe", } } Entry { filename = "ssl-date.nse", categories = { "default", "discovery", "safe", } } Entry { filename = "ssl-enum-ciphers.nse", categories = { "discovery", "intrusive", } }