Nmap Development mailing list archives
Re: [NSE] ventrilo-info Ventrilo server version detection and info
From: Marin Maržić <marzic () gmail com>
Date: Fri, 07 Jun 2013 23:59:38 +0200
Hey, these replies (2 emails at the bottom of this) slipped past me. Just came across them now half a year later when I was looking to post some updates to those probes. Never too late? The updated scripts keep the kind of portrules you seemed to like to use (less likely to run). Also added some version probes that can be controlled by rarity and act as a sort of "softmatch" for activating the scripts. Should help some when the services run on arbitrary ports and the scripts have such restrictive portrules set. - murmur-version.nse Now only sends and receives 1 packet when scanning the same port number on the same host in both TCP and UDP (used to repeat for each protocol). The "softmatch" probe: Probe UDP Murmur q|\0\0\0\0abcdefgh| rarity 9 ports 64738 match murmur m|^\0.{3}abcdefgh.{12}$|s p/Murmur/ v/1.2.X/ - ventrilo-info.nse Now only sends and receives 1 packet when scanning the same port number on the same host in both TCP and UDP (used to repeat for each protocol). Various code improvements, bug fixes. The "softmatch" probe follows. This one is encrypted and the match can't really be matched on anything except that it should be at least 111 bytes (conservative guess, should catch all). Probe UDP Ventrilo q|\x01\xe7\xe5\x75\x31\xa3\x17\x0b\x21\xcf\xbf\x2b\x99\x4e\xdd\x19\xac\xde\x08\x5f\x8b\x24\x0a\x11\x19\xb6\x73\x6f\xad\x28\x13\xd2\x0a\xb9\x12\x75| rarity 9 ports 3784 match ventrilo m|^.{111}|s p/Ventrilo/ v/2.1.2+/ The UDP payload follows. It is a general status request with a 1 packet reply: # Ventrilo 2.1.2+ # UDP general status request (encrypted). # See http://aluigi.altervista.org/papers.htm#ventrilo udp 3784 "\x01\xe7\xe5\x75\x31\xa3\x17\x0b\x21\xcf\xbf\x2b\x99\x4e\xdd\x19\xac\xde\x08\x5f\x8b\x24\x0a\x11\x19\xb6\x73\x6f\xad\x28\x13\xd2\x0a\xb9\x12\x75" - teamspeak2-version.nse You mentioned that this could have been done with a version probe and a couple match lines (and you were right!), but I have since found where the precise version numbers are hidden in the binary blob response. There is some information on the protocol at http://wiki.wireshark.org/TeamSpeak2 but they haven't found the version offsets. A normal login request is used. The "softmatch" probe: Probe UDP TeamSpeak2 q|\xf4\xbe\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x32\x78\xba\x85\x09\x54\x65\x61\x6d\x53\x70\x65\x61\x6b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x57\x69\x6e\x64\x6f\x77\x73\x20\x58\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x20\x00\x3c\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x6e\x69\x63\x6b\x6e\x61\x6d\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00| rarity 9 ports 8767 match ts2 m|^\xf4\xbe\x04\x00\x00\x00\x00\x00.............([^\0]+)[^\w\s]+([^\0]+)\0+[^\0].{355}$|s p/TeamSpeak 2/ o/$2/ i/name: $1; no password/ match ts2 m|^\xf4\xbe\x04\x00\x00\x00\x00\x00............\0{60}.{356}$|s p/TeamSpeak 2/ i|name: n/a; has password or version < 2.0.19.16 (very unlikely)| Examples of output: PORT STATE SERVICE VERSION 8767/udp open ts2 TeamSpeak 2 (name: COWCLANS; no password) Service Info: OS: Win32 PORT STATE SERVICE VERSION 8767/udp open ts2 TeamSpeak 2 (name: TeamSpeak Server; no password) Service Info: OS: Linux - TeamSpeak 2 nmap-payloads The payload sent is the one used in the above script. It is a normal login request and is not encrypted. Some information fields sent are in ASCII, but it's in hex here because it was convenient to copy it like that off the wire. I guess the description could be something like: # TeamSpeak 2 # UDP login request # See http://wiki.wireshark.org/TeamSpeak2 - TeamSpeak 2 TCP port service detection (the "TCPQuery" interface): Here are 2 examples you asked for of what output looks like for the suggested "ver" command: 2.0.23.19 Win32 Freeware OK 2.0.24.1 Linux Freeware OK - TeamSpeak 2 TCP port service detection (the http web admin interface): When I comment it out, the specific line matches. When I leave it functional below or above the specific lines, it overrides. Weird? - TeamSpeak 3 UDP probe and nmap-payloads This is an encrypted login request packet copied off the wire. Think there is no documentation on it. There seem to be some fields that echo back what is sent, and some that are static when sent this exact payload, so I match on them. Length varies. I guess the description could be something like: # TeamSpeak 3 # UDP login request (encrypted) - TeamSpeak 3 TCP port service detection (the "ServerQuery" interface): 2 examples of what output looks like for the suggested "version" command: version=3.0.6.1 build=1340956745 platform=Windows error id=0 msg=ok version=3.0.7.2 build=1368605352 platform=Linux error id=0 msg=ok - On another note, when I tried to make version scripts run for any as of yet unidentified port (like normal probes would with --version-all), it wasn't that straightforward. I came across this bit in http://nmap.org/book/nse-api.html#nse-api-arguments: "port.service Contains a string representation of the service running on port.number as detected by the Nmap service detection. If the port.version field is nil, Nmap has guessed the service based on the port number. Otherwise version detection was able to determine the listening service and this field is equal to port.version.name." Thought that maybe the mentioned fields could help determine if it was a guess or not, but this came up when testing (debug output at the start of a portrule) the 4 possible combinations: - port without an nmap-services entry, and no regex rule match: NSE: port.service=nil NSE: port.version=not nil NSE: port.version.name=nil NSE: port.version.name_confidence=3 PORT STATE SERVICE REASON VERSION 62314/udp open|filtered unknown no-response - port without an nmap-services entry, and there is a regex rule match: NSE: port.service=murmur NSE: port.version=not nil NSE: port.version.name=murmur NSE: port.version.name_confidence=10 PORT STATE SERVICE REASON VERSION 62314/udp open murmur udp-response Murmur 1.2.X - port (80) with a nmap-services entry (http), and no regex rule match: NSE: port.service=http NSE: port.version=not nil NSE: port.version.name=http NSE: port.version.name_confidence=3 PORT STATE SERVICE REASON VERSION 80/udp open|filtered http no-response - port (80) with a nmap-service entry (http), and there is a regex rule match: NSE: port.service=murmur NSE: port.version=not nil NSE: port.version.name=murmur NSE: port.version.name_confidence=10 PORT STATE SERVICE REASON VERSION 80/udp open murmur udp-response Murmur 1.2.X Some conclusions from this: - port.version is never nil (guess or not) - port.service and port.version.name are always equal (guess or not) - port.version.name_confidence is never nil; it is 3 when a guess was made and it is 3 even when no guess can be made, it is 10 on a match - if a port number has an entry in nmap-services, port.service and port.version.name will be set to it. This is why, for example, the Skype version script can never work against port 80 (it's set to "http"), or against any other port with an entry in nmap-services that isn't "unknown" or "". Then it seems that the following type of port rule would best emulate a normal probe that runs on any open or open|filtered, and as of yet unidentified port (udp in this case): portrule = function(host, port) return port.version.name_confidence ~= 10 and not shortport.port_is_excluded(port.number, "udp") end Guess I would have to add such a rule to all scripts if I wanted "true" --version-all functionality (full Nmap version detecting power). Marin On 16.1.2013. 1:30, David Fifield wrote:> On Tue, Dec 18, 2012 at 03:30:19AM +0100, Marin Maržić wrote:
here's a service detection and info script for the Ventrilo voice communication server service. If used as a normal script it prints out a lot of the server status details. More info in the .nse.Thank you, this is now committed in r30505 and following. I made some changes to the documentation, and changed the port rule to make it less likely to run. We don't yet have a good way to control the running of version scripts like this, which target services that can be run against arbitrary ports, but which we don't want to run for every open|filtered port by default. In version probes we use the rarity, but there is no equivalent notion for NSE scripts. David Fifield
On 23.12.2012. 2:14, David Fifield wrote:> On Wed, Dec 19, 2012 at 07:59:51PM +0100, Marin Maržić wrote:
been working on improving TeamSpeak 2 and 3 server service detection and here's what I came up with. TeamSpeak 2 (2 TCP and 1 UDP port): TCP port service detection (the "TCPQuery" interface): - replaced match line (for the NULL probe): match telnet m|^\[TS\]\r\n$| p/Teamspeak VoIP Information telnetd/ - with: softmatch ts2-TCPQuery m|^\[TS\]\r\n$| - and added probe: Probe TCP verLine q|ver\r\n| rarity 9 ports 51234 match ts2-TCPQuery m|^\[TS\]\r\n(\S+) (\S+) (\S+)\r\nOK\r\n$| p/TeamSpeak 2 server TCPQuery interface (telnetd)/ v/$1/ i/$3/ o/$2/ - This improves the detection of the specific TS2 telnetd (they call it the TCPQuery function) with additional information (more precise name, specific version, some extra info and OS). Rarity 9 works great because of the softmatch in the NULL probe so it doesn't slow down searches.I applied the part to make a more specific match for the TCPQuery port. Can you send some examples of verbatim responses sent in response to the "ver" command? I want to see what kind of things are going in the info field, and how the OS names are formatted. If there are multiple OS strings, we usually like to break them into multiple match lines in order to have different CPE.TCP port service detection (the "ServerQuery" interface): - replaced match lines (for the NULL probe): match teamspeak m|^TS3\n\r$| p/TeamSpeak voice communication/ v/3/ match teamspeak m|^TS3\n\rWelcome to the TeamSpeak 3 ServerQuery interface, type \"help\" for a list of commands and \"help <command>\" for information on a specific command\.\n\r$| p/TeamSpeak voice communication/ v/3/ - with: softmatch ts3-ServerQuery m|^TS3\n\r$| softmatch ts3-ServerQuery m|^TS3\n\rWelcome to the TeamSpeak 3 ServerQuery interface, type \"help\" for a list of commands and \"help <command>\" for information on a specific command\.\n\r$| - and added probe: Probe TCP versionLine q|version\r\n| rarity 9 ports 10011 match ts3-ServerQuery m|^TS3\n\r.*?version=(\S+) build=(\S+) platform=(\S+)\n\rerror id=0 msg=ok\n\r$|s p/TeamSpeak 3 server ServerQuery interface (telnetd)/ v/$1/ i/build: $2/ o/$3/Same here, I applied the more specific matches, but please show some example ooutput of the "version" command.TCP port service detection (the http web admin interface): - This one seemed to exist already in nmap-service-probes in the form of 2 match lines (for the NULL probe): match http m|^HTTP/1\.1 \d\d\d .*\r\nConnection: keep-alive\r\nContent-Type: text/HTML\r\nContent-Length: \d+\r\nServer: Indy/([\d.]+)\r\nSet-Cookie: .*\r\n\r\n<!-- header\.html -->.*TeamSpeak|s p/TeamSpeak admin httpd/ v/1.X/ i/Indy httpd $1/ match http m|^HTTP/1\.1 \d\d\d .*\r\nConnection: keep-alive\r\nContent-Type: text/HTML\r\nContent-Length: \d+\r\nServer: Indy/([\d.]+)\r\nSet-Cookie: .*<title>TeamSpeak 2 - Server-Administration</title>|s p/TeamSpeak admin httpd/ v/2.X/ i/Indy httpd $1/ - Unfortunately they never match because they are overriden by this line: match http m|^HTTP/1\.1 200 OK\r\n.*Server: Indy/([\w._-]+)\r\n|s p/Indy/ v/$1/ - not sure how this kind of stuff is usually fixedThis doesn't seem to be the case anymore in the current version of the file. The Indy/TeamSpeak lines appear (in the GetRequest probe) above any more generic Indy lines. Is it possible that the server output is slightly different and now doesn't match the regular expressions?- payload (nmap-payloads): # TeamSpeak 2 udp 8767
"\xf4\xbe\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x32\x78\xba\x85\x09\x54\x65\x61\x6d\x53\x70\x65\x61\x6b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x57\x69\x6e\x64\x6f\x77\x73\x20\x58\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x20\x00\x3c\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x6e\x69\x63\x6b\x6e\x61\x6d\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
UDP port service detection (the voice/login/session port): Probe UDP TeamSpeak3
q|\x05\xca\x7f\x16\x9c\x11\xf9\x89\x00\x00\x00\x00\x02\x9d\x74\x8b\x45\xaa\x7b\xef\xb9\x9e\xfe\xad\x08\x19\xba\xcf\x41\xe0\x16\xa2\x32\x6c\xf3\xcf\xf4\x8e\x3c\x44\x83\xc8\x8d\x51\x45\x6f\x90\x95\x23\x3e\x00\x97\x2b\x1c\x71\xb2\x4e\xc0\x61\xf1\xd7\x6f\xc5\x7e\xf6\x48\x52\xbf\x82\x6a\xa2\x3b\x65\xaa\x18\x7a\x17\x38\xc3\x81\x27\xc3\x47\xfc\xa7\x35\xba\xfc\x0f\x9d\x9d\x72\x24\x9d\xfc\x02\x17\x6d\x6b\xb1\x2d\x72\xc6\xe3\x17\x1c\x95\xd9\x69\x99\x57\xce\xdd\xdf\x05\xdc\x03\x94\x56\x04\x3a\x14\xe5\xad\x9a\x2b\x14\x30\x3a\x23\xa3\x25\xad\xe8\xe6\x39\x8a\x85\x2a\xc6\xdf\xe5\x5d\x2d\xa0\x2f\x5d\x9c\xd7\x2b\x24\xfb\xb0\x9c\xc2\xba\x89\xb4\x1b\x17\xa2\xb6|
rarity 9 ports 9987 match ts3
m|^.{8}\x00\x00\x02\x97\x76\x8b\x54\xad\x79\xe3\xaf\x87\xeb\xaa\x1a\x19\xba\xcf\x41\xe0\x16\xa2\x32\x6c\xf3\xcf\xf4\x8e\x3c\x44\x83\xc8\x8d\x51\x45\x6f\x90\x95\x23\x33\x08\x86\x2d\x40|s
p/TeamSpeak 3 server/ - not sure about the rarity here, won't get picked up on a default scan with 9 - payload (nmap-payloads): # TeamSpeak 3 udp 9987
"\x05\xca\x7f\x16\x9c\x11\xf9\x89\x00\x00\x00\x00\x02\x9d\x74\x8b\x45\xaa\x7b\xef\xb9\x9e\xfe\xad\x08\x19\xba\xcf\x41\xe0\x16\xa2\x32\x6c\xf3\xcf\xf4\x8e\x3c\x44\x83\xc8\x8d\x51\x45\x6f\x90\x95\x23\x3e\x00\x97\x2b\x1c\x71\xb2\x4e\xc0\x61\xf1\xd7\x6f\xc5\x7e\xf6\x48\x52\xbf\x82\x6a\xa2\x3b\x65\xaa\x18\x7a\x17\x38\xc3\x81\x27\xc3\x47\xfc\xa7\x35\xba\xfc\x0f\x9d\x9d\x72\x24\x9d\xfc\x02\x17\x6d\x6b\xb1\x2d\x72\xc6\xe3\x17\x1c\x95\xd9\x69\x99\x57\xce\xdd\xdf\x05\xdc\x03\x94\x56\x04\x3a\x14\xe5\xad\x9a\x2b\x14\x30\x3a\x23\xa3\x25\xad\xe8\xe6\x39\x8a\x85\x2a\xc6\xdf\xe5\x5d\x2d\xa0\x2f\x5d\x9c\xd7\x2b\x24\xfb\xb0\x9c\xc2\xba\x89\xb4\x1b\x17\xa2\xb6"
For all these, we need some more information. We don't like having undocumented binary blobs in the database. Do you have a link to protocol documentation? What do these probes do? Where do they come from? Check the comments above each payload in nmap-payloads; that's the kind of information we need.UDP port service detection (the voice/login/session port): - Attached an NSE script for this one. More info in the .nse.It looks like what this script does can be done with a version probe. It just sends a static payload and then does a pattern match on the returned value. A blank name, for example, would be handled with two match lines. My above comments on documentation apply equally here; please show some example output if possible. David Fifield
Attachment:
murmur-version.nse
Description:
Attachment:
teamspeak2-version.nse
Description:
Attachment:
ventrilo-info.nse
Description:
_______________________________________________ Sent through the dev mailing list http://nmap.org/mailman/listinfo/dev Archived at http://seclists.org/nmap-dev/
Current thread:
- Re: [NSE] ventrilo-info Ventrilo server version detection and info Marin Maržić (Jun 07)