From 3eca5e285c24780c39d2505f268bf96615c67217 Mon Sep 17 00:00:00 2001 From: paulino Date: Sat, 26 May 2018 20:54:27 +0000 Subject: [PATCH] Fixes bugs in tn3270.lua and improves script tso-brute. Closes #1218 --- CHANGELOG | 3 +++ nselib/tn3270.lua | 34 +++++++++++++++++----------------- scripts/tso-brute.nse | 12 ++++++++++++ 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1d4681e77..aa4576b40 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ #Nmap Changelog ($Id$); -*-text-*- +o [NSE][GH#1218] Fix bug related to screen rendering in NSE library tn3270. This + patch also improves the brute force script tso-brute. [mainframed] + o [NSE][GH#1209] Fix SIP, SASL, and HTTP Digest authentication when the algorithm contains lowercase characters. [Jeswin Mathai] diff --git a/nselib/tn3270.lua b/nselib/tn3270.lua index 1407d058c..b31d090d2 100644 --- a/nselib/tn3270.lua +++ b/nselib/tn3270.lua @@ -320,10 +320,10 @@ Telnet = { DECODE_BADDR = function ( byte1, byte2 ) if (byte1 & 0xC0) == 0 then -- (byte1 & 0x3F) << 8 | byte2 - return (((byte1 & 0x3F) << 8) | byte2) + 1 + return (((byte1 & 0x3F) << 8) | byte2) else -- (byte1 & 0x3F) << 6 | (byte2 & 0x3F) - return (((byte1 & 0x3F) << 6) | (byte2 & 0x3F)) + 1 + return (((byte1 & 0x3F) << 6) | (byte2 & 0x3F)) end end, @@ -653,7 +653,7 @@ Telnet = { if self.state == self.TN3270_DATA or self.state == self.TN3270E_DATA then -- since we're in TN3270 mode, let's create an empty buffer stdnse.debug(3, "Creating Empty IBM-3278-2 Buffer") - for i=1, 1920 do + for i=0, 1920 do self.buffer[i] = "\0" self.fa_buffer[i] = "\0" self.overwrite_buf[i] = "\0" @@ -816,10 +816,10 @@ Telnet = { stdnse.debug(4,"Writting Zero to buffer at address: " .. self.buffer_address) stdnse.debug(4,"Attribute Type: 0x".. stdnse.tohex(data:sub(i,i))) self:write_field_attribute(data:sub(i,i)) + self:write_char("\00") self.buffer_address = self:INC_BUF_ADDR(self.buffer_address) -- set the current position one ahead (after SF) i = i + 1 - self:write_char("\00") elseif cp == self.orders.SFE then stdnse.debug(4,"Start Field Extended") @@ -1030,13 +1030,13 @@ Telnet = { get_screen = function ( self ) stdnse.debug(3,"Returning the current TN3270 buffer") local buff = '\n' - for i = 1,#self.buffer do + for i = 0,#self.buffer do if self.buffer[i] == "\00" then buff = buff .. " " else buff = buff .. drda.StringUtil.toASCII(self.buffer[i]) end - if i % 80 == 0 then + if (i+1) % 80 == 0 then buff = buff .. "\n" end end @@ -1047,13 +1047,13 @@ Telnet = { lvl = lvl or 1 stdnse.debug(lvl,"---------------------- Printing the current TN3270 buffer ----------------------") local buff = '' - for i = 1,#self.buffer do + for i = 0,#self.buffer do if self.buffer[i] == "\00" then buff = buff .. " " else buff = buff .. drda.StringUtil.toASCII(self.buffer[i]) end - if i % 80 == 0 then + if (i+1) % 80 == 0 then stdnse.debug(lvl, buff) buff = '' end @@ -1065,7 +1065,7 @@ Telnet = { get_screen_raw = function ( self ) local buff = '' - for i = 1,#self.buffer do + for i = 0,#self.buffer do buff = buff .. drda.StringUtil.toASCII(self.buffer[i]) end return buff @@ -1179,7 +1179,7 @@ Telnet = { writeable = function (self) -- Returns a list with all writeable fields as {location, length} tuples local writeable_list = {} - for i = 1,#self.fa_buffer do + for i = 0,#self.fa_buffer do if ( self.fa_buffer[i] ~= "\00" ) and (self.fa_buffer[i]:byte(1) & 0x20) ~= 0x20 then -- found writeable flag for j = i,#self.fa_buffer do @@ -1197,7 +1197,7 @@ Telnet = { find = function ( self, str ) local buff = '' - for i = 1,#self.buffer do + for i = 0,#self.buffer do if self.buffer[i] == "\00" then buff = buff .. " " else @@ -1205,20 +1205,20 @@ Telnet = { end end --local buff = self:get_screen() - stdnse.debug(3, "Looking for: "..str) + stdnse.debug(3, "Looking for: " ..str) local i, j = string.find(buff, str) if i == nil then - stdnse.debug(3, "Couldn't find: "..str) + stdnse.debug(3, "Couldn't find: " ..str) return false else - stdnse.debug(3, "Found String: "..str) + stdnse.debug(3, "Found String: " ..str) return i , j end end, isClear = function ( self ) local buff = '' - for i = 1,#self.buffer do + for i = 0,#self.buffer do if self.buffer[i] == "\00" then buff = buff .. " " else @@ -1240,7 +1240,7 @@ Telnet = { -- @returns true if there are any hidden fields in the buffer any_hidden = function ( self ) local hidden_attrib = 0x0c -- 00001100 is hidden - for i = 1,#self.fa_buffer do + for i = 0,#self.fa_buffer do if (self.fa_buffer[i]:byte(1) & hidden_attrib) == hidden_attrib then return true end @@ -1307,7 +1307,7 @@ Telnet = { end stdnse.debug(3,"Printing the overwritten TN3270 buffer") local buff = '\n' - for i = 1,#self.overwrite_buf do + for i = 0,#self.overwrite_buf do if self.overwrite_buf[i] == "\0" then buff = buff .. " " else diff --git a/scripts/tso-brute.nse b/scripts/tso-brute.nse index d9f1b98c4..cb6d6f528 100644 --- a/scripts/tso-brute.nse +++ b/scripts/tso-brute.nse @@ -179,12 +179,23 @@ Driver = { -- IKJ56425I LOGON rejected User already logged on to system register_invalid(user) return true, creds.Account:new(user, "", "User logged on. Skipped.") + elseif (self.tn3270:find("IKJ56425I") and self.tn3270:find("IKJ56418I")) then + -- IKJ56425I LOGON REJECTED, RACF® TEMPORARILY REVOKING USER ACCESS + -- IKJ56418I CONTACT YOUR TSO ADMINISTRATOR + -- The first message (5I) is always followed by the second if the account it revoked + -- But not followed by the second message if its just logged on already + register_invalid(user) -- We dont want to keep generating errors + stdnse.verbose(3,"User: " .. user .. " LOCKED OUT") + return false, brute.Error:new("Account Locked out") elseif not (self.tn3270:find("IKJ56421I") or + self.tn3270:find("IKJ56443I") or self.tn3270:find("TSS7101E") or self.tn3270:find("TSS714[0-3]E") or + self.tn3270:find("TSS7099E") or self.tn3270:find("TSS7120E")) then -- RACF: -- IKJ56421I PASSWORD NOT AUTHORIZED FOR USERID + -- IKJ56443I TSOLOGON RECONNECT REJECTED - USER ACCESS REVOKED BY RACF -- Top Secret: -- TSS7101E Password is Incorrect @@ -193,6 +204,7 @@ Driver = { -- TSS7142E Accessor ID Not Yet Available for Use - Still Inactive -- TSS7143E Accessor ID Has Been Inactive Too Long -- TSS7120E PASSWORD VIOLATION THRESHOLD EXCEEDED + -- TSS7099E Signon credentials invalid -- The 'MSG allows testers to discern any relevant messages they may get for the account' stdnse.verbose(2,"Valid User/Pass: " .. user .. "/" .. pass)