📜  XML外部实体(XXE)和十亿笑

📅  最后修改于: 2021-04-17 01:29:12             🧑  作者: Mango

XXE或XML外部实体攻击是一个Web应用程序漏洞,它影响一个网站,该网站解析由用户驱动的不安全XML。成功执行XXE攻击后,可能会泄露网站文件系统中的本地文件。 XXE旨在访问容易受到不安全解析影响的网站的这些敏感本地文件。

XXE攻击的类型

  1. 文件检索XXE :顾名思义,如果目标系统中存在XXE易受攻击的端点,则受害者公司的应用程序服务器上的任意文件都可能暴露给攻击者。这可以通过在用户控制的文件中传递外部XML实体来实现。
  2. 盲目XXE:目标系统可能不会从攻击者仍然不安全且容易受到XXE攻击的实体放置的实体中返回数据。这是通过尝试格式错误的用户输入来完成的。这些包括长度超过系统预期的输入,错误的数据类型,特殊实体等。目的是使系统发生故障,并检查是否在错误响应中抛出了一些敏感信息。
  3. 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的影响和十亿次攻击

  1. XXE可能导致信息泄漏,它可能泄漏具有关键数据的系统文件。
  2. 从XXE获得的数据可用于针对其他漏洞的网站。
  3. 十亿个笑可能会导致服务中断或拒绝服务攻击。