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/auxiliary/scanner/misc/ibm_mq_enum.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::Tcp7include Msf::Auxiliary::Scanner8include Msf::Auxiliary::Report910def initialize(info = {})11super(update_info(info,12'Name' => 'Identify Queue Manager Name and MQ Version',13'Description' => 'Run this auxiliary against the listening port of an IBM MQ Queue Manager to identify its name and version. Any channel type can be used to get this information as long as the name of the channel is valid.',14'Author' => [ 'Petros Koutroumpis' ],15'License' => MSF_LICENSE16))17register_options(18[19OptString.new('CHANNEL', [ true, "Channel to use" ,"SYSTEM.DEF.SVRCONN"]),20OptInt.new('CONCURRENCY', [true, "The number of concurrent ports to check per host", 10]),21OptInt.new('TIMEOUT', [true, "The socket connect timeout in seconds", 10]),22OptString.new('PORTS', [true, 'Ports to probe', '1414']),2324])25deregister_options('RPORT')26end272829def create_packet(channel_type)30chan = datastore['CHANNEL'] + "\x20"*(20-datastore['CHANNEL'].length.to_i)31if channel_type == 032chan_type = "\x26"33elsif channel_type == 134chan_type = "\x07"35elsif channel_type == 236chan_type = "\x08"37end3839packet = "\x54\x53\x48\x20" + # StructID40"\x00\x00\x01\x0c" + # MQSegmLen41"\x02" + # ByteOrder42"\x01" + # SegmType43"\x01" + # CtlFlag144"\x00" + # CtlFlag245"\x00\x00\x00\x00\x00\x00\x00\x00" + # LUW Ident46"\x22\x02\x00\x00" + # Encoding47"\xb5\x01" + # CCSID48"\x00\x00" + # Reserved49"\x49\x44\x20\x20" + # StructId50"\x0d" + # FAP level51chan_type + # CapFlag1 - Message Type52"\x00" + # ECapFlag153"\x00" + # IniErrFlg154"\x00\x00" + # Reserved55"\x32\x00" + # MaxMsgBtch56"\xec\x7f\x00\x00" + # MaxTrSize57"\x00\x00\x40\x00" + # MaxMsgSize58"\xff\xc9\x9a\x3b" + # SeqWrapVal59chan + # Channel Name60"\x87" + # CapFlag261"\x00" + # ECapFlag262"\x5b\x01" + # ccsid63"QM1" + "\x20"*45 + # Queue Manager Name64"\x2c\x01\x00\x00" + # HBInterval65"\x8a\x00" + # EFLLength66"\x00" + # IniErrFlg267"\x55" + # Reserved168"\x00\xff" + # HdrCprsLst69"\x00\xff\xff\xff\xff\xff\xff\xff\xff" + # MsgCprsLst170"\xff\xff\xff\xff\xff\xff\xff" + # MsgCprsLst271"\x00\x00" + # Reserved272"\x00\x00\x00\x00" + # SSLKeyRst73"\x00\x00\x00\x00" + # ConvBySkt74"\x05" + # CapFlag375"\x00" + # ECapFlag376"\x00\x00" + # Reserved377"\x10\x13\x00\x00" + # ProcessId78"\x01\x00\x00\x00" + # ThreadId79"\x01\x00\x00\x00" + # TraceId80"MQMM09000000" + # ProdId81"MQMID" + "\x20"*43 + # MQM ID82"\x00\x00\xff\xff\xff\xff\xff\xff\xff" + # Unknown183"\xff\xff\xff\xff\xff\xff\xff\xff\xff" + # Unknown284"\xff\xff\x00\x00\x00\x00\x00\x00\x00" + # Unknown385"\x00\x00\x00\x00\x00" # Unknown486end878889def run_host(ip)90chan = datastore['CHANNEL']91if chan.length > 2092print_error("Channel name must be less than 20 characters.")93raise Msf::OptionValidateError.new(['CHANNEL'])94end95ports = Rex::Socket.portspec_crack(datastore['PORTS'])96while(ports.length > 0)97t = []98r = []99begin1001.upto(datastore['CONCURRENCY']) do101this_port = ports.shift102break if not this_port103t << framework.threads.spawn("Module(#{self.refname})-#{ip}:#{this_port}", false, this_port) do |port|104begin105data_recv = ""1063.times do |channel_type|107data_recv = send_packet(ip,port,channel_type)108if data_recv.nil?109next110end111# check if CHANNEL_WRONG_TYPE error received and retry with different type112if data_recv[data_recv.length-4...data_recv.length] != "\x02\x00\x00\x00"113break114end115end116if data_recv.nil?117print_status("No response received. Try increasing TIMEOUT value.")118print_line119next120end121status_code = data_recv[-4..-1]122if status_code == "\x18\x00\x00\x00"123print_status("Channel Requires SSL. Could not get more information.")124print_line125end126if not data_recv[0...3].include?('TSH')127next128end129if status_code == "\x01\x00\x00\x00"130print_error('Channel "' + chan + '" does not exist.')131print_line132end133if status_code == "\x02\x00\x00\x00" or status_code == "\x06\x00\x00\x00"134print_error('Unsupported channel type. Try a different channel.')135print_line136end137if data_recv.length < 180138next139end140qm_name = data_recv[76...124].delete(' ')141mq_version = data_recv[180...188].scan(/../).collect{|x| x.to_i}.join('.')142print_good("#{ip}:#{port} - Queue Manager Name: #{qm_name} - MQ Version: #{mq_version}")143print_line144end145end146end147t.each {|x| x.join }148end149end150end151152def send_packet(ip,port,channel_type)153begin154timeout = datastore['TIMEOUT'].to_i155packet = create_packet(channel_type)156s = connect(false,157{158'RPORT' => port,159'RHOST' => ip,160}161)162s.put(packet)163data = s.get_once(-1,timeout)164return data165rescue ::Rex::ConnectionRefused166print_error("#{ip}:#{port} - TCP Port Closed.")167print_line168rescue ::Rex::ConnectionError, ::IOError, ::Timeout::Error, Errno::ECONNRESET169print_error("#{ip}:#{port} - Connection Failed.")170print_line171rescue ::Interrupt172raise $!173ensure174if s175disconnect(s) rescue nil176end177end178end179180end181182183