XML编程基础

XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 的设计宗旨是传输数据,而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准
###XML标签根据自己主观定义,不像HTML是被预定义好的

<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

上例中的标签没有在任何 XML 标准中定义过(比如 和 )。这些标签是由文档的创作者发明的。

这是因为 XML 没有预定义的标签。

在 HTML 中使用的标签(以及 HTML 的结构)是预定义的。HTML 文档只使用在 HTML 标准中定义过的标签(比如

等等)。

XML 允许创作者定义自己的标签和自己的文档结构。

DTD

DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。

它使用一系列的合法元素来定义文档结构。可被成行地声明于 XML 文档中,也可作为一个外部引用。

1.假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:

如:

<?xml version="1.0"  encoding="utd-8"?> ##version声明版本号,encoding声明编码方式一定要写
<!DOCTYPE note [<!ELEMENT note (to,from,heading,body)><!ELEMENT to      (#PCDATA)><!ELEMENT from    (#PCDATA)><!ELEMENT heading (#PCDATA)><!ELEMENT body    (#PCDATA)>
]>
<note><to>黑娃</to><from>铁蛋</from><heading>语录</heading><body>加油!奥利给!</body>
</note>

2.假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:

//文件名是指上面面中元素声明保存的在哪个文件的文件名,类似于首先将元素声明写在该文件中然后通过SYSTEM调用该文件,在下方的代码中则不需要再写元素申明
注意外部实体引用时的关键字“SYSTEM”,同时也可以使用“PUBLIC”这个关键字,这两者的区别在于,SYSTEM表示私有的DTD,PUBLIC表示共有的DTD。

3.在 DTD 中,XML 元素通过元素声明来进行声明。
1.元素声明使用下面的语法:

<!ELEMENT 元素名称 类别>

例:<!ELEMENT to CDATA>

或者是:<!ELEMENT 元素名称 (元素内容)>
例:<!ELEMENT note (to,from,heading,body)>

2.对于空元素则通过类别关键词EMPTY进行声明:

<!ELEMENT 元素名称 EMPTY>

例:<!ELEMENT note EMPTY>

XML中5个预定义好的符号

< < 小于号
> > 大于号
& & 和
’ ’ 单引号
" " 双引号
尤其是<和&符,在我们编写时不能自定义使用,倘若我们非要使用这些符号,某些文本,比如 JavaScript 代码,包含大量 “<” 或 “&” 字符。为了避免错误,可以将脚本代码定义为 CDATA。怎可以通过CDATA编码。
##在CDATA编码,被CDATA框住的部分,XML编译器会直接忽略,在这其中我们可以包含XML中禁止自定义的5中标识符
CDATA 部分由 “<![CDATA[" 开始,由 "]]>” 结束:

<script>
<![CDATA[
function matchwo(a,b)
{
if (a < b && a < 0) then{return 1;}
else{return 0;}
}
]]>
</script>

CDATA 部分不能包含字符串 “]]>”。也不允许嵌套的 CDATA 部分。

标记 CDATA 部分结尾的 “]]>” 不能包含空格或折行。

DTD外部实体及内部实体

1)内部实体声明:
声明语法:

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

  一个实体的引用,由三部分构成:&符号, 实体名称, 分号。内部实体引用示例:

<?xml version="1.0" encoding="UTF-8"?>

]>
&test;
使用浏览器进行访问,并将xml代码作为参数传入,可以不复制xml声明,记得要将引用实体时的“&”手动编码为“&”(因为我们这里使用的是GET传参的方式,所以传入的内容会被进行URL编码,但是&在URL中被认为是两个参数的分隔符,所以如果我们不对其进行URL编码转换,浏览器会把它当作参数的分隔符来处理)
2)外部实体声明:
声明语法:

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

外部实体引用示例:

<?xml version="1.0" encoding="UTF-8"?>

]>

&xxe;
声明一个外部实体的关键在于“SYSTEM”这个关键字。SYSTEM在此意图让xml解析器知道,现在声明的是一个外部实体,需要从后面的外部资源中获取内容并存储在内部实体,如果后面的外部资源的语法,存在特殊符号,那么xml解析器会报错。
外部实体引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,比如http、file、ftp等,具体内容如下所示:
参数实体应注意以下几点:

DTD参数实体

参数实体声明:

内部:<!ENTITY % 实体名称 "实体值">
外部:<!ENTITY % 实体名称 SYSTEM "URI">
(1)使用 % 实体名(这里面空格不能少) 在 DTD 中定义,并且只能在 DTD 中使用 “%实体名;” 引用
(2)只有在 DTD 文件中,参数实体的声明才能引用其他实体
(3)和通用实体一样,参数实体也可以外部引用

