㈠ java中object和xml互相转换
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Object2XML {
public static String object2XML(Object obj, String outFileName)
throws FileNotFoundException {
// 构造输出XML文件的字节输出流
File outFile = new File(outFileName);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(outFile));
// 构造一个XML编码器
XMLEncoder xmlEncoder = new XMLEncoder(bos);
// 使用XML编码器写对象
xmlEncoder.writeObject(obj);
// 关闭编码器
xmlEncoder.close();
return outFile.getAbsolutePath();
}
public static Object xml2Object(String inFileName)
throws FileNotFoundException {
// 构造输入的XML文件的字节输入流
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(inFileName));
// 构造一个XML解码器
XMLDecoder xmlDecoder = new XMLDecoder(bis);
// 使用XML解码器读对象
Object obj = xmlDecoder.readObject();
// 关闭解码器
xmlDecoder.close();
return obj;
}
public static void main(String[] args) throws IOException {
// 构造一个StudentBean对象
StudentBean student = new StudentBean();
student.setName("wamgwu");
student.setGender("male");
student.setAge(15);
student.setPhone("55556666");
// 将StudentBean对象写到XML文件
String fileName = "AStudent.xml";
Object2XML.object2XML(student, fileName);
// 从XML文件读StudentBean对象
StudentBean aStudent = (StudentBean)Object2XML.xml2Object(fileName);
// 输出读到的对象
System.out.println(aStudent.toString());
}
}
㈡ Java 反序列化之 XStream 反序列化
在Java的世界中,XStream就像一座桥梁,连接着Java对象和XML的交流。它的核心功能在于实现对象与XML的双向转化,让我们一一探索它的奥秘。
首先,XStream的序列化过程,就是通过XStream的toXML(Person obj)方法,将Person类的实例转化为XML格式的文本。反序列化则是通过fromXML(String xml),从XML字符串中解析并重建Person对象的实例。
XStream的内部机制由四个关键组件构成:MarshallingStrategy(编码策略)、Mapper、Converter和EventHandler。其中,Converter是核心组件,它扮演着Java对象与XML标签间转换的桥梁。Converter类必须实现canConvert(Class type)、marshal(Object obj, HierarchicalStreamWriter writer)和unmarshal(HierarchicalStreamReader reader, Class type)这三个方法,确保数据在两者间的无缝流转。更详细的使用指南可以在XStream官方文档中找到。
EventHandler则扮演动态事件监听者的角色,它通过InvocationHandler与用户界面和应用逻辑紧密相连。在invokeInternal(Object proxy, Method method, Object[] args)这个关键方法中,XStream会根据方法名的不同,执行相应的操作,如处理equals、hashCode和toString等特殊方法,以及类和对象操作。
当XStream利用动态代理作为sink时,DynamicProxyConverter就起着关键作用。它负责将XML中的<dynamic-proxy>标签转换为动态代理对象,这也是CVE-2013-7285反序列化漏洞的触发点。通过构造恶意XML,攻击者能够利用这个机制,执行恶意代码,因为XStream会按照指定的接口执行handler中的方法。
在调试和修复过程中,XStream的解析流程显得尤为重要。例如,通过ams.readClassType(String xml)获取PoC XML的根标签类型,随后使用Mapper的realClass(Class type)功能遍历XML,将SortedSet转换为TreeSet。这个过程涉及到TreeMapConverter和AbstractReferenceUnmarshaller,它们在getCurrentReferenceKey()中关联了Reference键和类型,确保数据的正确转换。
深入到FastStack.convert()方法,我们看到treeMapConverter.unmarshalComparator()负责解析XML子元素,reader.movedown()则在此过程中添加子元素到pathTracker,确保了XML结构的完整解析。
在TreeSetConverter.unmarshal()中,每读取一个元素,都会调用putCurrentEntryIntoMap(readItem()),递归处理动态-proxy元素。整个过程,XStream最终返回一个DynamicProxyMapper$DynamicProxy实例,根据XML中的<interface>和<handler>标签,动态创建代理对象,并执行handler指定的方法。
当遇到攻击性XML时,XStream会调用EventHandler.invoke(),执行如java.lang.ProcessBuilder#start这样的操作,从而触发恶意代码执行。为了修复这个漏洞,官方采取了增加黑名单和自定义Converter等策略,限制对特定类(如java.beans.EventHandler和java.lang.ProcessBuilder)的转换,以增强安全性。
总结来说,理解XStream的反序列化机制,特别是与CVE-2013-7285相关的漏洞,不仅有助于我们深入掌握XML与Java对象交互的底层逻辑,也能为我们提供攻防策略的启示。这是一段值得深入研究和学习的历程。
参考文献:CVE-2013-7285详细资料
㈢ java将一串xml字符串转换成list,如果不好做的话,直接转换成dataset也行
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class XmlTest4 {
public static void main(String[] args) {
String xmlDoc = "<?xml version=Ƈ.0' encoding='UTF-8'?>" +
"<data result=' message='查询成功'>" +
"<certificateinfo>" +
"<certificateid><![CDATA[证照编号]]></certificateid>" +
"<certificatename><![CDATA[证照名称]]></certificatename>" +
"</certificateinfo>" +
"</data>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
Document doc = null;
try {
db = dbf.newDocumentBuilder();
doc = db.parse(new ByteArrayInputStream(xmlDoc.getBytes("UTF-8")));
System.out.println(doc.getElementsByTagName("certificateid").item(0).getTextContent());
System.out.println(doc.getElementsByTagName("certificatename").item(0).getTextContent());
}
catch (SAXException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
catch (ParserConfigurationException e) {
e.printStackTrace();
}
}
}
不知道你想干嘛。。。