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/mysql-dump-hashes.nse | 102 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 scripts/mysql-dump-hashes.nse (limited to 'scripts/mysql-dump-hashes.nse') diff --git a/scripts/mysql-dump-hashes.nse b/scripts/mysql-dump-hashes.nse new file mode 100644 index 0000000..b243ac8 --- /dev/null +++ b/scripts/mysql-dump-hashes.nse @@ -0,0 +1,102 @@ +local mysql = require "mysql" +local nmap = require "nmap" +local shortport = require "shortport" +local stdnse = require "stdnse" + +description = [[ +Dumps the password hashes from an MySQL server in a format suitable for +cracking by tools such as John the Ripper. Appropriate DB privileges (root) are required. + +The username and password arguments take precedence +over credentials discovered by the mysql-brute and mysql-empty-password +scripts. +]] + +--- +-- @usage +-- nmap -p 3306 --script mysql-dump-hashes --script-args='username=root,password=secret' +-- +-- @output +-- PORT STATE SERVICE +-- 3306/tcp open mysql +-- | mysql-dump-hashes: +-- | root:*9B500343BC52E2911172EB52AE5CF4847604C6E5 +-- | debian-sys-maint:*92357EE43977D9228AC9C0D60BB4B4479BD7A337 +-- |_ toor:*14E65567ABDB5135D0CFD9A70B3032C179A49EE7 +-- +-- @args username the username to use to connect to the server +-- @args password the password to use to connect to the server +-- + +author = "Patrik Karlsson" +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" +categories = {"auth", "discovery", "safe"} + + +dependencies = {"mysql-empty-password", "mysql-brute"} + +portrule = shortport.port_or_service(3306, "mysql") + +local arg_username = stdnse.get_script_args(SCRIPT_NAME .. ".username") +local arg_password = stdnse.get_script_args(SCRIPT_NAME .. ".password") or "" + +local function fail(err) return stdnse.format_output(false, err) end + +local function getCredentials() + -- first, let's see if the script has any credentials as arguments? + if ( arg_username ) then + return { [arg_username] = arg_password } + -- next, let's see if mysql-brute or mysql-empty-password brought us anything + elseif nmap.registry.mysqlusers then + -- do we have root credentials? + if nmap.registry.mysqlusers['root'] then + return { ['root'] = nmap.registry.mysqlusers['root'] } + else + -- we didn't have root, so let's make sure we loop over them all + return nmap.registry.mysqlusers + end + -- last, no dice, we don't have any credentials at all + end +end + +local function mysqlLogin(socket, username, password) + local status, response = mysql.receiveGreeting( socket ) + if ( not(status) ) then + return response + end + return mysql.loginRequest( socket, { authversion = "post41", charset = response.charset }, username, password, response.salt ) +end + + +action = function(host, port) + local creds = getCredentials() + if ( not(creds) ) then + stdnse.debug2("No credentials were supplied, aborting ...") + return + end + + local result = {} + for username, password in pairs(creds) do + local socket = nmap.new_socket() + if ( not(socket:connect(host, port)) ) then + return fail("Failed to connect to server") + end + + local status, response = mysqlLogin(socket, username, password) + if ( status ) then + local query = "SELECT DISTINCT CONCAT(user, ':', password) FROM mysql.user WHERE password <> ''" + local status, rows = mysql.sqlQuery( socket, query ) + socket:close() + if ( status ) then + result = mysql.formatResultset(rows, { noheaders = true }) + break + end + else + socket:close() + end + end + + if ( result ) then + return stdnse.format_output(true, result) + end +end -- cgit v1.2.3