简单理解呢,就是参数实体不能像普通实体那样在xml文档内容中进行引用,它的引用范围只在当前xml文件的DTD声明中,或者是当前的DTD文件中。

参数实体引用示例:

<?xml version="1.0" encoding="UTF-8"?>

**%xxe;**

]>


xml文档内容中使用“&hello”来引用定义的普通实体hello。所以这个时候,我们直接使用浏览器查看的时候,会是上面的显示。

XXE漏洞

XXE就是XML外部实体注入。当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。

利用场景:有回显和无回显

有回显的情况可以直接在页面中看到Payload的执行结果或现象(带内XML外部实体(XXE),即攻击者可以发送带有XXE有效负载的请求并从包含某些数据的Web应用程序获取响应)
抓包后构造外部实体引用,一般填写本地系统中一定纯在的文档如图中所示,发送包后可以发现文件内 内容被显示了出来
这样我们就读取到了windows系统的system.ini的文件内容。
但是这样也不代表这个payload的就适用于任何情况,比如我们更换一个读取的文件xmltest2.txt,内容是:

发送数据包后就会发现产生报错,原因是xml对于5种预定义符是会产生报错提示的


解决办法:XML CDATA
我们也大概知道了CDATA的使用方式,但是其还需要注意几点:
a. CDATA 部分不能包含字符串 “]]>”。也不允许嵌套的 CDATA 部分,这样会导致异常的闭合,从而使解析器报错。
b. 标记 CDATA 部分结尾的 “]]>” 不能包含空格或换行。
那么了解了这些,我们就可以尝试使用CDATA再次去读取目标文件的内容,我们首先需要把要读取的到的内容放在CDATA中,但是CDATA并没有提供拼接的方法,所以我们暂且使用普通实体进行拼接尝试(注意是尝试):
我们尝试直接使用实体来进行拼接,但是测试失败:
这说明我们的拼接方式不可行,我们现在使用的是一般实体,我们在前面的xml基础知识中介绍过了,一般实体的引用是在xml文档内容中,既然在xml文档内容中拼接不可行,那再dtd中拼接可行吗?我们再次进行尝试,既然再dtd中拼接,那就需要用到参数实体了。
我们再次尝试构造payload:
理论上,我们完美地将这几个参数实体拼接了起来,并将值赋给了一般实体all,但是遗憾的是,我们的payload还是报错了:

那么这又是为什么呢?根据XML规范所描述:“在DTD内部子集中的参数实体调用,不能混掺到标记语言中”,这是什么意思呢?就是不能在实际的标记语言中来调用参数实体,像我们这样,就是在标记语言中进行调用:

但可以在同级别中被当作标记语言调用,就像是参数实体的引用,就是将调用当成了一个标记语言,像这样:


也就是我们所构造的payload这种使用方式,不能在内部DTD中被这样使用,但是幸运的是,XML规范还声明了一点:“外部参数实体不受此限制”,这就告诉我们可以使用外部的DTD来构造payload,将我们的CDATA内容拼接起来:

DTD文件的内容:

我们再次进行攻击尝试,成功读取到文件内容:
Ps:
由于环境资源的关系,我们在进行攻击时,所使用的外部dtd文件,是本地环境的。但是在实际的攻击情况下,这个DTD文件应该是我们自己所掌握的主机的DTD文件,文件的内容是受我们所控的。

无回显的情况又称为Blind XXE,可以使用外带数据通道提取数据即带外XML外部实体(00B-XXE)。
但是,在实际情况中,大多数情况下服务器上的 XML 并不是输出用的,所以就少了输出这一环节,这样的话,即使漏洞存在,我们的payload的也被解析了,但是由于没有输出,我们也不知道解析得到的内容是什么,因此我们想要现实中利用这个漏洞就必须找到一个不依靠其回显的方法——外带数据
相较于前面有回显的漏洞代码,我们去掉了内容输出的一部分。这样,用之前的payload就没有作用了:
Payload的构造:
有了前面使用外部DTD文件来拼接内部DTD的参数实体的经验,我们可以知道,通过外部DTD的方式可以将内部参数实体的内容与外部DTD声明的实体的内容拼接起来,那么我们就可以有这样的设想:
我们可以在本地做一个端口监听,然后利用payload来从目标主机读取到文件内容后,将文件内容作为url的一部分来请求我们本地监听的端口,这样,我们只需要查看请求的url就可以知道读取到的内容是什么。
首先,我们使用ncat监听一个端口:

然后,我们构造payload:
我们选择使用外部DTD,在我们自己所能掌控(或是自己搭建)的主机上编写一个dtd文件:

我们注意到,第一个参数实体的声明中使用到了php的base64编码,这样是为了尽量避免由于文件内容的特殊性,产生xml解析器错误。
Payload如下:

如图,我们先声明一个外部的DTD引用,然后再xml文档内容中引用外部DTD中的一般实体。
开始攻击:
然后查看我们的端口监听情况,会发现我们收到了一个连接请求,问号后面的内容就是我们读取到的文件内容经过编码后的字符串:

Ps:
有时候也会出现报错的情况(这是我们在漏洞的代码中没有屏蔽错误和警告),比如我们这里的payload没有选用php的base64编码,这里报错了,但是同时也将所读取的内容爆了出来,只是特殊字符经过了HTML实体编码。

漏洞发现

a.首先寻找接受XML作为输入内容的端点。
(可以通过修改HTTP的请求方法,修改Content-Type头部字段等等方法,然后看看应用程序的响应,然后看看程序是否解析了发送的内容,如果解析了,那么则可能有XXE攻击漏洞。)
还可以尝试注入xml预定义的一些实体,看其是否报错,通过报错信息判断
b…如果站点解析xml,就可以尝试引用实体和DTD c.如果可以。引用外部实体,则存在xxe漏洞

XXE其他攻击方式

1.通过XXE漏洞进行内网探测
当然进行内网探测我们还需要做一些准备工作,就是获取目标主机在内网中的IP地址,或是内网的网络划分信息,我们可以先利用 file 协议读取我们作为支点服务器的网络配置文件,看一下有没有内网,以及网段大概是什么样子(我以linux 为例),我们可以尝试读取 /etc/network/interfaces 或者 /proc/net/arp 或者 /etc/host 等跟内网配置有关的文件,我们可以通过这些文件的内容来获取更多有关内网的信息。如果实在没有办法获取目标主机的内网配置相关信息,那就花费时间爆破吧。
内网存活主机探测:
如下,其实payload就是简单的一个外部实体的注入payload:

只不过是将http://后面的部分替换为目标主机:
就像这样,如果目标主机对应的端口开启了http服务,或是其他服务,如ftp,也是可以通过http协议来访问,这样根据目标主机的响应内容或者状态码,就可以判断主机的存活与否,根据这个原理,我们在网上找到了相应的py脚本:
运行该脚本就能够找出相应网段是否存在开启http服务的主机。
2.内网主机端口探测:
同样的,根据内网存活主机的扫描方式,我们也可以针对某个主机进行端口的扫描:
构造payload:

扫描的大概原理是这样的:
比如你扫描一个关闭的端口,在等待了一段时间后,返回协议连接失败且超过了最长时间限制30秒:
而你扫描开放的端口,也可能是内容错误等其他的警告信息:
Ps:
有时候,端口扫描时判断端口的开放和关闭并不是虚拟机中这个样子,由于环境的不同,版本的不同,你可能会遇到的状况是:关闭的端口在超时之后,返回的是500状态码。
而开放的端口,返回的是200的状态码,以及一些xml警告信息,有时候还会附带上我们payload中期望输出的字符串。
所以,在进行内网探测时,探测结果判定的依据,还需要你自己来判断。你可以是根据返回状态码,也可以是根据返回的警告信息的内容,又或者你也可以尝试根据返回信息的时间长短。
3.通过XXE漏洞进行DOS攻击(不要轻易尝试!!!!!!!!)。
Payload如下:
上面的payload就是著名的“billionlaughs”攻击,该代码可以在目标主机的内存中生成十亿个“lol”字符串,从而导致 Dos攻击。它也被称为指数实体扩展攻击,是一种名副其实的XML炸弹。原理为:通过创建一项递归的 XML 定义,构造恶意的XML实体文件耗尽可用内存,如以上代码所示,在XMl中定义了一个实体lol9,它的值包含了十个实体lol8的值,而每个lol8又包含了十个lol7的值…最后产生10亿个“lol”字符串,占用内存约高达3GB。因为许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中,解析非常慢,这样,就会占用大量的内存资源,造成了拒绝服务器攻击。

本文参考某大佬博客以及合天安全公司实验所完成

