1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-09 14:11:29 +00:00
Files
nmap/scripts/mmouse-brute.nse
dmiller f37ac44380 Move brute.Account to creds.Account
In addition to fitting better (brute library is the verb, creds library
is the noun), this will allow creds.lua to use creds.Account internally
where necessary (see subsequent commits)

Also change old references to string argument "OPEN" into
creds.State.VALID.
2014-09-23 05:23:13 +00:00

120 lines
3.1 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 for connecting to Mobile Mouse (default 5s)
author = "Patrik Karlsson"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"intrusive", "brute"}
local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout"))
arg_timeout = (arg_timeout or 5) * 1000
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, creds.Account:new("", password, creds.State.VALID)
end
local err = brute.Error:new("An unexpected error occurred, 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