summaryrefslogtreecommitdiffstats
path: root/scripts/murmur-version.nse
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/murmur-version.nse')
-rw-r--r--scripts/murmur-version.nse101
1 files changed, 101 insertions, 0 deletions
diff --git a/scripts/murmur-version.nse b/scripts/murmur-version.nse
new file mode 100644
index 0000000..433ff3d
--- /dev/null
+++ b/scripts/murmur-version.nse
@@ -0,0 +1,101 @@
+local comm = require "comm"
+local nmap = require "nmap"
+local shortport = require "shortport"
+local string = require "string"
+
+description = [[
+Detects the Murmur service (server for the Mumble voice communication
+client) versions 1.2.X.
+
+The Murmur server listens on a TCP (control) and a UDP (voice) port
+with the same port number. This script activates on both a TCP and UDP
+port version scan. In both cases probe data is sent only to the UDP
+port because it allows for a simple and informative ping command.
+
+The single probe will report on the server version, current user
+count, maximum users allowed on the server, and bandwidth used for
+voice communication. It is used by the Mumble client to ping known
+Murmur servers.
+
+The IP address from which service detection is being ran will most
+likely be temporarily banned by the target Murmur server due to
+multiple incorrect handshakes (Nmap service probes). This ban makes
+identifying the service via TCP impossible in practice, but does not
+affect the UDP probe used by this script.
+
+It is possible to get a corrupt user count (usually +1) when doing a
+TCP service scan due to previous service probe connections affecting
+the server.
+
+See http://mumble.sourceforge.net/Protocol.
+]]
+
+---
+-- @output
+-- PORT STATE SERVICE VERSION
+-- 64740/tcp open murmur Murmur 1.2.4 (control port; users: 35; max. users: 100; bandwidth: 72000 b/s)
+-- 64740/udp open murmur Murmur 1.2.4 (voice port; users: 35; max. users: 100; bandwidth: 72000 b/s)
+
+author = "Marin Maržić"
+license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
+categories = { "version" }
+
+portrule = shortport.version_port_or_service({64738}, "murmur", {"tcp", "udp"})
+
+action = function(host, port)
+ local mutex = nmap.mutex("murmur-version:" .. host.ip .. ":" .. port.number)
+ mutex("lock")
+
+ if host.registry["murmur-version"] == nil then
+ host.registry["murmur-version"] = {}
+ end
+ -- Maybe the script already ran for this port number on another protocol
+ local r = host.registry["murmur-version"][port.number]
+ if r == nil then
+ r = {}
+ host.registry["murmur-version"][port.number] = r
+
+ local status, result = comm.exchange(
+ host, port.number, "\0\0\0\0abcdefgh", { proto = "udp", timeout = 3000 })
+ if not status then
+ mutex("done")
+ return
+ end
+
+ -- UDP port is open
+ nmap.set_port_state(host, { number = port.number, protocol = "udp" }, "open")
+
+ if not string.match(result, "^%z...abcdefgh............$") then
+ mutex("done")
+ return
+ end
+
+ -- Detected; extract relevant data
+ r.v_a, r.v_b, r.v_c, r.users, r.maxusers, r.bandwidth =
+ string.unpack(">BBB xxxxxxxx I4I4I4", result, 2)
+ end
+
+ mutex("done")
+
+ -- If the registry is empty the port was probed but Murmur wasn't detected
+ if next(r) == nil then
+ return
+ end
+
+ port.version.name = "murmur"
+ port.version.name_confidence = 10
+ port.version.product = "Murmur"
+ port.version.version = r.v_a .. "." .. r.v_b .. "." .. r.v_c
+ port.version.extrainfo = "; users: " .. r.users .. "; max. users: " ..
+ r.maxusers .. "; bandwidth: " .. r.bandwidth .. " b/s"
+ -- Add extra info depending on protocol
+ if port.protocol == "tcp" then
+ port.version.extrainfo = "control port" .. port.version.extrainfo
+ else
+ port.version.extrainfo = "voice port" .. port.version.extrainfo
+ end
+
+ nmap.set_port_version(host, port, "hardmatched")
+
+ return
+end