XEE漏洞基础以及进阶相关推荐

  1. 二进制函数_Go二进制文件逆向分析从基础到进阶——MetaInfo、函数符号和源码文件路径列表...

    书接前文,本文主要介绍 Go 二进制文件中 Meta Information 的解析,与函数符号和源码文件路径列表的提取.最后详细介绍一下 Moduledata 这个结构.传送门:Go二进制文件逆向分 ...

  2. 【web安全原理分析】-XEE漏洞入门

    前言 XXE漏洞 XXE漏洞全称(XML External Entity Injection)即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意 ...

  3. [web安全原理分析]-XEE漏洞入门

    前言 1 前言 XXE漏洞 XXE漏洞全称(XML External Entity Injection)即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致 ...

  4. 计算机编程书籍-笨办法学Python 3:基础篇+进阶篇

    编辑推荐: 适读人群 :本书适合所有已经开始使用Python的技术人员,包括初级开发人员和已经升级到Python 3.6版本以上的经验丰富的Python程序员. "笨办法学"系列, ...

  5. 简明python教程 豆瓣-福利分享:个人整理的Python书单,从基础到进阶

    原标题:福利分享:个人整理的Python书单,从基础到进阶 我挑选的一些书籍,大家可以自行到书店或是网上自己选购.也由于个人水平有限,很可能大家觉得优秀的书籍没有列出,如果大家有觉得不错的书籍,欢迎大 ...

  6. python网络爬虫权威指南 豆瓣_福利分享:个人整理的Python书单,从基础到进阶...

    原标题:福利分享:个人整理的Python书单,从基础到进阶 我挑选的一些书籍,大家可以自行到书店或是网上自己选购.也由于个人水平有限,很可能大家觉得优秀的书籍没有列出,如果大家有觉得不错的书籍,欢迎大 ...

  7. Database之SQLSever:SQLSever基础知识进阶、软件安装注意事项、软件使用经验总结之详细攻略

    Database之SQLSever:SQLSever基础知识进阶.软件安装注意事项.软件使用经验总结之详细攻略 目录 SQLSever基础知识进阶 SQL与T-SQL.PL-SQL的区别 数据库相关基 ...

  8. 蓝牙基础知识进阶——Physical channel

    蓝牙基础知识进阶--Physical channel 二.物理通道 物理通道是piconet区分的标准,它是蓝牙系统结构层次中的最底层了. Q1:物理通道有哪些类型 物理通道通常可以分为四种类型: 1 ...

  9. 由浅入深学java iso_由浅入深学Java:基础、进阶与必做260题 PDF扫描版[47MB]

    由浅入深学Java:基础.进阶与必做260题讲解了Java方方面面的知识,全书共分为4篇共28章,第1篇从最基本的JDK安装讲起,包括基本语法与数据类型.数组.字符串.程序控制语句.面向对象编程.继承 ...

最新文章

  1. Nginx虚拟主机、Nginx模块的安装使用(加密模块--with-http_ssl_module)
  2. 【django】配置redis数据库【4】
  3. 实验1 词法分析程序设计
  4. DS博客作业06--图
  5. Linux内核网络协议栈4-创建socket(2)
  6. 试用到期_各大化妆品品牌试用装广告
  7. 从零开始学前端:字符串和数组的方法 --- 今天你学习了吗?(JS:Day10)
  8. linux shell cut -d ‘:‘ -f1,3
  9. UI设计师需要熟记的45个快捷键Windows、Mac
  10. java 动态读取配置文件_java读取配置文件的几种方法
  11. mysql数据库character_关于MySQL如何修改character
  12. 计算机不支持格式,显示视频格式不支持怎么处理,需要什么软件
  13. 注册华为云用户: 访问官网 https://huaweicloud.com/ 注册华为云用户(需手机号验证) 登录并完成实名认证 为账号充值不少于100元(不用时可提现
  14. 『辞旧迎新』一个只会写Bug的Coder年终总结
  15. C语言如何求出一堆整数的最大值
  16. 基于Maple的超静定连续梁内力求解器的实现
  17. Android广播接收者使用总结
  18. 前端学习笔记02--CSS快速了解
  19. python requests请求接口返回304问题解决
  20. 同济大学计算机考研招生人数2020,2020同济大学计算机考研大纲

热门文章

  1. 在Eclipse中使用“Ctrl+Alt+上下箭头”快速复制快捷键导致屏幕旋转
  2. I2C接口的OLED在树莓派3上的应用(luma.oled驱动)
  3. 串口返回调试c语言代码,用CC2530做串口实验,用调试助手输入自己的名字,电脑返回结果...
  4. 怎么将pdf转换成word转换器在线
  5. 实习期间策划部分页面视觉效果
  6. BlueStacks模拟器:多平台上运行Android应用
  7. Cordova + vue 打包安卓(Android) apk
  8. Samp免流软件以及地铁跑酷的自校验分析
  9. 服务器与客户端的时间同步
  10. 信创升级 | 秒云与人大金仓完成兼容性互认证