diff --git a/scripts/afp-serverinfo.nse b/scripts/afp-serverinfo.nse index 53b0b3c2e..c0e23ed76 100644 --- a/scripts/afp-serverinfo.nse +++ b/scripts/afp-serverinfo.nse @@ -1,4 +1,5 @@ local afp = require "afp" +local format = require "format" local nmap = require "nmap" local shortport = require "shortport" local stdnse = require "stdnse" @@ -16,46 +17,84 @@ hostname, IPv4 and IPv6 addresses, and hardware type (for example -- PORT STATE SERVICE -- 548/tcp open afp -- | afp-serverinfo: --- | | Server Flags: 0x8ffb --- | | Super Client: Yes --- | | UUIDs: Yes --- | | UTF8 Server Name: Yes --- | | Open Directory: Yes --- | | Reconnect: Yes --- | | Server Notifications: Yes --- | | TCP/IP: Yes --- | | Server Signature: Yes --- | | ServerMessages: Yes --- | | Password Saving Prohibited: No --- | | Password Changing: Yes --- | |_ Copy File: Yes --- | Server Name: mac-mini --- | Machine Type: Macmini2,1 --- | AFP Versions: AFP3.3, AFP3.2, AFP3.1, AFPX03 --- | UAMs: DHCAST128, DHX2, Recon1, Client Krb v2, No User Authent --- | Server Signature: 000000000000100080000016cbaed4ac --- | Network Address 1: 192.168.0.190:548 --- | Network Address 2: [fe80:0000:0000:0000:0216:cbff:feae:d4ac]:548 --- | Network Address 3: 192.168.0.190 --- | Directory Name 1: afpserver/LKDC:SHA1.02EBDBCFABF3C222D6FE9FE4D908893568387654@LKDC:SHA1.02EBDBCFABF3C222D6FE9FE4D908893568387654 --- |_ UTF8 Server Name: mac-mini +-- | Server Flags: +-- | Flags hex: 0x837d +-- | Super Client: true +-- | UUIDs: false +-- | UTF8 Server Name: true +-- | Open Directory: true +-- | Reconnect: false +-- | Server Notifications: true +-- | TCP/IP: true +-- | Server Signature: true +-- | Server Messages: true +-- | Password Saving Prohibited: true +-- | Password Changing: false +-- | Copy File: true +-- | Server Name: foobardigital +-- | Machine Type: Netatalk +-- | AFP Versions: AFPVersion 1.1, AFPVersion 2.0, AFPVersion 2.1, AFP2.2, AFPX03, AFP3.1 +-- | UAMs: DHX2 +-- | Server Signature: bbeb480e00000000bbeb480e00000000 +-- | Network Addresses: +-- | 192.0.2.235 +-- | foobardigital.com +-- |_ UTF8 Server Name: foobardigital +-- +-- @xmloutput +-- +-- 0x837d +-- true +-- false +-- true +-- true +-- false +-- true +-- true +-- true +-- true +-- true +-- false +-- true +--
+-- foobardigital +-- Netatalk +-- +-- AFPVersion 1.1 +-- AFPVersion 2.0 +-- AFPVersion 2.1 +-- AFP2.2 +-- AFPX03 +-- AFP3.1 +--
+-- +-- DHX2 +--
+-- +-- bbeb480e00000000bbeb480e00000000 +-- +-- 192.0.2.235 +-- foobardigital.com +--
+-- foobardigital -- Version 0.2 -- Created 2010/02/09 - v0.1 - created by Andrew Orr -- Revised 2010/02/10 - v0.2 - added checks for optional fields +-- Revised 2015/02/25 - v0.3 - XML structured output author = "Andrew Orr" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"default", "discovery", "safe"} -portrule = shortport.portnumber(548, "tcp") +portrule = shortport.port_or_service(548, "afp") action = function(host, port) local socket = nmap.new_socket() local status - local result = {} + local result = stdnse.output_table() local temp -- set a reasonable timeout value @@ -80,61 +119,58 @@ action = function(host, port) -- response. It might be better rearranged? -- output the server flags nicely - table.insert(result, string.format("| Server Flags: 0x%04x", response.flags.raw)) - table.insert(result, string.format("| Super Client: %s", response.flags.SuperClient and "Yes" or "No")) - table.insert(result, string.format("| UUIDs: %s", response.flags.UUIDs and "Yes" or "No")) - table.insert(result, string.format("| UTF8 Server Name: %s", response.flags.UTF8ServerName and "Yes" or "No")) - table.insert(result, string.format("| Open Directory: %s", response.flags.OpenDirectory and "Yes" or "No")) - table.insert(result, string.format("| Reconnect: %s", response.flags.Reconnect and "Yes" or "No")) - table.insert(result, string.format("| Server Notifications: %s", response.flags.ServerNotifications and "Yes" or "No")) - table.insert(result, string.format("| TCP/IP: %s", response.flags.TCPoverIP and "Yes" or "No")) - table.insert(result, string.format("| Server Signature: %s", response.flags.ServerSignature and "Yes" or "No")) - table.insert(result, string.format("| ServerMessages: %s", response.flags.ServerMessages and "Yes" or "No")) - table.insert(result, string.format("| Password Saving Prohibited: %s", response.flags.NoPasswordSaving and "Yes" or "No")) - table.insert(result, string.format("| Password Changing: %s", response.flags.ChangeablePasswords and "Yes" or "No")) - table.insert(result, string.format("|_ Copy File: %s", response.flags.CopyFile and "Yes" or "No")) + -- Would like to just pass response.flags, but key ordering would be more + -- work than it's worth. + local flags = stdnse.output_table() + flags["Flags hex"] = ("0x%04x"):format(response.flags.raw) + flags["Super Client"] = response.flags.SuperClient + flags["UUIDs"] = response.flags.UUIDs + flags["UTF8 Server Name"] = response.flags.UTF8ServerName + flags["Open Directory"] = response.flags.OpenDirectory + flags["Reconnect"] = response.flags.Reconnect + flags["Server Notifications"] = response.flags.ServerNotifications + flags["TCP/IP"] = response.flags.TCPoverIP + flags["Server Signature"] = response.flags.ServerSignature + flags["Server Messages"] = response.flags.ServerMessages + flags["Password Saving Prohibited"] = response.flags.NoPasswordSaving + flags["Password Changing"] = response.flags.ChangeablePasswords + flags["Copy File"] = response.flags.CopyFile + + result["Server Flags"] = flags -- other info - table.insert(result, string.format("Server Name: %s", response.server_name)) - table.insert(result, string.format("Machine Type: %s", response.machine_type)) + result["Server Name"] = response.server_name + result["Machine Type"] = response.machine_type -- list the supported AFP versions - temp = "AFP Versions: " - for i = 1, response.afp_version_count-1 do - temp = temp .. response.afp_versions[i] .. ", " - end - temp = temp .. response.afp_versions[response.afp_version_count] - table.insert(result, temp) + format.as_horizontal(response.afp_versions) + result["AFP Versions"] = response.afp_versions -- list the supported UAMs (User Authentication Modules) - temp = "UAMs: " - for i = 1, response.uam_count-1 do - temp = temp .. response.uams[i] .. ", " - end - temp = temp .. response.uams[response.uam_count] - table.insert(result, temp) + format.as_horizontal(response.uams) + result["UAMs"] = response.uams -- server signature, not sure of the format here so just showing a hex string if response.flags.ServerSignature then - table.insert(result, string.format("Server Signature: %s", stdnse.tohex(response.server_signature))) + result["Server Signature"] = stdnse.tohex(response.server_signature) end -- listing the network addresses one line each -- the default for Mac OS X AFP server is to bind everywhere, so this will -- list all network interfaces that the machine has - for i = 1, response.network_addresses_count do - table.insert(result, string.format("Network Address %d: %s", i, response.network_addresses[i])) + if response.network_addresses_count > 0 then + result["Network Addresses"] = response.network_addresses end -- similar to above - for i = 1, response.directory_names_count do - table.insert(result, string.format("Directory Name %d: %s", i, response.directory_names[i])) + if response.directory_names_count > 0 then + result["Directory Names"] = response.directory_names end -- and finally the utf8 server name if response.flags.UTF8ServerName then - table.insert(result, string.format("UTF8 Server Name: %s", response.utf8_server_name)) + result["UTF8 Server Name"] = response.utf8_server_name end - return stdnse.format_output(true, result) + return result end