mirror of
https://github.com/nmap/nmap.git
synced 2025-12-28 18:39:03 +00:00
Add RHOST bruting to nje-node-brute. See #554
This commit is contained in:
@@ -33,13 +33,17 @@ target IP (OIP) and a 1 byte response value (R) as outlined below:
|
||||
</code>
|
||||
|
||||
* TYPE: Can either be 'OPEN', 'ACK', or 'NAK', in EBCDIC, padded by spaces to make 8 bytes. This script always send 'OPEN' type.
|
||||
* RHOST: Name of the local machine initiating the connection. Set to 'FAKE'
|
||||
* RHOST: Node name of the local machine initiating the connection. Set to 'FAKE'.
|
||||
* RIP: Hex value of the local systems IP address. Set to '0.0.0.0'
|
||||
* OHOST: The value being enumerated to determine the target system name.
|
||||
* OHOST: The value being enumerated to determine the targets NJE node name.
|
||||
* OIP: IP address, in hex, of the target system. Set to '0.0.0.0'.
|
||||
* R: The response. NJE will send an 'R' of 0x01 if the OHOST is wrong or 0x04/0x00 if the OHOST is correct.
|
||||
* R: The response. NJE will send an 'R' of 0x01 if the OHOST is wrong or 0x04 if the OHOST is correct.
|
||||
|
||||
Since most systems will only have one node name, it is recommended to use the
|
||||
By default this script will attempt the brute force a mainframes OHOST. If supplied with
|
||||
the argument <code>nje-node-brute.ohost</code> this script will attempt the bruteforce
|
||||
the RHOST, setting OHOST to the value supplied to the argument.
|
||||
|
||||
Since most systems will only have one OHOST name, it is recommended to use the
|
||||
<code>brute.firstonly</code> script argument.
|
||||
]]
|
||||
|
||||
@@ -52,24 +56,27 @@ Since most systems will only have one node name, it is recommended to use the
|
||||
-- @args nje-node-brute.hostlist The filename of a list of node names to try.
|
||||
-- Defaults to "nselib/data/vhosts-default.lst"
|
||||
--
|
||||
-- @args nje-node-brute.ohost The target mainframe OHOST. Used to bruteforce RHOST.
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 175/tcp open nje syn-ack
|
||||
-- | nje-node-brute:
|
||||
-- | Node Name:
|
||||
-- | Node Name:WASHDC - Valid credentials
|
||||
-- | POTATO:CACTUS - Valid credentials
|
||||
-- |_ Statistics: Performed 6 guesses in 14 seconds, average tps: 0
|
||||
--
|
||||
-- @changelog
|
||||
-- 2015-06-15 - v0.1 - created by Soldier of Fortran
|
||||
-- 2016-03-22 - v0.2 - Added RHOST Brute forcing.
|
||||
|
||||
author = "Soldier of Fortran"
|
||||
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"intrusive", "brute"}
|
||||
|
||||
portrule = shortport.port_or_service({175,2252}, "nje")
|
||||
|
||||
local openNJEfmt = "\xd6\xd7\xc5\xd5@@@@\xc6\xc1\xd2\xc5@@@@\0\0\0\0%s\0\0\0\0\0"
|
||||
local openNJEfmt = "\xd6\xd7\xc5\xd5@@@@%s\0\0\0\0%s\0\0\0\0\0"
|
||||
|
||||
Driver = {
|
||||
new = function(self, host, port, options)
|
||||
@@ -86,6 +93,7 @@ Driver = {
|
||||
-- the high timeout should take delays into consideration
|
||||
local s, r, opts, _ = comm.tryssl(self.host, self.port, '', { timeout = 50000 } )
|
||||
if ( not(s) ) then
|
||||
stdnse.debug2("Failed to connect")
|
||||
return false, "Failed to connect to server"
|
||||
end
|
||||
self.socket = s
|
||||
@@ -100,15 +108,24 @@ Driver = {
|
||||
-- Generates an NJE 'OPEN' packet with the node name
|
||||
password = string.upper(password)
|
||||
stdnse.verbose(2,"Trying... %s", password)
|
||||
local openNJE = openNJEfmt:format( drda.StringUtil.toEBCDIC(("%-8s"):format(password)) )
|
||||
local openNJE
|
||||
if self.options['ohost'] then
|
||||
-- One RHOST may have many valid OHOSTs
|
||||
if password == self.options['ohost'] then return false, brute.Error:new( "RHOST cannot be OHOST" ) end
|
||||
openNJE = openNJEfmt:format(drda.StringUtil.toEBCDIC(("%-8s"):format(password)),
|
||||
drda.StringUtil.toEBCDIC(("%-8s"):format(self.options['ohost'])) )
|
||||
else
|
||||
openNJE = openNJEfmt:format(drda.StringUtil.toEBCDIC(("%-8s"):format('FAKE')),
|
||||
drda.StringUtil.toEBCDIC(("%-8s"):format(password)) )
|
||||
end
|
||||
local status, err = self.socket:send( openNJE )
|
||||
if not status then return false, "Failed to send" end
|
||||
local status, data = self.socket:receive_bytes(33)
|
||||
if not status then return false, "Failed to receive" end
|
||||
if ( data:sub(-1) == "\0" ) or
|
||||
( data:sub(-1) == "\x04" ) then
|
||||
stdnse.verbose("Valid Node Name Found: %s", password)
|
||||
return true, creds.Account:new("Node Name", password, creds.State.VALID)
|
||||
if ( not self.options['ohost'] and ( data:sub(-1) == "\x04" ) ) or
|
||||
( self.options['ohost'] and ( data:sub(-1) == "\0" ) ) then
|
||||
-- stdnse.verbose(2,"Valid Node Name Found: %s", password)
|
||||
return true, creds.Account:new((self.options['ohost'] or "Node Name"), password, creds.State.VALID)
|
||||
end
|
||||
return false, brute.Error:new( "Invalid Node Name" )
|
||||
end,
|
||||
@@ -131,6 +148,9 @@ end
|
||||
action = function( host, port )
|
||||
-- Oftentimes the LPAR will be one of the subdomain of a system.
|
||||
local names = host.name and stdnse.strsplit("%.", host.name) or {}
|
||||
local o_host = stdnse.get_script_args('nje-node-brute.ohost') or nil
|
||||
local options = {}
|
||||
if o_host then options = { ohost = o_host:upper() } end
|
||||
if host.targetname then
|
||||
host.targetname:gsub("[^.]+", function(n) table.insert(names, n) end)
|
||||
end
|
||||
@@ -142,12 +162,13 @@ action = function( host, port )
|
||||
table.insert(names, l)
|
||||
end
|
||||
end
|
||||
local engine = brute.Engine:new(Driver, host, port)
|
||||
local users = unpwdb.filter_iterator(iter(names), valid_name)
|
||||
if o_host then stdnse.verbose(2,'RHOST Mode, using OHOST: %s', o_host:upper()) end
|
||||
local engine = brute.Engine:new(Driver, host, port, options)
|
||||
local nodes = unpwdb.filter_iterator(iter(names), valid_name)
|
||||
engine.options:setOption("passonly", true )
|
||||
engine:setPasswordIterator(users)
|
||||
engine:setPasswordIterator(nodes)
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
engine.options:setTitle("Node Name")
|
||||
engine.options:setTitle("Node Name(s)")
|
||||
local status, result = engine:start()
|
||||
return result
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user