自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

從JDK源碼來看XXE的觸發(fā)原理和對應的防御手段

安全 應用安全
這幾天繼續(xù)在重寫GadgetInspector工具,進一步的增強該自動化工具的source點和sink點,同時增強過程中的漏報和誤報的問題。

前言

這幾天繼續(xù)在重寫GadgetInspector工具,進一步的增強該自動化工具的source點和sink點,同時增強過程中的漏報和誤報的問題。

這里主要是對其中有關(guān)于XXE中的兩點sink進行幾點分析。

sinks

DocumentBuilder類

這個JDK中內(nèi)置的類是一種的DOM型的解釋器,該種Parser的特點是將完整的xml文檔內(nèi)容加載到樹結(jié)構(gòu)中去,然后我們通過遍歷結(jié)點來獲取我們需要的內(nèi)容。

首先編寫一段實例代碼,來使用DocumentBuilder類來讀取xml文檔的內(nèi)容。

Employee.xml

<employees>
<employee id="111">
<firstName>Rakesh</firstName>
<lastName>Mishra</lastName>
<location>Bangalore</location>
</employee>
<employee id="112">
<firstName>John</firstName>
<lastName>Davis</lastName>
<location>Chennai</location>
</employee>
<employee id="113">
<firstName>Rajesh</firstName>
<lastName>Sharma</lastName>
<location>Pune</location>
</employee>
</employees>

DOMParserDemo.java。

public class DOMParserDemo {
public static void main(String[] args) throws Exception{
// 獲取DOM Builder Factory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

// 獲取DOM Builder
DocumentBuilder builder = factory.newDocumentBuilder();

// 加載xml文檔
Document document = builder.parse("Employee.xml");

// 建立一個鏈表存放Employee對象
List<Employee> employeeList = new ArrayList<>();

// 提取數(shù)據(jù)
NodeList nodeList = document.getDocumentElement().getChildNodes();

// 迭代進行讀取xml文檔
for (int i = 0; i < nodeList.getLength(); i++) {
// 獲取對應結(jié)點,這里的結(jié)點是employee標簽
Node node = nodeList.item(i);

if (node instanceof Element) {
// 創(chuàng)建一個Employee空對象
Employee employee = new Employee();
// 獲取xml文檔中的id值
employee.id = node.getAttributes().getNamedItem("id").getNodeValue();
// 獲取子結(jié)點信息
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
// 獲取對應結(jié)點
Node node1 = childNodes.item(j);
if (node1 instanceof Element) {
// 獲取對應的信息
String content = node1.getTextContent().trim();
switch (node1.getNodeName()) {
case "firstName":
employee.firstName = content;
break;
case "lastName":
employee.lastName = content;
break;
case "location":
employee.location = content;
break;
}
}
}
// 將獲取的每一個對象添加進入列表中去
employeeList.add(employee);
}
}
// 打印數(shù)據(jù)
for (Employee employee : employeeList) {
System.out.println(employee);
}
}
}

這種方式就是遍歷xml文檔中的一個一個的文檔來進行對應信息的讀取。

image-20221218203218462.png

這里只是一個簡單的使用該種解釋器進行xml文檔的讀取。

我們主要是進行XXE的展示。

XXE.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "http://127.0.0.1:9999">
]>
<doc>&xxe;</doc>

主要的漏洞點是在調(diào)用DocumentBuilder#parse方法進行xml文檔的加載的時候,如果加載的是上面給出的xml內(nèi)容,將會導致XXE。

image-20221218203915774.png

簡單的調(diào)試了一下。

resolveEntity:95, ChainingEntityResolver (weblogic.xml.jaxp)
resolveEntity:110, EntityResolverWrapper (com.sun.org.apache.xerces.internal.util)
resolveEntityAsPerStax:997, XMLEntityManager (com.sun.org.apache.xerces.internal.impl)
startEntity:1212, XMLEntityManager (com.sun.org.apache.xerces.internal.impl)
scanEntityReference:1908, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
next:3061, XMLDocumentFragmentScannerImpl$FragmentContentDriver (com.sun.org.apache.xerces.internal.impl)
next:602, XMLDocumentScannerImpl (com.sun.org.apache.xerces.internal.impl)
scanDocument:505, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
parse:842, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:771, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:141, XMLParser (com.sun.org.apache.xerces.internal.parsers)
parse:243, DOMParser (com.sun.org.apache.xerces.internal.parsers)
parse:339, DocumentBuilderImpl (com.sun.org.apache.xerces.internal.jaxp)
parse:163, RegistryDocumentBuilder (weblogic.xml.jaxp)
parse:177, DocumentBuilder (javax.xml.parsers)
main:22, DOMParserDemo (study.xmlParser)

