Lucene search

K
nmapPatrik KarlssonNMAP:VOLDEMORT-INFO.NSE
HistoryJan 31, 2012 - 8:32 p.m.

voldemort-info NSE Script

2012-01-3120:32:37
Patrik Karlsson
nmap.org
183

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%

Retrieves cluster and store information from the Voldemort distributed key-value store using the Voldemort Native Protocol.

Example Usage

nmap -p 6666 --script voldemort-info <ip>

Script Output

PORT     STATE SERVICE
6666/tcp open  irc
| voldemort-info:
|   Cluster
|     Name: mycluster
|     Id: 0
|     Host: localhost
|     HTTP Port: 8081
|     TCP Port: 6666
|     Admin Port: 6667
|     Partitions: 0, 1
|   Stores
|     test
|       Persistence: bdb
|       Description: Test store
|       Owners: [email protected], [email protected]
|       Routing strategy: consistent-routing
|       Routing: client
|     wordcounts
|       Persistence: read-only
|       Routing strategy: consistent-routing
|_      Routing: client

Requires


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

description = [[
Retrieves cluster and store information from the Voldemort distributed key-value store using the Voldemort Native Protocol.
]]

---
-- @usage
-- nmap -p 6666 --script voldemort-info <ip>
--
-- @output
-- PORT     STATE SERVICE
-- 6666/tcp open  irc
-- | voldemort-info:
-- |   Cluster
-- |     Name: mycluster
-- |     Id: 0
-- |     Host: localhost
-- |     HTTP Port: 8081
-- |     TCP Port: 6666
-- |     Admin Port: 6667
-- |     Partitions: 0, 1
-- |   Stores
-- |     test
-- |       Persistence: bdb
-- |       Description: Test store
-- |       Owners: [email protected], [email protected]
-- |       Routing strategy: consistent-routing
-- |       Routing: client
-- |     wordcounts
-- |       Persistence: read-only
-- |       Routing strategy: consistent-routing
-- |_      Routing: client
--

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


portrule = shortport.port_or_service(6666, "vp3", "tcp")

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

-- Connect to the server and make sure it supports the vp3 protocol
-- @param host table as received by the action method
-- @param port table as received by the action method
-- @return status true on success, false on failure
-- @return socket connected to the server
local function connect(host, port)
  local socket = nmap.new_socket()
  socket:set_timeout(5000)

  local status, err = socket:connect(host, port)
  if ( not(status) ) then
    return false, "Failed to connect to server"
  end

  status, err = socket:send("vp3")
  if ( not(status) ) then
    return false, "Failed to send request to server"
  end

  local response
  status, response = socket:receive_bytes(2)
  if ( not(status) ) then
    return false, "Failed to receive response from server"
  elseif( response ~= "ok" ) then
    return false, "Unsupported protocol"
  end
  return true, socket
end

-- Get Voldemort metadata
-- @param socket connected to the server
-- @param file the xml file to retrieve
-- @return status true on success false on failure
-- @return data string as received from the server
local function getMetadata(socket, file)

  local req = "\x01\x00" .. string.pack(">s1x I4 s1x", "metadata", 0, file)
  local status, err = socket:send(req)
  if ( not(status) ) then
    return false, "Failed to send request to server"
  end
  local status, data = socket:receive_bytes(10)
  if ( not(status) ) then
    return false, "Failed to receive response from server"
  end
  local len = string.unpack(">I2", data, 9)
  while( #data < len - 2 ) do
    local status, tmp = socket:receive_bytes(len - 2 - #data)
    if ( not(status) ) then
      return false, "Failed to receive response from server"
    end
    data = data .. tmp
  end
  return true, data
end


action = function(host, port)

  -- table of variables to query the server
  local vars = {
    ["cluster"] = {
      { key = "Name", match = "<cluster>.-<name>(.-)</name>" },
      { key = "Id", match = "<cluster>.-<server>.-<id>(%d-)</id>.-</server>" },
      { key = "Host",  match = "<cluster>.-<server>.-<host>(%w-)</host>.-</server>" },
      { key = "HTTP Port", match = "<cluster>.-<server>.-<http%-port>(%d-)</http%-port>.-</server>" },
      { key = "TCP Port", match = "<cluster>.-<server>.-<socket%-port>(%d-)</socket%-port>.-</server>" },
      { key = "Admin Port", match = "<cluster>.-<server>.-<admin%-port>(%d-)</admin%-port>.-</server>" },
      { key = "Partitions", match = "<cluster>.-<server>.-<partitions>([%d%s,]*)</partitions>.-</server>" },
    },
    ["store"] = {
      { key = "Persistence", match = "<store>.-<persistence>(.-)</persistence>" },
      { key = "Description", match = "<store>.-<description>(.-)</description>" },
      { key = "Owners", match = "<store>.-<owners>(.-)</owners>" },
      { key = "Routing strategy", match = "<store>.-<routing%-strategy>(.-)</routing%-strategy>" },
      { key = "Routing", match = "<store>.-<routing>(.-)</routing>" },
    },
  }

  -- connect to the server
  local status, socket = connect(host, port)
  if ( not(status) ) then
    return fail(socket)
  end

  -- get the cluster meta data
  local status, response = getMetadata(socket, "cluster.xml")
  if ( not(status) or not(response:match("<cluster>.*</cluster>")) ) then
    return
  end

  -- Get the cluster details
  local cluster_tbl = { name = "Cluster" }
  for _, item in ipairs(vars["cluster"]) do
    local val = response:match(item.match)
    if ( val ) then
      table.insert(cluster_tbl, ("%s: %s"):format(item.key, val))
    end
  end

  -- get the stores meta data
  local status, response = getMetadata(socket, "stores.xml")
  if ( not(status) or not(response:match("<stores>.-</stores>")) ) then
    return
  end

  local result, stores = {}, { name = "Stores" }
  table.insert(result, cluster_tbl)

  -- iterate over store items
  for store in response:gmatch("<store>.-</store>") do
    local name = store:match("<store>.-<name>(.-)</name>")
    local store_tbl = { name = name or "unknown" }

    for _, item in ipairs(vars["store"]) do
      local val = store:match(item.match)
      if ( val ) then
        table.insert(store_tbl, ("%s: %s"):format(item.key, val))
      end
    end
    table.insert(stores, store_tbl)
  end
  table.insert(result, stores)
  return stdnse.format_output(true, 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:VOLDEMORT-INFO.NSE