1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-07 21:21:31 +00:00
Files
nmap/scripts/nexpose-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

82 lines
2.8 KiB
Lua

local brute = require "brute"
local creds = require "creds"
local http = require "http"
local shortport = require "shortport"
local stdnse = require "stdnse"
local openssl = stdnse.silent_require "openssl"
description=[[
Performs brute force password auditing against a Nexpose vulnerability scanner using the API 1.1. By default it only tries three guesses per username to avoid target account lockout.
]]
---
-- @usage
-- nmap --script nexpose-brute -p 3780 <ip>
--
-- @output
-- PORT STATE SERVICE REASON VERSION
-- 3780/tcp open ssl/nexpose syn-ack NeXpose NSC 0.6.4
-- | nexpose-brute:
-- | Accounts
-- | nxadmin:nxadmin - Valid credentials
-- | Statistics
-- |_ Performed 5 guesses in 1 seconds, average tps: 5
--
-- As the Nexpose application enforces account lockout after 4 incorrect login
-- attempts, the script performs only 3 guesses per default. This can be
-- altered by supplying the <code>brute.guesses</code> argument a different
-- value or 0 (zero) to guess the whole dictionary.
author = "Vlatko Kosturjak"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"intrusive", "brute"}
portrule = shortport.port_or_service(3780, "nexpose", "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 ) return true end,
login = function( self, username, password )
local postdata='<?xml version="1.0" encoding="UTF-8"?><LoginRequest sync-id="1" user-id="'..username..'" password="'..password..'"></LoginRequest>'
local response = http.post( self.host, self.port, '/api/1.1/xml', { no_cache = true, header = { ["Content-Type"] = "text/xml" } }, nil, postdata )
if (not(response)) then
local err = brute.Error:new( "Couldn't send/receive HTTPS request" )
err:setRetry( true )
return false, err
end
if (response.body == nil or response.body:match('<LoginResponse.*success="0"')) then
stdnse.debug2("Bad login: %s/%s", username, password)
return false, brute.Error:new( "Bad login" )
elseif (response.body:match('<LoginResponse.*success="1"')) then
stdnse.debug1("Good login: %s/%s", username, password)
return true, creds.Account:new(username, password, creds.State.VALID)
end
stdnse.debug1("WARNING: Unhandled response: %s", response.body)
return false, brute.Error:new( "incorrect response from server" )
end,
disconnect = function( self ) return true end,
}
action = function(host, port)
local engine = brute.Engine:new(Driver, host, port)
engine.options.script_name = SCRIPT_NAME
engine.options.max_guesses = tonumber(stdnse.get_script_args('brute.guesses')) or 3
local status, result = engine:start()
return result
end