Lucene search

K
nmapPatrik KarlssonNMAP:AFP-BRUTE.NSE
HistoryMar 29, 2010 - 5:41 p.m.

afp-brute NSE Script

2010-03-2917:41:00
Patrik Karlsson
nmap.org
141

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.973 High

EPSS

Percentile

99.8%

Performs password guessing against Apple Filing Protocol (AFP).

Script Arguments

afp.password, afp.username

See the documentation for the afp library.

passdb, unpwdb.passlimit, unpwdb.timelimit, unpwdb.userlimit, userdb

See the documentation for the unpwdb library.

Example Usage

nmap -p 548 --script afp-brute <host>

Script Output

PORT    STATE SERVICE
548/tcp open  afp
| afp-brute:
|_  admin:KenSentMe => Valid credentials

Requires


local afp = require "afp"
local nmap = require "nmap"
local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local unpwdb = require "unpwdb"

-- 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 <host>
--
-- @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 https://nmap.org/book/man-legal.html"
categories = {"intrusive", "brute"}


-- Version 0.3
-- Created 01/15/2010 - v0.1 - created by Patrik Karlsson <[email protected]>
-- 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")

action = function( host, port )

  local result, response, status = {}, nil, nil
  local valid_accounts, found_users = {}, {}
  local helper
  local usernames, passwords

  status, usernames = unpwdb.usernames()
  if not status then return end

  status, passwords = unpwdb.passwords()
  if not status then return end

  for password in passwords do
    for username in usernames do
      if ( not(found_users[username]) ) then

        helper = afp.Helper:new()
        status, response = helper:OpenSession( host, port )

        if ( not(status) ) then
          stdnse.debug1("OpenSession failed")
          return
        end


        stdnse.debug1("Trying %s/%s ...", username, password)
        status, response = helper:Login( username, password )

        -- if the response is "Parameter error." we're dealing with Netatalk
        -- This basically means that the user account does not exist
        -- In this case, why bother continuing? Simply abort and thank Netatalk for the fish
        if response:match("Parameter error.") then
          stdnse.debug1("Netatalk told us the user does not exist! Thanks.")
          -- mark it as "found" to skip it
          found_users[username] = true
        end

        if status then
          -- Add credentials for other afp scripts to use
          if nmap.registry.afp == nil then
            nmap.registry.afp = {}
          end
          nmap.registry.afp[username]=password
          found_users[username] = true

          table.insert( valid_accounts, string.format("%s:%s => Valid credentials", username, password:len()>0 and password or "<empty>" ) )
          break
        end
        helper:CloseSession()
      end
    end
    usernames("reset")
  end

  local output = stdnse.format_output(true, valid_accounts)

  return output

end

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.973 High

EPSS

Percentile

99.8%

Related for NMAP:AFP-BRUTE.NSE