--- -- A module implementing IPMI protocol (the code is a porting of the Metasploit ipmi scanner: -- https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/ipmi) -- -- @author "Claudiu Perta " local bin = require "bin" local bit = require "bit" local math = require "math" local stdnse = require "stdnse" local table = require "table" _ENV = stdnse.module("ipmi", stdnse.seeall) local HAVE_SSL, openssl = pcall(require,"openssl") PAYLOADS = { ["IPMI"] = 0, ["PAYLOAD_SOL"] = 1, ["RMCPPLUSOPEN_REQ"] = 0x10, ["RMCPPLUSOPEN_REP"] = 0x11, ["RAKP1"] = 0x12, ["RAKP2"] = 0x13, ["RAKP3"] = 0x14, ["RAKP4"] = 0x15, } RMCP_ERRORS = { [1] = "Insufficient resources to create new session \ (wait for existing sessions to timeout)", -- Shouldn't occur. [2] = "Invalid Session ID", -- Shouldn't occur. [3] = "Invalid payload type", -- If these happen, we need to enhance our mechanism for detecting -- supported auth algorithms. [4] = "Invalid authentication algorithm", [5] = "Invalid integrity algorithm", [6] = "No matching authentication payload", [7] = "No matching integrity payload", -- This suggests the session was timed out while trying to negotiate, -- shouldn't happen. [8] = "Inactive Session ID", [9] = "Invalid role", [0xa] = "Unauthorised role or privilege level requested", [0xb] = "Insufficient resources to create a session at the requested role", [0xc] = "Invalid username length", [0xd] = "Unauthorized name", [0xe] = "Unauthorized GUID", [0xf] = "Invalid integrity check value", [0x10] = "Invalid confidentiality algorithm", [0x11] = "No cipher suite match with proposed security algorithms", -- Never observed, most likely a bug in xCAT or IPMI device. [0x12] = "Illegal or unrecognized parameter", } Helper = { new = function(self, o) local o ={} setmetatable(o, self) self.__index = self return o end, checksum = function(self, data) local sum = 0 -- TODO(claudiu) Finish implementation. local pos, str = bin.unpack("A", data, 0) end, random_text = function(self, len) local text = "" for i = 1, len do text = text .. string.char(math.random(255)) end return text end, random_console_session_id = function(self) local console_session_id = "" local len = 4 for i = 1, len do console_session_id = console_session_id .. string.char(math.random(255)) end return console_session_id end, channel_auth_request = function(self) return bin.pack( "AAAA", "\x06\x00\xff\x07", -- Header "\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x09\x20\x18", "\xc8\x81\x00\x38\x8e\x04\xb5") end, -- Open rmcpplus_request session_open_request = function(self, console_session_id) local header = bin.pack( "AACAA", "\x06\x00\xff\x07", -- RMCP Header "\x06", -- RMCP+ Authentication Type PAYLOADS["RMCPPLUSOPEN_REQ"], -- Payload Type "\x00\x00\x00\x00", -- Session ID "\x00\x00\x00\x00" -- Sequence Number ) local data = bin.pack( "AAAAAAAAA", "\x00\x00", -- Maximum Access "\x00\x00", -- Reserved console_session_id, "\x00\x00\x00\x08", "\x01\x00\x00\x00", "\x01\x00\x00\x08", "\x01\x00\x00\x00", -- HMAC-SHA1 "\x02\x00\x00\x08", "\x01\x00\x00\x00" -- AES Encryption ) return bin.pack("