Lucene search

K
nmapPatrik KarlssonNMAP:REDIS-BRUTE.NSE
HistoryJan 02, 2012 - 11:27 a.m.

redis-brute NSE Script

2012-01-0211:27:06
Patrik Karlsson
nmap.org
422

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 brute force passwords auditing against a Redis key-value store.

Script Arguments

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

See the documentation for the unpwdb library.

creds.[service], creds.global

See the documentation for the creds library.

brute.credfile, brute.delay, brute.emptypass, brute.firstonly, brute.guesses, brute.mode, brute.passonly, brute.retries, brute.start, brute.threads, brute.unique, brute.useraspass

See the documentation for the brute library.

Example Usage

nmap -p 6379 <ip> --script redis-brute

Script Output

PORT     STATE SERVICE
6379/tcp open  unknown
| redis-brute:
|   Accounts
|     toledo - Valid credentials
|   Statistics
|_    Performed 5000 guesses in 3 seconds, average tps: 1666

Requires


local brute = require "brute"
local creds = require "creds"
local redis = require "redis"
local shortport = require "shortport"
local stdnse = require "stdnse"

description = [[
Performs brute force passwords auditing against a Redis key-value store.
]]

---
-- @usage
-- nmap -p 6379 <ip> --script redis-brute
--
-- @output
-- PORT     STATE SERVICE
-- 6379/tcp open  unknown
-- | redis-brute:
-- |   Accounts
-- |     toledo - Valid credentials
-- |   Statistics
-- |_    Performed 5000 guesses in 3 seconds, average tps: 1666
--
--

author = "Patrik Karlsson"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"intrusive", "brute"}


portrule = shortport.port_or_service(6379, "redis")

local function fail(err) return stdnse.format_output(false, err) end

Driver = {

  new = function(self, host, port)
    local o = { host = host, port = port }
    setmetatable(o, self)
    self.__index = self
    return o
  end,

  connect = function( self )
    self.helper = redis.Helper:new(self.host, self.port)
    return self.helper:connect(brute.new_socket())
  end,

  login = function( self, username, password )
    local status, response = self.helper:reqCmd("AUTH", password)

    -- some error occurred, attempt to retry
    if ( status and response.type == redis.Response.Type.ERROR and
      "-ERR invalid password" == response.data ) then
      return false, brute.Error:new( "Incorrect password" )
    elseif ( status and response.type == redis.Response.Type.STATUS and
      "+OK" ) then
      return true, creds.Account:new( "", password, creds.State.VALID)
    else
      local err = brute.Error:new( response.data )
      err:setRetry( true )
      return false, err
    end

  end,

  disconnect = function(self)
    return self.helper:close()
  end,

}


local function checkRedis(host, port)

  local helper = redis.Helper:new(host, port)
  local status = helper:connect()
  if( not(status) ) then
    return false, "Failed to connect to server"
  end

  local status, response = helper:reqCmd("INFO")
  if ( not(status) ) then
    return false, "Failed to request INFO command"
  end

  if ( redis.Response.Type.ERROR == response.type ) then
    if ( "-ERR operation not permitted" == response.data ) or
        ( "-NOAUTH Authentication required." == response.data) then
      return true
    end
  end

  return false, "Server does not require authentication"
end

action = function(host, port)

  local status, err =  checkRedis(host, port)
  if ( not(status) ) then
    return fail(err)
  end

  local engine = brute.Engine:new(Driver, host, port )

  engine.options.script_name = SCRIPT_NAME
  engine.options.firstonly = true
  engine.options:setOption( "passonly", true )

  local result
  status, result = engine:start()
  return result
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:REDIS-BRUTE.NSE