1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-07 13:11:28 +00:00
Files
nmap/scripts/sip-brute.nse
tomsellers 035ae9e9b1 Updated account status text in brute force password discovery scripts in an effort to make the reporting more consistent across all scripts. This will have an impact on any code that parses these values.
In the case of a few of these scripts the only thing that was updated was the example text as the scripts relied on the creds library which handles the strings internally.
2011-09-11 12:13:13 +00:00

108 lines
3.3 KiB
Lua
Executable File

description = [[
Performs brute force password auditing against Session Initiation Protocol (SIP - http://en.wikipedia.org/wiki/Session_Initiation_Protocol) accounts. This protocol is most commonly associated with VoIP sessions.
]]
---
-- @usage
-- nmap -sU -p 5060 <target> --script=sip-brute
--
-- PORT STATE SERVICE
-- 5060/udp open|filtered sip
-- | sip-brute:
-- | Accounts
-- | 1000:password123 => Valid credentials
-- | Statistics
-- |_ Performed 5010 guesses in 3 seconds, average tps: 1670
-- Version 0.1
-- Created 04/03/2011 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
author = "Patrik Karlsson"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"intrusive", "auth"}
require "shortport"
require "sip"
require "brute"
require "creds"
portrule = shortport.port_or_service(5060, "sip", "udp")
Driver = {
new = function(self, host, port)
local o = {}
setmetatable(o, self)
self.__index = self
o.host = host
o.port = port
return o
end,
connect = function( self )
self.helper = sip.Helper:new(self.host, self.port, { expires = 0 })
local status, err = self.helper:connect()
if ( not(status) ) then
return "ERROR: Failed to connect to SIP server"
end
return true
end,
login = function( self, username, password )
self.helper:setCredentials(username, password)
status, err = self.helper:register()
if ( not(status) ) then
-- The 3CX System has an anti-hacking option that triggers after
-- a certain amount of guesses. This protection basically prevents
-- any connection from the offending IP at an application level.
if ( err:match("^403 Forbidden") ) then
local err = brute.Error:new("The systems seems to have blocked our IP")
err:setAbort( true )
return false, err
end
return false, brute.Error:new( "Incorrect password" )
end
return true, brute.Account:new(username, password, creds.State.VALID)
end,
disconnect = function(self) return self.helper:close() end,
}
-- Function used to check if we can distinguish existing from non-existing
-- accounts. In order to do so we send a semi-random username and password
-- and interpret the response. Some servers will respond as if the login
-- was successful which makes it impossible to tell successfull logins
-- from non-existing accounts apart.
local function checkBadUser(host, port)
local user = "baduser-" .. math.random(10000)
local pass = "badpass-" .. math.random(10000)
local helper = sip.Helper:new(host, port, { expires = 0 })
print(user, pass)
local status, err = helper:connect()
if ( not(status) ) then return false, "ERROR: Failed to connect" end
helper:setCredentials(user, pass)
local status, err = helper:register()
helper:close()
return status, err
end
action = function(host, port)
local force = stdnse.get_script_args("sip-brute.force")
if ( not(force) ) then
local status = checkBadUser(host, port)
if ( status ) then
return "\nERROR: Cannot detect non-existing user accounts, this will result in:\n" ..
" * Non-exisiting accounts being detected as found\n" ..
" * Passwords for existing accounts being correctly detected\n\n" ..
"Supply the sip-brute.force argument to override"
end
end
local engine = brute.Engine:new(Driver, host, port)
engine.options.script_name = SCRIPT_NAME
local status, result = engine:start()
return result
end