1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00
Files
nmap/scripts/http-proxy-brute.nse
dmiller f37ac44380 Move brute.Account to creds.Account
In addition to fitting better (brute library is the verb, creds library
is the noun), this will allow creds.lua to use creds.Account internally
where necessary (see subsequent commits)

Also change old references to string argument "OPEN" into
creds.State.VALID.
2014-09-23 05:23:13 +00:00

116 lines
3.4 KiB
Lua

local base64 = require "base64"
local brute = require "brute"
local creds = require "creds"
local http = require "http"
local shortport = require "shortport"
local stdnse = require "stdnse"
description = [[
Performs brute force password guessing against HTTP proxy servers.
]]
---
-- @usage
-- nmap --script http-proxy-brute -p 8080 <host>
--
-- @output
-- PORT STATE SERVICE
-- 8080/tcp open http-proxy
-- | http-proxy-brute:
-- | Accounts
-- | patrik:12345 - Valid credentials
-- | Statistics
-- |_ Performed 6 guesses in 2 seconds, average tps: 3
--
-- @args http-proxy-brute.url sets an alternative URL to use when brute forcing
-- (default: http://scanme.insecure.org)
-- @args http-proxy-brute.method changes the HTTP method to use when performing
-- brute force guessing (default: HEAD)
author = "Patrik Karlsson"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
-- maybe the script does not need to be in the external category
-- as most request should not "leave" the proxy.
categories = {"brute", "intrusive", "external"}
portrule = shortport.port_or_service({8123,3128,8000,8080},{'polipo','squid-http','http-proxy'})
local arg_url = stdnse.get_script_args(SCRIPT_NAME .. '.url') or 'http://scanme.nmap.org/'
local arg_method = stdnse.get_script_args(SCRIPT_NAME .. '.method') or "HEAD"
Driver = {
new = function(self, host, port)
local o = { host = host, port = port }
setmetatable(o, self)
self.__index = self
return o
end,
connect = function( self )
return true
end,
login = function( self, username, password )
-- the http library does not yet support proxy authentication, so let's
-- do what's necessary here.
local header = { ["Proxy-Authorization"] = "Basic " .. base64.enc(username .. ":" .. password) }
local response = http.generic_request(self.host, self.port, arg_method, arg_url, { header = header, bypass_cache = true } )
-- if we didn't get a 407 error, assume the credentials
-- were correct. we should probably do some more checks here
if ( response.status ~= 407 ) then
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,
}
-- checks whether the proxy really needs authentication and that the
-- authentication mechanism can be handled by our script, currently only
-- BASIC authentication is supported.
local function checkProxy(host, port, url)
local response = http.generic_request(host, port, arg_method, url, { bypass_cache = true })
if ( response.status ~= 407 ) then
return false, "Proxy server did not require authentication"
end
local proxy_auth = response.header["proxy-authenticate"]
if ( not(proxy_auth) ) then
return false, "No proxy authentication header was found"
end
local challenges = http.parse_www_authenticate(proxy_auth)
for _, challenge in ipairs(challenges) do
if ( "Basic" == challenge.scheme ) then
return true
end
end
return false, "The authentication scheme wasn't supported"
end
action = function(host, port)
local status, err = checkProxy(host, port, arg_url)
if ( not(status) ) then
return ("\n ERROR: %s"):format(err)
end
local engine = brute.Engine:new(Driver, host, port)
engine.options.script_name = SCRIPT_NAME
local result
status, result = engine:start()
return result
end