local creds = require "creds" local nmap = require "nmap" local shortport = require "shortport" local stdnse = require "stdnse" local mongodb = stdnse.silent_require "mongodb" description = [[ Attempts to get build info and server status from a MongoDB database. ]] --- -- @usage -- nmap -p 27017 --script mongodb-info -- -- @args mongodb-info.db Database to check. Default: admin -- -- @output -- PORT STATE SERVICE REASON -- 27017/tcp open unknown syn-ack -- | mongodb-info: -- | MongoDB Build info -- | ok = 1 -- | bits = 64 -- | version = 1.3.1- -- | gitVersion = d1f0ffe23bcd667f4ed18a27b5fd31a0beab5535 -- | sysInfo = Linux domU-12-31-39-06-79-A1 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_41 -- | Server status -- | opcounters -- | delete = 0 -- | insert = 3 -- | getmore = 0 -- | update = 0 -- | query = 10 -- | connections -- | available = 19999 -- | current = 1 -- | uptime = 747 -- | mem -- | resident = 9 -- | virtual = 210 -- | supported = true -- | mapped = 80 -- | ok = 1 -- | globalLock -- | ratio = 0.010762343463949 -- | lockTime = 8037112 -- | totalTime = 746780850 -- | extra_info -- | heap_usage_bytes = 117120 -- | note = fields vary by platform -- |_ page_faults = 0 -- version 0.3 -- Created 01/12/2010 - v0.1 - created by Martin Holst Swende -- Revised 01/03/2012 - v0.3 - added authentication support author = "Martin Holst Swende" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"default", "discovery", "safe"} dependencies = {"mongodb-brute"} local arg_db = stdnse.get_script_args(SCRIPT_NAME .. ".db") or "admin" portrule = shortport.port_or_service({27017}, {"mongodb"}) function action(host,port) local socket = nmap.new_socket() -- set a reasonable timeout value socket:set_timeout(10000) -- do some exception / cleanup local catch = function() socket:close() end local try = nmap.new_try(catch) try( socket:connect(host, port) ) local req, statusresponse, buildinfo, err -- ugliness to allow creds.mongodb to work, as the port is not recognized -- as mongodb, unless a service scan was run local ps = port.service port.service = 'mongodb' local c = creds.Credentials:new(creds.ALL_DATA, host, port) for cred in c:getCredentials(creds.State.VALID + creds.State.PARAM) do local status, err = mongodb.login(socket, arg_db, cred.user, cred.pass) if ( not(status) ) then return err end end port.service = ps local status, packet = mongodb.serverStatusQuery() if not status then return packet end local statQResult, buildQResult status,statQResult = mongodb.query(socket, packet) if not status then return statQResult end port.version.name ='mongodb' port.version.product='MongoDB' port.version.name_confidence = 10 nmap.set_port_version(host,port) status, packet = mongodb.buildInfoQuery() if not status then return packet end status, buildQResult = mongodb.query(socket,packet ) if not status then stdnse.log_error(buildQResult) return buildQResult end local versionNumber = buildQResult['version'] port.version.product='MongoDB '..versionNumber nmap.set_port_version(host,port) local stat_out = mongodb.queryResultToTable(statQResult) local build_out = mongodb.queryResultToTable(buildQResult) local output = {"MongoDB Build info",build_out,"Server status",stat_out} return stdnse.format_output(true, output ) end