1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-16 04:39:03 +00:00

Add omp2-brute and omp2-enum-targets from Henri Doreau.

This commit is contained in:
david
2011-04-20 23:44:16 +00:00
parent 3447e2a6a2
commit fef214063a
5 changed files with 393 additions and 0 deletions

View File

@@ -1,5 +1,9 @@
# Nmap Changelog ($Id$); -*-text-*-
o [NSE] Added omp2-brute and omp2-enum-targets, which respectively get
authentication credentials and then a list of scanning targets from
the OpenVAS Management Protocol. [Henri Doreau]
o [NSE] Added backorifice-info from Gorjan Petrovski, which retrieves
lots of system information from a BackOrifice server.

179
nselib/omp2.lua Normal file
View File

@@ -0,0 +1,179 @@
---
-- This library was written to ease interaction with OpenVAS Manager servers
-- using OMP (OpenVAS Management Protocol) version 2.
--
-- A very small subset of the protocol is implemented.
-- * Connection/authentication
-- * Targets enumeration
--
-- The library can also store accounts in the registry to share them between
-- scripts.
--
-- The complete protocol documentation is available on the official OpenVAS
-- website: http://www.openvas.org/omp-2-0.html
--
-- Sample use:
-- <code>
-- local session = omp2.Session:new()
-- local status, err = session:connect(host, port)
-- local status, err = session:authenticate(username, password)
-- ...
-- session:close()
-- </code>
--
-- @author Henri Doreau
-- @copyright Same as Nmap -- See http://nmap.org/book/man-legal.html
--
-- @args omp2.username The username to use for authentication.
-- @args omp2.password The password to use for authentication.
--
module(... or "omp2", package.seeall)
require("stdnse")
require("nmap")
local HAVE_SSL = false
if pcall(require,'openssl') then
HAVE_SSL = true
end
--- A Session class holds connection and interaction with the server
Session = {
--- Creates a new session object
new = function(self, o)
o = o or {}
setmetatable(o, self)
self.__index = self
o.username = nmap.registry.args["omp2.username"]
o.password = nmap.registry.args["omp2.password"]
o.socket = nmap.new_socket()
return o
end,
--- Establishes the (SSL) connection to the remote server
connect = function(self, host, port)
if not HAVE_SSL then
return false, "The OMP2 module requires OpenSSL support"
end
return self.socket:connect(host, port, "ssl")
end,
--- Closes connection
close = function(self)
return self.socket:close()
end,
--- Attempts to authenticate on the current connection
authenticate = function(self, username, password)
local status, err, xmldata
-- TODO escape credentials
status, err = self.socket:send("<authenticate><credentials>"
.. "<username>" .. username .. "</username>"
.. "<password>" .. password .. "</password>"
.. "</credentials></authenticate>")
if not status then
stdnse.print_debug("ERROR: %s", err)
return false, err
end
status, xmldata = self.socket:receive()
if not status then
stdnse.print_debug("ERROR: %s", xmldata)
return false, xmldata
end
return xmldata:match('status="200"')
end,
--- Lists targets defined on the remote server
ls_targets = function(self)
local status, err, xmldata
local res, target_names, target_hosts = {}, {}, {}
status, err = self.socket:send("<get_targets/>")
if not status then
stdnse.print_debug("ERROR: %s", err)
return false, err
end
status, xmldata = self.socket:receive()
if not status then
stdnse.print_debug("ERROR: %s", xmldata)
return false, xmldata
end
-- As NSE has no XML parser yet, we use regexp to extract the data from the
-- XML output. Targets are defined as a name and the corresponding host(s).
-- Thus we gather both and return an associative array, using names as keys
-- and hosts as values.
local i = 0
for name in xmldata:gmatch("<name>(.-)</name>") do
-- XXX this is hackish: skip the second and third "<name>" tags, as they
-- describe other components than the targets.
-- see: http://www.openvas.org/omp-2-0.html#command_get_targets
if i % 3 == 0 then
table.insert(target_names, name)
end
i = i + 1
end
for hosts in xmldata:gmatch("<hosts>(.-)</hosts>") do
table.insert(target_hosts, hosts)
end
for i, _ in ipairs(target_names) do
res[target_names[i]] = target_hosts[i]
end
return res
end,
}
--- Registers OMP2 credentials for a given host
function add_account(host, username, password)
if not nmap.registry[host.ip] then
nmap.registry[host.ip] = {}
end
if not nmap.registry[host.ip]["omp2accounts"] then
nmap.registry[host.ip]["omp2accounts"] = {}
end
table.insert(nmap.registry[host.ip]["omp2accounts"], {["username"] = username, ["password"] = password})
end
--- Retrieves the list of accounts for a given host
function get_accounts(host)
local accounts = {}
local username, password
username = nmap.registry.args["omp2.username"]
password = nmap.registry.args["omp2.password"]
if username and password then
table.insert(accounts, {["username"] = username, ["password"] = password})
end
if nmap.registry[host.ip] and nmap.registry[host.ip]["omp2accounts"] then
for _, account in pairs(nmap.registry[host.ip]["omp2accounts"]) do
table.insert(accounts, account)
end
end
if #accounts > 0 then
return accounts
end
return nil
end

83
scripts/omp2-brute.nse Normal file
View File

