diff --git a/CHANGELOG b/CHANGELOG index 14f8ad466..f0dc194a1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Add freelancer-info to gather information about the Freelancer + game server. Also added a related version detection probe and UDP + protocol payload for detecting the service. [Marin Maržić] + o [Ncat] Fixed compilation when --without-liblua is specified in configure (an #include needed an ifdef guard). [Quentin Glidic] diff --git a/nmap-payloads b/nmap-payloads index 24d55fb98..a9b71e2ae 100644 --- a/nmap-payloads +++ b/nmap-payloads @@ -169,6 +169,11 @@ udp 2049 "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +# Freelancer game server status query +# http://sourceforge.net/projects/gameq/ +# (relevant files: games.ini, packets.ini, freelancer.php) +udp 2302 "\x00\x02\xf1\x26\x01\x26\xf0\x90\xa6\xf0\x26\x57\x4e\xac\xa0\xec\xf8\x68\xe4\x8d\x21" + # Sun Service Tag Discovery protocol (stdiscover) # http://arc.opensolaris.org/caselog/PSARC/2006/638/stdiscover_protocolv2.pdf # Would work better with a varying cookie; the second and later sends of this diff --git a/nmap-service-probes b/nmap-service-probes index 2ce7094c5..50025d0e8 100644 --- a/nmap-service-probes +++ b/nmap-service-probes @@ -12324,3 +12324,14 @@ rarity 9 ports 7887 match xmlsysd m|^Content-Length: [0-9]+\n\n<\?xml version=\"1\.0\"\?>\s*\s*\s*\s*([^<]*)\s*([^<]*)\s*\s*\s*\s*([^<]*)\s*\s*|s p/xmlsysd daemon/ h/$1/ i/IP: $2/ o/$3/ cpe:/a:wulfware:xmlsysd/ + +##############################NEXT PROBE############################## +# Freelancer game server status query +# http://sourceforge.net/projects/gameq/ +# (relevant files: games.ini, packets.ini, freelancer.php) +Probe UDP FreelancerStatus q|\x00\x02\xf1\x26\x01\x26\xf0\x90\xa6\xf0\x26\x57\x4e\xac\xa0\xec\xf8\x68\xe4\x8d\x21| +rarity 9 +ports 2302 + +match freelancer m|^\x00\x03\xf1\x26.{88}(.*)\0\0(?:.*?:){5}(.*)\0\0$|s p/Freelancer/ i/name: $P(1); description: $P(2)/ + diff --git a/scripts/freelancer-info.nse b/scripts/freelancer-info.nse new file mode 100644 index 000000000..09ffa8cd7 --- /dev/null +++ b/scripts/freelancer-info.nse @@ -0,0 +1,104 @@ +local comm = require "comm" +local nmap = require "nmap" +local shortport = require "shortport" +local string = require "string" +local bit = require "bit" +local stdnse = require "stdnse" + +description = [[ +Detects the Freelancer game server (FLServer.exe) service by sending a +status query UDP probe. + +When run as a version detection script (-sV), the script +will report on the server name, current number of players, maximum +number of players, and whether it has a password set. When run +explicitly (--script freelancer-info), the script will +additionally report on the server description, whether players can harm +other players, and whether new players are allowed. + +See http://sourceforge.net/projects/gameq/ +(relevant files: games.ini, packets.ini, freelancer.php) +]] + +-- @output +-- PORT STATE SERVICE REASON VERSION +-- 2302/udp open freelancer udp-response Freelancer (name: Discovery Freelancer RP 24/7; players: 152/225; password: no) +-- | freelancer-info: +-- | server name: Discovery Freelancer RP 24/7 +-- | server description: This is the official discovery freelancer RP server. To know more about the server, please visit www.discoverygc.com +-- | players: 152 +-- | max. players: 225 +-- | password: no +-- | allow players to harm other players: yes +-- |_ allow new players: yes +-- +-- @xmloutput +-- Discovery Freelancer RP 24/7 +-- This is the official discovery freelancer RP server. To know more about the server, please visit www.discoverygc.com +-- 152 +-- 225 +-- no +-- yes +-- yes + +author = "Marin Maržić" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = { "default", "discovery", "safe", "version" } + +portrule = shortport.version_port_or_service({2302}, "freelancer", "udp") + +action = function(host, port) + local status, data = comm.exchange(host, port.number, + "\x00\x02\xf1\x26\x01\x26\xf0\x90\xa6\xf0\x26\x57\x4e\xac\xa0\xec\xf8\x68\xe4\x8d\x21", + { proto = "udp", timeout = 3000 }) + if not status then + return + end + + -- port is open + nmap.set_port_state(host, port, "open") + + local passwordbyte, maxplayers, numplayers, name, pvpallow, newplayersallow, description = + string.match(data, "^\x00\x03\xf1\x26............(.)...(.)...(.)...................................................................(.*)\0\0(.):(.):.*:.*:.*:(.*)\0\0$") + if not passwordbyte then + return + end + + local o = stdnse.output_table() + + o["server name"] = string.gsub(name, "[^%g%s]", "") + o["server description"] = string.gsub(description, "[^%g%s]", "") + o["players"] = numplayers:byte(1) - 1 + o["max. players"] = maxplayers:byte(1) - 1 + + passwordbyte = passwordbyte:byte(1) + if bit.band(passwordbyte, 128) ~= 0 then + o["password"] = "yes" + else + o["password"] = "no" + end + + o["allow players to harm other players"] = "n/a" + if pvpallow == "1" then + o["allow players to harm other players"] = "yes" + elseif pvpallow == "0" then + o["allow players to harm other players"] = "no" + end + + o["allow new players"] = "n/a" + if newplayersallow == "1" then + o["allow new players"] = "yes" + elseif newplayersallow == "0" then + o["allow new players"] = "no" + end + + port.version.name = "freelancer" + port.version.name_confidence = 10 + port.version.product = "Freelancer" + port.version.extrainfo = "name: " .. o["server name"] .. "; players: " .. + o["players"] .. "/" .. o["max. players"] .. "; password: " .. o["password"] + + nmap.set_port_version(host, port, "hardmatched") + + return o +end diff --git a/scripts/script.db b/scripts/script.db index 104aa2537..3c4f99c55 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -106,6 +106,7 @@ Entry { filename = "finger.nse", categories = { "default", "discovery", "safe", Entry { filename = "firewalk.nse", categories = { "discovery", "safe", } } Entry { filename = "firewall-bypass.nse", categories = { "intrusive", "vuln", } } Entry { filename = "flume-master-info.nse", categories = { "default", "discovery", "safe", } } +Entry { filename = "freelancer-info.nse", categories = { "default", "discovery", "safe", "version", } } Entry { filename = "ftp-anon.nse", categories = { "auth", "default", "safe", } } Entry { filename = "ftp-bounce.nse", categories = { "default", "safe", } } Entry { filename = "ftp-brute.nse", categories = { "brute", "intrusive", } }