在將xml文檔路徑傳入了DocumentBuilder#parser方法之后。

image-20221218220213785.png

將會將其轉(zhuǎn)換為InputSource類傳入DocumentBuilderImpl#parser方法中進行解析。

image-20221218220853160.png

這里將會調(diào)用DOMParser#parser繼續(xù)進行解析。

image-20221218221015832.png

按照其中的邏輯將會一次性加載xml文件的所有內(nèi)容,之后通過調(diào)用parse方法進行解析。

最后經(jīng)過一系列的解析,特別是通過調(diào)用XMLDocumentFragmentScannerImpl#scanEntityReference方法的調(diào)用來掃描獲取xml文件中的實體,之后方法中調(diào)用了XMLEntityManager#startEntity方法進行實體的處理。

image-20221218221758389.png

在該方法中存在有是否是外部實體的判斷,如果存在有外部實體,將會調(diào)用resolveEntityAsPerStax方法來獲取外部實體中的信息,這里將會發(fā)起一個請求,也即能達到前面截圖中的效果。

防御方法
  • 可以采用禁用所有DTDs的方式.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
  • 如果業(yè)務需要存在有DTD的使用,我們可以轉(zhuǎn)而求其次,禁用XML中的外部實體和參數(shù)實體.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); //防止外部實體
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //防止參數(shù)實體
  • 較為完整的修復方式。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null;
FEATURE = "http://javax.xml.XMLConstants/feature/secure-processing";
dbf.setFeature(FEATURE, true);
FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true);
FEATURE = "http://xml.org/sax/features/external-parameter-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://xml.org/sax/features/external-general-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
dbf.setFeature(FEATURE, false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
DocumentBuilder builder = dbf.newDocumentBuilder();
builder.parse(xxxx);

SAXParser類

接下來的一個XXE的sink點就是在SAXParser#parser方法的調(diào)用中,這種方式的xml文檔的解析,主要是依靠的SAX Parser這個,這個解析器的不同于DOM Parser,這個解釋器是不會直接將完整的XML文檔加載進入內(nèi)存中,這種解釋器轉(zhuǎn)而逐行進行XML文檔的解析,當他們遇到不同的元素的時候觸發(fā)不同的事件,例如:開始標簽 / 結(jié)束標簽 / 字符類似的數(shù)據(jù)等等事件類型,這種解釋器是一種基于事件的解釋器。

這里也是簡單的舉一個例子,使用的xml文件也是上面已經(jīng)提到了的Employee.xml文件內(nèi)容

而對于讀取xml文件的實例。

SAXParserDemo.java

public class SAXParserDemo extends Exception {
public static void main(String[] args) throws Exception{
// 創(chuàng)建SAXParser Factory
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
// 創(chuàng)建自定義的handler對象
SAXHandler saxHandler = new SAXHandler();
// 加載xml文檔,加上自定義的handler對象
saxParser.parse("Employee.xml", saxHandler);
// 打印結(jié)果
for (Employee employee : saxHandler.employeeList) {
System.out.println(employee);
}
}

}
class SAXHandler extends DefaultHandler {
// 定義屬性
List<Employee> employeeList = new ArrayList<>();
Employee employee = null;
String content = null;

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
switch (qName) {
case "employee":
// 如果遇到了employee標簽采用的邏輯
employee = new Employee();
employee.id = attributes.getValue("id");
break;
}
}

@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
switch (qName) {
// 遇到結(jié)束標簽采用的邏輯
case "firstName":
employee.firstName = content;
break;
case "lastName":
employee.lastName = content;
break;
case "location":
employee.location = content;
break;
case "employee":
employeeList.add(employee);
break;
}
}

@Override
public void characters(char[] ch, int start, int length) throws SAXException {
content = String.copyValueOf(ch, start, length).trim();
}
}

這種解釋器的方式,主要是在傳入xml文件路徑的時候,同時傳入了一個handler對象,這個對象是繼承了DefaultHandler這個內(nèi)置的默認Handler對象的。

在這個類中定義了很多方法。

