From 0d47952611198ef6b1163f366dc03922d20b1475 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 09:42:04 +0200 Subject: Adding upstream version 7.94+git20230807.3be01efb1+dfsg. Signed-off-by: Daniel Baumann --- scripts/pgsql-brute.nse | 169 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 scripts/pgsql-brute.nse (limited to 'scripts/pgsql-brute.nse') diff --git a/scripts/pgsql-brute.nse b/scripts/pgsql-brute.nse new file mode 100644 index 0000000..a239df4 --- /dev/null +++ b/scripts/pgsql-brute.nse @@ -0,0 +1,169 @@ +local nmap = require "nmap" +local pgsql = require "pgsql" +local shortport = require "shortport" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" +local unpwdb = require "unpwdb" + +local openssl = stdnse.silent_require "openssl" + +description = [[ +Performs password guessing against PostgreSQL. +]] + +--- +-- @usage +-- nmap -p 5432 --script pgsql-brute +-- +-- @output +-- 5432/tcp open pgsql +-- | pgsql-brute: +-- | root: => Valid credentials +-- |_ test:test => Valid credentials +-- +-- @args pgsql.nossl If set to 1 or true, disables SSL. +-- @args pgsql.version Force protocol version 2 or 3. + +-- SSL Encryption +-- -------------- +-- We need to handle several cases of SSL support +-- o SSL can be supported on a server level +-- o SSL can be enforced per host or network level +-- o SSL can be denied per host or network level + +author = "Patrik Karlsson" +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" +categories = {"intrusive", "brute"} + + +-- Version 0.4 +-- Created 01/15/2010 - v0.1 - created by Patrik Karlsson +-- Revised 02/20/2010 - v0.2 - moved version detection to pgsql library +-- Revised 03/04/2010 - v0.3 - added code from ssh-hostkey.nse to check for SSL support +-- - added support for trusted authentication method +-- Revised 09/10/2011 - v0.4 - changed account status text to be more consistent with other *-brute scripts + +portrule = shortport.port_or_service(5432, "postgresql") + +--- Connect a socket to the server with or without SSL +-- +-- @param host table as received by the action function +-- @param port table as received by the action function +-- @param ssl boolean, if true connect using SSL +-- @return socket connected to server +local function connectSocket(host, port, ssl) + local socket = nmap.new_socket() + + -- set a reasonable timeout value + socket:set_timeout(5000) + socket:connect(host, port) + + -- let's be responsible and avoid sending communication in the clear + if ( ssl ) then + local status = pgsql.requestSSL(socket) + if ( status ) then + socket:reconnect_ssl() + end + end + return socket +end + +action = function( host, port ) + + local status, response, ssl_enable, output + local result, response, status, nossl = {}, nil, nil, false + local valid_accounts = {} + local pg + + if ( nmap.registry.args['pgsql.version'] ) then + if ( tonumber(nmap.registry.args['pgsql.version']) == 2 ) then + pg = pgsql.v2 + elseif ( tonumber(nmap.registry.args['pgsql.version']) == 3 ) then + pg = pgsql.v3 + else + stdnse.debug1("Unsupported version %s", nmap.registry.args['pgsql.version']) + return + end + else + pg = pgsql.detectVersion(host, port ) + end + + local usernames, passwords + status, usernames = unpwdb.usernames() + if not status then + return stdnse.format_output(false, usernames) + end + + status, passwords = unpwdb.passwords() + if not status then + return stdnse.format_output(false, passwords) + end + + -- If the user explicitly does not disable SSL, enforce it + if ( ( nmap.registry.args['pgsql.nossl'] == 'true' ) or + ( nmap.registry.args['pgsql.nossl'] == '1' ) ) then + nossl = true + end + + for username in usernames do + ssl_enable = not(nossl) + for password in passwords do + stdnse.debug1("Trying %s/%s ...", username, password ) + local socket = connectSocket( host, port, ssl_enable ) + status, response = pg.sendStartup(socket, username, username) + + -- if nossl is enforced by the user, we're done + if ( not(status) and nossl ) then + break + end + + -- SSL failed, this can occur due to: + -- 1. The server does not do SSL + -- 2. SSL was denied on a per host or network level + -- + -- Attempt SSL connection + if ( not(status) ) then + socket:close() + ssl_enable = false + socket = connectSocket( host, port, ssl_enable ) + status, response = pg.sendStartup(socket, username, username) + if (not(status)) then + if ( response:match("no pg_hba.conf entry for host") ) then + stdnse.debug1("The host was denied access to db \"%s\" as user \"%s\", aborting ...", username, username ) + break + else + stdnse.debug1("sendStartup returned: %s", response ) + break + end + end + end + + -- Do not attempt to authenticate if authentication type is trusted + if ( response.authtype ~= pgsql.AuthenticationType.Success ) then + status, response = pg.loginRequest( socket, response, username, password, response.salt) + end + + if status then + -- Add credentials for other pgsql scripts to use + if nmap.registry.pgsqlusers == nil then + nmap.registry.pgsqlusers = {} + end + nmap.registry.pgsqlusers[username]=password + if ( response.authtype ~= pgsql.AuthenticationType.Success ) then + table.insert( valid_accounts, string.format("%s:%s => Valid credentials", username, password:len()>0 and password or "" ) ) + else + table.insert( valid_accounts, string.format("%s => Trusted authentication", username ) ) + end + break + end + socket:close() + end + passwords("reset") + end + + output = stdnse.format_output(true, valid_accounts) + + return output + +end -- cgit v1.2.3