Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /usr/share/nmap/nselib/ |
Upload File : |
--- -- 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) -- -- @class module -- @name ipmi -- @author "Claudiu Perta <claudiu.perta@gmail.com>" local stdnse = require "stdnse" local string = require "string" local rand = require "rand" _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", } channel_auth_request = function() return ( "\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 rmcpplus_header = function (payload_type) return ( "\x06\x00\xff\x07" .. -- RMCP Header "\x06" .. -- RMCP+ Authentication Type string.char(PAYLOADS[payload_type]) .. -- Payload Type "\x00\x00\x00\x00" .. -- Session ID "\x00\x00\x00\x00" -- Sequence Number ) end -- Open rmcpplus_request session_open_request = function(console_session_id) local data = ( "\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 rmcpplus_header("RMCPPLUSOPEN_REQ") .. string.pack("<s2", data) end -- Open rmcpplus_request session_open_cipher_zero_request = function(console_session_id) console_session_id = console_session_id or rand.random_string(4) local data = ( "\x00\x00" .. -- Maximum Access "\x00\x00" .. -- Reserved console_session_id .. "\x00\x00\x00\x08" .. "\x00\x00\x00\x00" .. -- Cipher-zero "\x01\x00\x00\x08" .. "\x00\x00\x00\x00" .. -- Cipher-zero "\x02\x00\x00\x08" .. "\x00\x00\x00\x00" -- No Encryption ) return rmcpplus_header("RMCPPLUSOPEN_REQ") .. string.pack("<s2", data) end rakp_1_request = function(bmc_session_id, console_random_id, username) local data = string.pack( "<Bxxx I c16 Bxx s1", 0, -- Message Tag bmc_session_id, console_random_id, 0x14, -- Privilege level username ) return rmcpplus_header("RAKP1") .. string.pack("<s2", data) end rakp_hmac_sha1_salt = function( console_session_id, bmc_session_id, console_random_id, bmc_random_id, bmc_guid, authorization_level, username) local salt = string.pack( "c4 I c16c16c16 Bs1", console_session_id, bmc_session_id, console_random_id, bmc_random_id, bmc_guid, authorization_level, username ) return salt end verify_rakp_hmac_sha1 = function(salt, hash, password) if not(HAVE_SSL) then return false end local digest = openssl.hmac('sha1', password, salt) return (digest == hash) end --[[ Multi-byte fields in RMCP/ASF fields are specified as being transmitted in 'Network Byte Order' - meaning most-significant byte first. RMCP and ASF-specified fields are therefore transferred most-significant byte first. The IPMI convention is to transfer multi-byte numeric fields least-significant Byte first. Therefore, unless otherwise specified: Data in the IPMI Session Header and IPMI Message fields are transmitted least-significant byte first. --]] parse_channel_auth_reply = function(reply) local data = {} local pos = 1 local value data.rmcp_version, data.rmcp_padding, data.rmcp_sequence, value, pos = string.unpack("<BBBB", reply, pos) data.rmcp_mtype = ((value & 0x80) ~= 0) data.rmcp_class = (value & 0x7F) data.session_auth_type, data.session_sequence, data.session_id, data.message_length, data.ipmi_tgt_address, data.ipmi_tgt_lun, data.ipmi_header_checksum, data.ipmi_src_address, data.ipmi_src_lun, data.ipmi_command, data.ipmi_completion_code, data.ipmi_channel, value, pos = string.unpack("<BI4I4BBBBBBBBBB", reply, pos) data.ipmi_compat_20 = ((value & 0x80) ~= 0) data.ipmi_compat_reserved1 = ((value & 0x40) ~= 0) data.ipmi_compat_oem_auth = ((value & 0x20) ~= 0) data.ipmi_compat_password = ((value & 0x10) ~= 0) data.ipmi_compat_reserved2 = ((value & 0x08) ~= 0) data.ipmi_compat_md5 = ((value & 0x04) ~= 0) data.ipmi_compat_md2 = ((value & 0x02) ~= 0) data.ipmi_compat_none = ((value & 0x01) ~= 0) value, pos = string.unpack("B", reply, pos) data.ipmi_user_reserved1 = ((value >> 6) & 0x03) data.ipmi_user_kg = ((value & 0x20) ~= 0) data.ipmi_user_disable_message_auth = ((value & 0x10) ~= 0) data.ipmi_user_disable_user_auth = ((value & 0x08) ~= 0) data.ipmi_user_non_null = ((value & 0x04) ~= 0) data.ipmi_user_null = ((value & 0x02) ~= 0) data.ipmi_user_anonymous = ((value & 0x01) ~= 0) value, pos = string.unpack("B", reply, pos) data.ipmi_conn_reserved1 = ((value >> 2) & 0x3F) data.ipmi_conn_20 = ((value & 0x02) ~= 0) data.ipmi_conn_15 = ((value & 0x01) ~= 0) -- 24 bits OEMID data.ipmi_oem_id, pos = string.unpack("<I3", reply, pos) data.ipmi_oem_data = reply:sub(pos) return data end parse_open_session_reply = function(reply) local data = {} local pos = 1 local value -- 4 bytes Header data.rmcp_version, data.rmcp_padding, data.rmcp_sequence, value, pos = string.unpack("BBBB", reply, pos) -- bit 1 data.rmcp_mtype = ((value & 0x80) ~= 0) -- bit [2:8] data.rmcp_class = (value & 0x7F) data.session_auth_type, value, pos = string.unpack("BB", reply, pos) -- bit 1 data.session_payload_encrypted = ((value & 0x80) ~= 0) -- bit 2 data.session_payload_authenticated = ((value & 0x40) ~= 0) -- bit [3:8] data.session_payload_type = (value & 0x3F) data.session_id, data.session_sequence, data.message_length, data.ignored1, data.error_code, data.ignored2, data.console_session_id, data.bmc_session_id, pos = string.unpack("<I4I4I2BBI2I4I4", reply, pos) return data end parse_rakp_1_reply = function(reply) local data = {} local pos = 1 local value -- 4 bytes Header data.rmcp_version, data.rmcp_padding, data.rmcp_sequence, value, pos = string.unpack("BBBB", reply, pos) -- bit 1 data.rmcp_mtype = ((value & 0x80) ~= 0) -- bit [2:8] data.rmcp_class = (value & 0x7F) data.session_auth_type, value, pos = string.unpack("BB", reply, pos) -- bit 1 data.session_payload_encrypted = ((value & 0x80) ~= 0) -- bit 2 data.session_payload_authenticated = ((value & 0x40) ~= 0) -- bit [3:8] data.session_payload_type = (value & 0x3F) data.session_id, data.session_sequence, data.message_length, data.ignored1, data.error_code, data.ignored2, data.console_session_id, data.bmc_random_id, data.bmc_guid, data.hmac_sha1, pos = string.unpack("<I4I4I2BBI2I4c16c16c20", reply, pos) return data end return _ENV;