mirror of
https://github.com/nmap/nmap.git
synced 2025-12-09 22:21:29 +00:00
Many scripts were documented as using timespecs (10s, 5000ms, etc) for timeout script-args, but one 1 or 2 actually did. Now all timeout script-args will accept timespecs, except those which took a number of milliseconds, which remain unchanged. Also fixed some documentation issues (missing script name in arg description, missing nsedoc for args, etc)
119 lines
3.0 KiB
Lua
119 lines
3.0 KiB
Lua
local brute = require "brute"
|
|
local creds = require "creds"
|
|
local nmap = require "nmap"
|
|
local shortport = require "shortport"
|
|
local stdnse = require "stdnse"
|
|
|
|
description = [[
|
|
Performs brute force password auditing against the RPA Tech Mobile Mouse
|
|
servers.
|
|
|
|
The Mobile Mouse server runs on OS X, Windows and Linux and enables remote
|
|
control of the keyboard and mouse from an iOS device. For more information:
|
|
http://mobilemouse.com/
|
|
]]
|
|
|
|
---
|
|
-- @usage
|
|
-- nmap --script mmouse-brute -p 51010 <host>
|
|
--
|
|
-- @output
|
|
-- PORT STATE SERVICE
|
|
-- 51010/tcp open unknown
|
|
-- | mmouse-brute:
|
|
-- | Accounts
|
|
-- | vanilla - Valid credentials
|
|
-- | Statistics
|
|
-- |_ Performed 1199 guesses in 23 seconds, average tps: 47
|
|
--
|
|
-- @args mmouse-brute.timeout socket timeout (milliseconds) for connecting to Mobile Mouse (default 5000)
|
|
|
|
author = "Patrik Karlsson"
|
|
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
|
categories = {"intrusive", "brute"}
|
|
|
|
|
|
local arg_timeout = stdnse.get_script_args(SCRIPT_NAME .. ".timeout") or 5000
|
|
|
|
portrule = shortport.port_or_service(51010, "mmouse", "tcp")
|
|
|
|
Driver = {
|
|
|
|
new = function(self, host, port)
|
|
local o = { host = host, port = port }
|
|
setmetatable(o, self)
|
|
self.__index = self
|
|
return o
|
|
end,
|
|
|
|
connect = function( self )
|
|
self.socket = nmap.new_socket()
|
|
self.socket:set_timeout(arg_timeout)
|
|
return self.socket:connect(self.host, self.port)
|
|
end,
|
|
|
|
login = function( self, username, password )
|
|
local devid = "0123456789abcdef0123456789abcdef0123456"
|
|
local devname = "Lord Vaders iPad"
|
|
local suffix = "2".."\30".."2".."\04"
|
|
local auth = ("CONNECT\30%s\30%s\30%s\30%s"):format(password, devid, devname, suffix)
|
|
|
|
local status = self.socket:send(auth)
|
|
if ( not(status) ) then
|
|
local err = brute.Error:new( "Failed to send data to server" )
|
|
err:setRetry( true )
|
|
return false, err
|
|
end
|
|
|
|
local status, data = self.socket:receive_buf("\04", true)
|
|
|
|
if (data:match("^CONNECTED\30([^\30]*)") == "NO" ) then
|
|
return false, brute.Error:new( "Incorrect password" )
|
|
elseif ( data:match("^CONNECTED\30([^\30]*)") == "YES" ) then
|
|
return true, brute.Account:new("", password, creds.State.VALID)
|
|
end
|
|
|
|
local err = brute.Error:new("An unexpected error occured, retrying ...")
|
|
err:setRetry(true)
|
|
return false, err
|
|
end,
|
|
|
|
disconnect = function(self)
|
|
self.socket:close()
|
|
end,
|
|
|
|
}
|
|
|
|
local function hasPassword(host, port)
|
|
local driver = Driver:new(host, port)
|
|
if ( not(driver:connect()) ) then
|
|
error("Failed to connect to server")
|
|
end
|
|
local status = driver:login(nil, "nmap")
|
|
driver:disconnect()
|
|
|
|
return not(status)
|
|
end
|
|
|
|
|
|
action = function(host, port)
|
|
|
|
if ( not(hasPassword(host, port)) ) then
|
|
return "\n Server has no password"
|
|
end
|
|
|
|
local status, result
|
|
local engine = brute.Engine:new(Driver, host, port )
|
|
|
|
engine.options.script_name = SCRIPT_NAME
|
|
engine.options.firstonly = true
|
|
engine.options:setOption( "passonly", true )
|
|
|
|
-- mouse server does not behave well when multiple threads are guessing
|
|
engine:setMaxThreads(1)
|
|
|
|
status, result = engine:start()
|
|
|
|
return result
|
|
end
|