image-20221218224652398.png

在查看這個類的結(jié)構(gòu)的時候,其中這個類是實現(xiàn)了幾個接口的,其中實現(xiàn)的有一個接口是ContentHandler,在這個接口中定義了多個和XML文檔內(nèi)容有關(guān)的方法。

  • startDocument()
  • endElement()
  • endDocument()
  • startElement()
  • ......

有關(guān)這些方法的作用,也是很明顯,運行一下子看看效果。

image-20221218225941740.png

如果我們將XML文檔的地址替換成XXE.xml路徑,同樣將會觸發(fā)XXE,同樣簡單的調(diào)試了一下。

startElement:36, SAXHandler (study.xmlParser)
startElement:509, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
startElement:745, XMLDTDValidator (com.sun.org.apache.xerces.internal.impl.dtd)
scanStartElement:1359, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
scanRootElementHook:1289, XMLDocumentScannerImpl$ContentDriver (com.sun.org.apache.xerces.internal.impl)
next:3132, XMLDocumentFragmentScannerImpl$FragmentContentDriver (com.sun.org.apache.xerces.internal.impl)
next:852, XMLDocumentScannerImpl$PrologDriver (com.sun.org.apache.xerces.internal.impl)
next:602, XMLDocumentScannerImpl (com.sun.org.apache.xerces.internal.impl)
scanDocument:505, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
parse:842, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:771, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:141, XMLParser (com.sun.org.apache.xerces.internal.parsers)
parse:1213, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
parse:643, SAXParserImpl$JAXPSAXParser (com.sun.org.apache.xerces.internal.jaxp)
parse:392, SAXParser (javax.xml.parsers)
parse:274, SAXParser (javax.xml.parsers)
main:20, SAXParserDemo (study.xmlParser)

對于這種解釋器,和上面的一種不同在于,前面主要是調(diào)用的DOMParser類進行解析,而這里主要是調(diào)用了SAXParser類進行解析。

在對應的parse方法中。

image-20221219192432895.png

傳入了兩個參數(shù),一個是XML文檔的路徑,一個是自己實現(xiàn)的繼承了DefaultHandler類的類對象

在將XML文檔路徑封裝成了InputSource對象之后進行解析的邏輯。

image-20221219192713039.png

這里不同于前面的,這里在創(chuàng)建了一個XMLReader對象之后,設定了對應的Handler對象。

獨特的點體現(xiàn)在調(diào)用XMLDocumentFragmentScannerImpl#scanDocument方法進行XML的掃描的過程中

在掃描到ROOT Element位置的時候,將會觸發(fā)對應的Hook點。

image-20221219194828661.png

具體點就是調(diào)用了scanRootElementHook方法。

image-20221219195111257.png

image-20221219195122866.png

這里是配置了對應的Handler的,這里將會在AbstractSAXParser#startElement方法的調(diào)用中,調(diào)用其中的ContentHandler的對象方法進行處理。

image-20221219195254624.png

防御方法。

SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
SAXParser parser = spf.newSAXParser();
parser.parse(InputSource, (HandlerBase) null);

責任編輯:武曉燕 來源: FreeBuf.COM
相關(guān)推薦

2016-01-12 09:47:07

2021-06-01 09:26:20

網(wǎng)絡安全APT代碼

2020-12-01 09:17:24

網(wǎng)絡安全DDoS服務器

2013-08-27 22:04:27

2010-09-26 09:20:34

2014-07-09 15:41:51

2019-12-31 14:15:56

網(wǎng)絡安全區(qū)塊鏈技術(shù)

2010-04-20 14:15:49

負載均衡產(chǎn)品

2022-05-03 23:21:13

安全意識網(wǎng)絡安全網(wǎng)絡釣魚

2019-03-12 05:37:12

斷電事件網(wǎng)絡攻擊

2009-12-15 10:57:05

2022-11-30 09:07:09

JDK源碼數(shù)組

2022-06-03 23:30:26

應用安全數(shù)據(jù)財務預算

2023-04-28 09:44:51

Java源碼Native

2011-09-07 15:07:52

2016-01-26 14:36:06

混合云混合云成本混合云安全

2025-02-24 08:24:25

2024-09-27 08:25:47

2013-05-14 09:56:37

2009-07-08 14:06:22

ClassLoaderJDK源碼
點贊
收藏

51CTO技術(shù)棧公眾號