㈠ 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();
}
}
}
不知道你想幹嘛。。。