Nmap Development mailing list archives

Re: [NSE] nje-node-brute.nse update


From: Phil <mainframed767 () gmail com>
Date: Tue, 22 Mar 2016 15:34:16 -0700

When I wrote this I got my OHOSTs and RHOSTs switched. Please find attached an updated version of this script to 
reflect this change:

Attachment: nje-node-brute.nse
Description:



On Mar 21, 2016, at 2:42 PM, Phil <mainframed767 () gmail com> wrote:

Hi All,

Please see the attached file (diff included below) for updates to nje-node-brute.nse which includes the addition of 
the ability to brute force an NJE nodes' OHOST. Currently the script only supports brute forcing RHOST. This update 
adds a new argument 'nje-node-brute.rhost’. When set the script will attempt the brute force an OHOST using the set 
RHOST. Otherwise it continues with the default behavior.

<nje-node-brute.nse>

DIFF:

Index: scripts/nje-node-brute.nse
===================================================================
--- scripts/nje-node-brute.nse        (revision 35708)
+++ scripts/nje-node-brute.nse        (working copy)
@@ -39,7 +39,11 @@
* 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.

-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 RHOST. If supplied with
+the argument <code>nje-node-brute.rhost</code> this script will attempt the bruteforce
+a valid OHOST using the RHOST of the value supplied.
+
+Since most systems will only have one RHOST name, it is recommended to use the
<code>brute.firstonly</code> script argument.
]]

@@ -52,12 +56,14 @@
-- @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.rhost The target mainframe RHOST. Used to bruteforce OHOST.
+--
-- @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
@@ -69,7 +75,7 @@

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 +92,7 @@
    -- 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.debug("Failed to connect")
      return false, "Failed to connect to server"
    end
    self.socket = s
@@ -100,15 +107,22 @@
    -- 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 = openNJEfmt:format(drda.StringUtil.toEBCDIC(("%-8s"):format('FAKE')),
+                                      drda.StringUtil.toEBCDIC(("%-8s"):format(password)) )
+    if self.options['rhost'] then
+      -- One RHOST may have many valid OHOSTs
+      if password == self.options['rhost'] 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['rhost'])) )
+    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
+    if ( not self.options['rhost'] and ( data:sub(-1) == "\x04" ) ) or
+       ( self.options['rhost'] and ( data:sub(-1) == "\0" ) ) then
      stdnse.verbose("Valid Node Name Found: %s", password)
-      return true, creds.Account:new("Node Name", password, creds.State.VALID)
+      return true, creds.Account:new((self.options['rhost'] or "Node Name"), password, creds.State.VALID)
    end
    return false, brute.Error:new( "Invalid Node Name" )
  end,
@@ -131,6 +145,9 @@
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 r_host = stdnse.get_script_args('nje-node-brute.rhost') or nil
+  local options = {}
+  if r_host then options = { rhost = r_host:upper() } end
  if host.targetname then
    host.targetname:gsub("[^.]+", function(n) table.insert(names, n) end)
  end
@@ -142,12 +159,13 @@
      table.insert(names, l)
    end
  end
-  local engine = brute.Engine:new(Driver, host, port)
-  local users = unpwdb.filter_iterator(iter(names), valid_name)
+  if r_host then stdnse.verbose(2,'OHOST Mode, using RHOST: %s', r_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

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

_______________________________________________
Sent through the dev mailing list
https://nmap.org/mailman/listinfo/dev
Archived at http://seclists.org/nmap-dev/

Current thread: