diff --git a/CHANGELOG b/CHANGELOG index e703574da..2604fff87 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Added the afp-serverinfo script that gets a hostname, IP + addresses, and other configuration information from an AFP server. + The script, and a patch to the afp library, were originally + contributed by Andrew Orr and were subsequently enhanced by Patrik + and David. + o [Zenmap] Added the ability to print Nmap output to a printer. [David] Nmap 5.30BETA1 [2010-03-29] diff --git a/scripts/afp-serverinfo.nse b/scripts/afp-serverinfo.nse new file mode 100644 index 000000000..f3365235b --- /dev/null +++ b/scripts/afp-serverinfo.nse @@ -0,0 +1,137 @@ +description = [[ +Shows AFP server information. This information includes the server's +hostname, IPv4 and IPv6 addresses, and hardware type (for example +Macmini or MacBookPro). +]] + +--- +-- @output +-- 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 + +-- Version 0.2 +-- Created 2010/02/09 - v0.1 - created by Andrew Orr +-- Revised 2010/02/10 - v0.2 - added checks for optional fields + +author = "Andrew Orr" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"discovery", "safe"} + +require 'shortport' +require 'stdnse' +require 'afp' +require 'bit' + +portrule = shortport.portnumber(548, "tcp") + +action = function(host, port) + + local socket = nmap.new_socket() + local status + local result = {} + local temp + + -- set a reasonable timeout value + socket:set_timeout(5000) + + -- do some exception handling / cleanup + local catch = function() + socket:close() + end + + local try = nmap.new_try(catch) + + try( socket:connect(host.ip, port.number, "tcp") ) + + -- get our data + afp_proto = afp.Proto:new( { socket=socket } ) + + response = afp_proto:fp_get_server_info( socket ) + response = response.result + + -- all the server information is output in the order it occurs in the server + -- 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")) + + -- other info + table.insert(result, string.format("Server Name: %s", response.server_name)) + table.insert(result, string.format("Machine Type: %s", 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) + + -- 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) + + -- 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))) + 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])) + 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])) + 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)) + end + + return stdnse.format_output(true, result) +end diff --git a/scripts/script.db b/scripts/script.db index dfab79f5a..c60f9e985 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -1,5 +1,6 @@ Entry { filename = "afp-brute.nse", categories = { "auth", "intrusive", } } Entry { filename = "afp-path-vuln.nse", categories = { "safe", "vuln", } } +Entry { filename = "afp-serverinfo.nse", categories = { "discovery", "safe", } } Entry { filename = "afp-showmount.nse", categories = { "discovery", "safe", } } Entry { filename = "asn-query.nse", categories = { "discovery", "external", "safe", } } Entry { filename = "auth-owners.nse", categories = { "default", "safe", } }