diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 07:42:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 07:42:04 +0000 |
commit | 0d47952611198ef6b1163f366dc03922d20b1475 (patch) | |
tree | 3d840a3b8c0daef0754707bfb9f5e873b6b1ac13 /nselib/omp2.lua | |
parent | Initial commit. (diff) | |
download | nmap-0d47952611198ef6b1163f366dc03922d20b1475.tar.xz nmap-0d47952611198ef6b1163f366dc03922d20b1475.zip |
Adding upstream version 7.94+git20230807.3be01efb1+dfsg.upstream/7.94+git20230807.3be01efb1+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'nselib/omp2.lua')
-rw-r--r-- | nselib/omp2.lua | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/nselib/omp2.lua b/nselib/omp2.lua new file mode 100644 index 0000000..83c38cd --- /dev/null +++ b/nselib/omp2.lua @@ -0,0 +1,181 @@ +--- +-- 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 https://nmap.org/book/man-legal.html +-- +-- @args omp2.username The username to use for authentication. +-- @args omp2.password The password to use for authentication. +-- + +local nmap = require "nmap" +local stdnse = require "stdnse" +local table = require "table" +_ENV = stdnse.module("omp2", stdnse.seeall) + +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, socket) + + local o = {} + setmetatable(o, self) + self.__index = self + + o.username = nmap.registry.args["omp2.username"] + o.password = nmap.registry.args["omp2.password"] + o.socket = socket or 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.debug1("ERROR: %s", err) + return false, err + end + + status, xmldata = self.socket:receive() + if not status then + stdnse.debug1("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.debug1("ERROR: %s", err) + return false, err + end + + status, xmldata = self.socket:receive() + if not status then + stdnse.debug1("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 + + +return _ENV; |