XXE或XML外部实体攻击是一个Web应用程序漏洞,它影响一个网站,该网站解析由用户驱动的不安全XML。成功执行XXE攻击后,可能会泄露网站文件系统中的本地文件。 XXE旨在访问容易受到不安全解析影响的网站的这些敏感本地文件。
XXE攻击的类型
- 文件检索XXE :顾名思义,如果目标系统中存在XXE易受攻击的端点,则受害者公司的应用程序服务器上的任意文件都可能暴露给攻击者。这可以通过在用户控制的文件中传递外部XML实体来实现。
- 盲目XXE:目标系统可能不会从攻击者仍然不安全且容易受到XXE攻击的实体放置的实体中返回数据。这是通过尝试格式错误的用户输入来完成的。这些包括长度超过系统预期的输入,错误的数据类型,特殊实体等。目的是使系统发生故障,并检查是否在错误响应中抛出了一些敏感信息。
- XXE到SSRF:即使系统没有将带有本地文件内容的响应返回给攻击者,在存在XXE攻击的情况下仍然可以利用系统。该实体可以指向目标公司的本地IP,只能通过其网站/网络访问。在XXE有效负载中放置Intranet IP将使目标应用程序调用其本地终结点,否则攻击者将无法访问该本地终结点。这种攻击称为SSRF或服务器端请求伪造。
XML解析
XML是常用的数据交换格式之一。数据可以XML格式在用户和网站之间传输。考虑一个以XML形式接受用户信息的网站。提交到网站的XML如下所示,
XML
Siva
24
Lead
Subbu
25
Developer
XML
&test;;
Java
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class GFGXMLParser
{
public static void main(String[] args)
{
try
{
File file = new File("/Users/Siva-5136/Downloads/Untrusted.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbFactory.newDocumentBuilder();
Document doc = db.parse(file);
NodeList nodeList = doc.getElementsByTagName("userDetails");
//Set XML XXE Related Properties
for (int ind = 0; ind < nodeList.getLength(); ind++)
{
Node node = nodeList.item(ind);
if(Node.ELEMENT_NODE == node.getNodeType() )
{
Element nodeElement = (Element) node;
System.out.println(nodeElement.getElementsByTagName("uId").item(0).getTextContent());
System.out.println(nodeElement.getElementsByTagName("uFirstName").item(0).getTextContent());
}
}
}
catch (Throwable e)
{
System.out.println("Exception Parsing XML ",e);
}
}
}
XML
]>
`&xxe;`
`test`
Java
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class GFGXMLParser
{
public static void main(String[] args)
{
try
{
File file = new File("/Users/Siva-5136/Downloads/Untrusted.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbFactory.newDocumentBuilder();
Document doc = db.parse(file);
NodeList nodeList = doc.getElementsByTagName("userDetails");
//Set XML XXE Related Properties
dbFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
for (int ind = 0; ind < nodeList.getLength(); ind++)
{
Node node = nodeList.item(ind);
if(Node.ELEMENT_NODE == node.getNodeType() )
{
Element nodeElement = (Element) node;
System.out.println(nodeElement.getElementsByTagName("uId").item(0).getTextContent());
System.out.println(nodeElement.getElementsByTagName("uFirstName").item(0).getTextContent());
}
}
}
catch (Throwable e)
{
System.out.println("Exception Parsing XML ",e);
}
}
}
XML
]>
&lol9;
网站接受此XML,对其进行解析以获取Input XML中记录的名称,年龄和职业,然后返回已处理名称的响应。
XML由实体的概念组成,这些实体引用XML文档中的单个对象。实体可以用XML定义,并且可以在整个网站上重复使用多次。例如,
XML格式
&test;;
测试在XML文档中被描述为实体,并且可以在任何地方重用。还可以查找引用某些第三方网站的外部实体。
解析XML文档的代码
有多个XML解析库可解析XML文档并返回Queryable Object。通常,在Java,XML解析如下:
Java
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class GFGXMLParser
{
public static void main(String[] args)
{
try
{
File file = new File("/Users/Siva-5136/Downloads/Untrusted.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbFactory.newDocumentBuilder();
Document doc = db.parse(file);
NodeList nodeList = doc.getElementsByTagName("userDetails");
//Set XML XXE Related Properties
for (int ind = 0; ind < nodeList.getLength(); ind++)
{
Node node = nodeList.item(ind);
if(Node.ELEMENT_NODE == node.getNodeType() )
{
Element nodeElement = (Element) node;
System.out.println(nodeElement.getElementsByTagName("uId").item(0).getTextContent());
System.out.println(nodeElement.getElementsByTagName("uFirstName").item(0).getTextContent());
}
}
}
catch (Throwable e)
{
System.out.println("Exception Parsing XML ",e);
}
}
}
进行XXE攻击
考虑使用输入XML进行控制。输入未经验证,并直接传递到XML解析器。用户可以尝试上传以下XML文件,
XML格式
]>
`&xxe;`
`test`
当XML解析器解析XML输入时,它将通过其定义解析名为“ xxe”的实体。根据输入,将XML实体定义为系统资源“ file:// etc / passwd” ,它是网站应用程序服务器上的敏感本地文件。解析的XML用该敏感本地文件的内容替换实体,并可以将其发送回用户。这称为XML实体攻击。
防范XXE攻击
该网站应通过在解析用户生成的XML内容之前禁用它们来保护自己免受XXE的侵害。如果失败,则该网站容易受到XXE攻击,因此可能向攻击者泄露高度敏感的私人信息。有多种方法可基于用于解析XML源文件的应用程序堆栈和库来禁用此功能。
几乎所有主要的XML解析器都提供了一种在XML解析器本身中禁用XML外部实体的方法。对于上述XML解析示例,代码的安全版本如下所示:
Java
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class GFGXMLParser
{
public static void main(String[] args)
{
try
{
File file = new File("/Users/Siva-5136/Downloads/Untrusted.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbFactory.newDocumentBuilder();
Document doc = db.parse(file);
NodeList nodeList = doc.getElementsByTagName("userDetails");
//Set XML XXE Related Properties
dbFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
for (int ind = 0; ind < nodeList.getLength(); ind++)
{
Node node = nodeList.item(ind);
if(Node.ELEMENT_NODE == node.getNodeType() )
{
Element nodeElement = (Element) node;
System.out.println(nodeElement.getElementsByTagName("uId").item(0).getTextContent());
System.out.println(nodeElement.getElementsByTagName("uFirstName").item(0).getTextContent());
}
}
}
catch (Throwable e)
{
System.out.println("Exception Parsing XML ",e);
}
}
}
相关漏洞
与XML解析相关的另一个常见漏洞称为“十亿笑攻击”。它使用实体来周期性地解决自身问题,从而消耗更多的CPU使用率并引起拒绝服务攻击。可能导致XXE攻击的XML有效负载示例如下:
XML格式
]>
&lol9;
实体会不断地对其自身进行解析,从而减慢请求速度并在应用程序上造成DOS攻击。十亿个笑声攻击可能像上面的代码片段中所述完全禁用DOCTYPE或对实体的评估设置了最大限制。
XXE的影响和十亿次攻击
- XXE可能导致信息泄漏,它可能泄漏具有关键数据的系统文件。
- 从XXE获得的数据可用于针对其他漏洞的网站。
- 十亿个笑可能会导致服务中断或拒绝服务攻击。