@@ -0,0 +1,83 @@
description = [[
Performs brute force password auditing against the OpenVAS manager using OMPv2.
]]
---
-- @usage
-- nmap -p 9390 --script omp2-brute <target>
--
-- @output
-- PORT STATE SERVICE REASON
-- 9390/tcp open openvas syn-ack
-- | svn-brute:
-- | Accounts
-- |_ admin:secret => Login correct
--
author = "Henri Doreau"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"auth", "intrusive"}
require("omp2")
require("nmap")
require("brute")
require("shortport")
portrule = shortport.port_or_service(9390, "openvas")
Driver = {
new = function(self, host, port)
local o = {}
setmetatable(o, self)
self.__index = self
o.host = host
o.port = port
o.session = omp2.Session:new()
return o
end,
--- Connects to the OpenVAS Manager
--
-- @return status boolean for connection success/failure
-- @return err string describing the error on failure
connect = function(self)
return self.session:connect(self.host, self.port)
end,
--- Closes connection
--
-- @return status boolean for closing success/failure
disconnect = function(self)
return self.session:close()
end,
--- Attempts to login the the OpenVAS Manager using a given username/password
-- couple. Store the credentials in the registry on success.
--
-- @param username string containing the login username
-- @param password string containing the login password
-- @return status boolean for login success/failure
-- @return err string describing the error on failure
login = function(self, username, password)
if self.session:authenticate(username, password) then
-- store the account for possible future use
omp2.add_account(self.host, username, password)
return true, brute.Account:new(username, password, "OPEN")
else
return false, brute.Error:new("login failed")
end
end,
--- Deprecated
check = function(self)
return true
end,
}
action = function(host, port)
local status, result = brute.Engine:new(Driver, host, port):start()
return result
end

View File

@@ -0,0 +1,125 @@
description = [[
Attempts to get the list of targets from an OpenVAS Manager server.
The script authenticates on the manager using provided or previously cracked
credentials and gets the list of defined targets for each account.
These targets will be added to the scanning queue in case
<code>newtargets</code> global variable is set.
]]
---
-- @usage
-- nmap -p 9390 --script omp2-brute,omp2-enum-targets <target>
--
-- @usage
-- nmap -p 9390 --script omp2-enum-targets --script-args omp2.username=admin,omp2.password=secret <target>
--
-- @output
-- PORT STATE SERVICE
-- 9390/tcp open openvas
-- | omp2-enum-targets:
-- |
-- | Targets for account admin:
-- | TARGET HOSTS
-- | Sales network 192.168.20.0/24
-- | Production network 192.168.30.0/24
-- |_ Firewall 192.168.1.254
--
author = "Henri Doreau"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"}
dependencies = {"omp2-brute"}
require("tab")
require("omp2")
require("target")
require("stdnse")
require("shortport")
portrule = shortport.port_or_service(9390, "openvas")
--- Return the list of targets defined for a given user
--
-- @param host the target host table
-- @param port the targetted OMP port
-- @param username the username to use to login
-- @param password the password to use to login
-- @return the list of targets for this user or nil
local function account_enum_targets(host, port, username, password)
local targets
local session = omp2.Session:new()
local status, err = session:connect(host, port)
if not status then
stdnse.print_debug("%s: connection failure (%s)", SCRIPT_NAME, err)
return nil
end
if session:authenticate(username, password) then
targets = session:ls_targets()
else
stdnse.print_debug("%s: authentication failure (%s:%s)", SCRIPT_NAME, username, password)
end
session:close()
return targets
end
--- Generate the output string representing the list of discovered targets
--
-- @param targets the list of targets as a name->hosts mapping
-- @return the array as a formatted string
local function report(targets)
local outtab = tab.new()
tab.add(outtab, 1, "TARGET")
tab.add(outtab, 2, "HOSTS")
tab.nextrow(outtab)
for name, hosts in pairs(targets) do
tab.addrow(outtab, name, hosts)
end
return tab.dump(outtab)
end
action = function(host, port)
local results = {}
local credentials = omp2.get_accounts(host)
if not credentials then
-- unable to authenticate on the server
return "No valid account available!"
end
for _, account in pairs(credentials) do
local username, password = account.username, account.password
local targets = account_enum_targets(host, port, username, password)
if targets ~= nil then
table.insert(results, "\nTargets for account " .. username .. ":")
table.insert(results, report(targets))
else
table.insert(results, "\nNo targets found for account " .. username)
end
if target.ALLOW_NEW_TARGETS and targets ~= nil then
stdnse.print_debug("%s: adding new targets %s", SCRIPT_NAME, stdnse.strjoin(", ", targets))
target.add(unpack(targets))
end
end
return stdnse.format_output(true, results)
end

View File

@@ -119,6 +119,8 @@ Entry { filename = "nping-brute.nse", categories = { "auth", "intrusive", } }
Entry { filename = "nrpe-enum.nse", categories = { "discovery", "intrusive", } }
Entry { filename = "ntp-info.nse", categories = { "default", "discovery", "safe", } }
Entry { filename = "ntp-monlist.nse", categories = { "discovery", "intrusive", } }
Entry { filename = "omp2-brute.nse", categories = { "auth", "intrusive", } }
Entry { filename = "omp2-enum-targets.nse", categories = { "discovery", "safe", } }
Entry { filename = "oracle-brute.nse", categories = { "auth", "intrusive", } }
Entry { filename = "oracle-enum-users.nse", categories = { "auth", "intrusive", } }
Entry { filename = "oracle-sid-brute.nse", categories = { "auth", "intrusive", } }