XML注入

XML注入简介


什么是xml?

XML 指可扩展标记语言(EXtensible Markup Language)

XML 是一种标记语言,很类似 HTML

XML 的设计宗旨是传输数据,而非显示数据

XML 标签没有被预定义。您需要自行定义标签。

XML 被设计为具有自我描述性。

XML 是 W3C 的推荐标准

例如:在tomcat中配置文件的存储格式便是XML文件,server.xml、web.xml

 xml特点

XML仅仅是纯文本,他不会做任何事情。

XML可以自己发明标签(允许定义自己的标签和文档结构)

XML 无所不在。XML 是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行。

总结成一句话就是:XML是用来存储数据的

xml的定义

推荐学习文章如下:

https://www.w3school.com.cn/xml/xml_syntax.asp

https://jingyan.baidu.com/article/77b8dc7fb26f366174eab639.html

https://www.cnblogs.com/weiyinfu/p/5374824.html

最终得出一个结构

首先进行XML声明,然后是DTD部分  ==>>   <!DOCTYPE 变量名 <元素>>

也就是XML名单定义,最后XML文档元素,如下代码

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

什么是XML注入?

XML注入又叫XXE攻击

XXE = XML External Entity 即外部实体,从安全角度理解成XML External Entity attack 外部实体注入攻击

有了XML实体,关键字’SYSTEM’会令XML解析器从URI中读取内容,并允许它在XML文档中被替换

因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现

 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)

XXE扩展

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

外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示:

知识扩展


php伪协议

php伪协议实际上就是支持与封装的协议(共十二种)

a.  file:// — 访问本地文件系统

b.  http:// — 访问 HTTP(s) 网址

c.  ftp:// — 访问 FTP(s) URLs

d.  php:// — 访问各个输入/输出流(I/O streams)

e.  zlib:// — 压缩流

f.  data:// — 数据(RFC 2397)

g.  glob:// — 查找匹配的文件路径模式

h.  phar:// — PHP 归档

i.  ssh2:// — Secure Shell 2

j.  rar:// — RAR

k. ogg:// — 音频流

l.  expect:// — 处理交互式的流

file://协议

file://协议在双off的情况下也是可以正常使用的

allow_url_fopen :off/on

allow_url_include:off/on


file://用于访问本地文件系统,在CTF中常用来读取本地文件

使用方法:file://文件的绝对路径和文件名

php://协议

php://协议的使用条件:

1.  不需要开启allow_url_fopen

2.  php://input、 php://stdin、 php://memory 和 php://temp 需要开启allow_url_include。


php://filter 用于读取源码且在双off的情况下也可以正常使用

allow_url_fopen :off/on   (使用条件)

allow_url_include:off/on

Eg: http://127.0.0.1/cmd.php?file=php://filter/read=convert.base64-encode/resource=index.php


php://input 可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。

allow_url_fopen :off/on

allow_url_include:on

Eg:http://127.0.0.1/cmd.php?file=php://input

        [POST DATA] <?php phpinfo()?>

参考文章https://www.cnblogs.com/So7cool/p/9795712.html

漏洞原理


XXE漏洞形成大体有4种方式:

  1. simplexml_load_string()函数造成的回显注入
  2. SimpleXMLElement()对象造成的回显注入
  3. DOMDocument()类造成的回显注入
  4. BlindXXE形式==>>也是由simplexml_load_string()函数造成的无回显注入

simplexml_load_string()函数

转换形式良好的XML字符串为SimpleXMLElement对象,然后输出对象的键和元素,下面的菜鸟教程测试代码

个人测试代码如下

SimpleXMLElement()对象

此函数用来实例化一个SimpleXML,如下代码

$index = new SimpleXMLElement('<doc></doc>');

实际代码测试如下

DOMDocument()类

参考文章:

https://blog.csdn.net/ssll2826/article/details/84080038

https://bbs.csdn.net/topics/360051568?list=19321717

实例测试如下图

特别注意:最初的php版本显示不了dom信息,需要php5.3以上才支持(必须加粗加红,看了半天)

参考链接:https://bbs.csdn.net/topics/392170938

漏洞实现


回显类

simplexml_load_string()函数,提交的post数据为,较好形式的XML字符串,如下图

SimpleXMLElement()对象和DOMDocument()类,测试与上图一致

无回显类

我们先读取我们想要的文件,然后为了传输方便,我们先来个base64编码,我们可以使用php伪协议读取文件(仅PHP支持)

在无回显的时候我们就需要引用外部实体了

下面是个人搭建的靶场

$postStr是个可控变量,$GLOBALS超全局变量,”HTTP_RAW_POST_DATA”是我们传的参数

simplexml_load_string()函数转换形式良好的XML字符串为SimpleXMLElement对象,如下图所示

构造代码

需要我们提交的xml形式的字符串,由于页面无法给我们回显,得尝试其他发放,首先我们需要上传的参数,首先声明文件,在DTD部分,定义file实体存储通过php伪协议读取的flag.php文件,然后引用外部实体,如下图所示

构造其中的1.xml文件,定义send实体,通过get方式向2.php传参,参数值为file实体,注意标红部分不得用%,必须转码,为了避免和上面的%号冲突,实际测试不转也不行,如下图所示

构造2.php文件,向3.txt文件写入file实体的内容,如下图所示

说一下大体流程

第一个图:我们提交的poyload,是通过php伪协议读取flag文件内容,报错到变量file中%remote调用DTD中的第二个元素,去访问一个远程的xml文件

第二个图:元素吧我们之前读到额flag文件作为传参值,去访问本地一个php文件

第三个图:php文件的作用是把接受到的get传参得到的内容保存到一个txt文件中

通过这个方式我们可以成功读取,告别了无回显不知道读取内容的尴尬,手动抱拳

抓包测试

打开burp,抓取数据包,修改为POST,并打上传参值,如下图所示

得到3.txt,如下图所示

漏洞防御


漏洞条件

1、当程序允许引用XML外部实体时

2、用户能自由控制输入

防御方案

目前对于XXE漏洞防御最主要的还是禁用加载外部实体的功能;以PHP为例,你只需在代码中配置

libxml_disable_entity_loader(true);

 如果不禁用加载外部实体,只过滤用户的输入

  • 白名单过滤-可行
  • 黑名单过滤-不建议
  • 字符转义-可行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值