local brute = require "brute" local creds = require "creds" local afp = require "afp" local nmap = require "nmap" local shortport = require "shortport" local string = require "string" local stdnse = require "stdnse" -- we don't really need openssl here, but let's attempt to load it as a way -- to simply prevent the script from running, in case we don't have it local openssl = stdnse.silent_require("openssl") description = [[ Performs password guessing against Apple Filing Protocol (AFP). ]] --- -- @usage -- nmap -p 548 --script afp-brute -- -- @output -- PORT STATE SERVICE -- 548/tcp open afp -- | afp-brute: -- |_ admin:KenSentMe => Valid credentials -- Information on AFP implementations -- -- Snow Leopard -- ------------ -- - Delay 10 seconds for accounts with more than 5 incorrect login attempts (good) -- - Instant response if password is successful -- -- Netatalk -- -------- -- - Netatalk responds with a "Parameter error" when the username is invalid -- author = "Patrik Karlsson" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"intrusive", "brute"} -- Version 0.3 -- Created 01/15/2010 - v0.1 - created by Patrik Karlsson -- Revised 03/09/2010 - v0.2 - changed so that passwords are iterated over users -- - this change makes better sense as guessing is slow -- Revised 09/09/2011 - v0.3 - changed account status text to be more consistent with other *-brute scripts portrule = shortport.port_or_service(548, "afp") Driver = { new = function(self, host, port) local o = {} setmetatable(o, self) self.__index = self o.host = host o.port = port return o end, connect = function(self) self.afp = afp.Helper:new() status, response = self.afp:OpenSession(self.host, self.port) if (not(status)) then return false, brute.Error:new("OpenSession failed") end return true end, login = function(self, username, password) local status, response = self.afp:Login(username, password) if (status) then -- Add credentials for other afp scripts to use if not nmap.registry.afp then nmap.registry.afp = {} end nmap.registry.afp[username]=password return true, brute.Account:new(username, password, creds.State.VALID) else return false, brute.Error:new("Invalid credentials") end end, disconnect = function(self) self.afp:CloseSession() end, check = function(self) return true end, } action = function( host, port ) local status, result local engine = brute.Engine:new(Driver, host, port) engine.options.script_name = SCRIPT_NAME status, result = engine:start() return result end