summaryrefslogtreecommitdiffstats
path: root/scripts/broadcast-dropbox-listener.nse
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/broadcast-dropbox-listener.nse')
-rw-r--r--scripts/broadcast-dropbox-listener.nse140
1 files changed, 140 insertions, 0 deletions
diff --git a/scripts/broadcast-dropbox-listener.nse b/scripts/broadcast-dropbox-listener.nse
new file mode 100644
index 0000000..9144539
--- /dev/null
+++ b/scripts/broadcast-dropbox-listener.nse
@@ -0,0 +1,140 @@
+local json = require "json"
+local nmap = require "nmap"
+local stdnse = require "stdnse"
+local tab = require "tab"
+local target = require "target"
+local table = require "table"
+
+description = [[
+Listens for the LAN sync information broadcasts that the Dropbox.com client
+broadcasts every 20 seconds, then prints all the discovered client IP
+addresses, port numbers, version numbers, display names, and more.
+
+If the <code>newtargets</code> script argument is given, all discovered Dropbox
+clients will be added to the Nmap target list rather than just listed in the
+output.
+]]
+
+---
+-- @usage
+-- nmap --script=broadcast-dropbox-listener
+-- nmap --script=broadcast-dropbox-listener --script-args=newtargets -Pn
+-- @output
+-- Pre-scan script results:
+-- | broadcast-dropbox-listener:
+-- | displayname ip port version host_int namespaces
+-- |_noob 192.168.0.110 17500 1.8 34176083 26135075
+--
+-- Pre-scan script results:
+-- | broadcast-dropbox-listener:
+-- | displayname ip port version host_int namespaces
+-- |_noob 192.168.0.110 17500 1.8 34176083 26135075
+-- Nmap scan report for 192.168.0.110
+-- Host is up (0.00073s latency).
+-- Not shown: 997 filtered ports
+-- PORT STATE SERVICE
+-- 139/tcp open netbios-ssn
+-- 445/tcp open microsoft-ds
+-- 1047/tcp open neod1
+
+author = {"Ron Bowes", "Mak Kolybabi", "Andrew Orr", "Russ Tait Milne"}
+license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
+categories = {"broadcast", "safe"}
+
+
+local DROPBOX_BROADCAST_PERIOD = 20
+local DROPBOX_PORT = 17500
+
+prerule = function()
+ return true
+end
+
+action = function()
+ -- Start listening for broadcasts.
+ local sock = nmap.new_socket("udp")
+ sock:set_timeout(2 * DROPBOX_BROADCAST_PERIOD * 1000)
+ local status, result = sock:bind(nil, DROPBOX_PORT)
+ if not status then
+ stdnse.debug1("Could not bind on port %d: %s", DROPBOX_PORT, result)
+ sock:close()
+ return
+ end
+
+ -- Keep track of the IDs we've already seen.
+ local ids = {}
+
+ -- Initialize the output table.
+ local results = tab.new(6)
+ tab.addrow(
+ results,
+ 'displayname',
+ 'ip',
+ 'port',
+ 'version',
+ 'host_int',
+ 'namespaces'
+ )
+
+ local status, result = sock:receive()
+ while status do
+ -- Parse JSON.
+ local status, info = json.parse(result)
+ if status then
+ -- Get IP address of broadcasting host.
+ local status, _, _, ip, _ = sock:get_info()
+ if not status then
+ stdnse.debug1("Failed to get socket info.")
+ break
+ end
+ stdnse.debug1("Received broadcast from host %s (%s).", info.displayname, ip)
+
+ -- Check if we've already seen this ID.
+ if ids[info.host_int] then
+ -- We can stop now, since we've seen the same ID twice
+ -- If ever a host sends a broadcast twice in a row, this will
+ -- artificially stop the listener. I can't think of a workaround
+ -- for now, so this will have to do.
+ break
+ end
+ ids[info.host_int] = true
+
+ -- Add host scan list.
+ if target.ALLOW_NEW_TARGETS then
+ target.add(ip)
+ end
+
+ -- Add host to list.
+ for _, key1 in pairs({"namespaces", "version"}) do
+ for key2, val in pairs(info[key1]) do
+ info[key1][key2] = tostring(info[key1][key2])
+ end
+ end
+ tab.addrow(
+ results,
+ info.displayname,
+ ip,
+ info.port,
+ table.concat(info.version, "."),
+ info.host_int,
+ table.concat(info.namespaces, ", ")
+ )
+
+ stdnse.debug1("Added host %s.", info.displayname)
+ end
+
+ status, result = sock:receive()
+ end
+
+ sock:close()
+
+ -- If no broadcasts received, don't output anything.
+ if not next(ids) then
+ return
+ end
+
+ -- Format table, without trailing newline.
+ results = tab.dump(results)
+ results = results:sub(1, #results - 1)
+
+ return "\n" .. results
+end