绕过web服务器的CORS限制
跨源资源共享(Cross-OriginResource Sharing, CORS)是在服务器端配置的一组策略,它告诉浏览器服务器是否允许在外部站点(跨源请求)上使用脚本代码生成的请求,以及来自哪个站点,或者它是否只接受在自己托管的页面中生成的请求(同源)。正确配置的CORS策略可以帮助防止跨站请求伪造攻击,尽管它还不够,但它可以阻止一些攻击。
在这个小节中,我们将配置一个不允许跨源请求的web服务,并创建一个能够发送伪造请求的页面。
环境准备
对于这个小节,我们将使用DVWA Web服务。可以从它的GitHub地址
https://github.com/snoopysecurity/dvws进行下载。
下载最新版本并复制到OWASP BWA虚拟机(或直接下载到它);我们将把代码放在/var/www/dvwebservices/中。
这段代码是一组脆弱的web服务,其目的是进行安全测试;我们将修改其中一个,使其不那么脆弱。打开
/var/www/dvwebservices/vulnerabilities/cors/server.php
可能会使用nano编辑器,默认情况下包括在VM中:
nano/var/www/dvwebservices/vulnerabilities/cors/server.php
查找所有设置了Access-Control-Allow-Origin头的实例,并对每一行进行注释,如下面的屏幕截图所示:
我们还需要添加几行代码来正确处理请求参数;最终代码如下:
被logo挡住的地方为$dictionary[$obj->searchterm]]));
实战演练
一旦在服务器中有了这些代码,我们就可以在
http://192.168.56.11/dvwebservices/vulnerabilities/cors/client.php
浏览web服务客户机并开始我们的练习。使用BurpSuite作为我们的代理来进行攻击:
1、首先,让我们通过浏览来查看正常的client.php。它显示服务器生成的一个密钥。
2、如果我们转到代理Burp suite,在本例中,我们可以看到客户机向服务器发出POST请求server.php。在这个请求中有一些需要注意的地方,如下面的截图所示:
内容类型头是application/json,这意味着主体是json格式的。
请求体不是标准的HTTP请求格式(param1=value¶m2=value),而是JSON对象,由header指定:
3、假设我们要对该请求进行CSRF攻击。如果希望HTML页面以JSON格式发出请求,则不能使用HTML表单;我们需要使用JavaScript。创建一个HTML文件,cos-json-request.html在这个例子中,用以下代码:
4、前面的代码复制client.php发出的请求。在浏览器中打开它并单击Submit request。什么也不会发生,下面的截图显示了原因:
根据前面的错误,请求被浏览器阻塞,因为服务器没有在其访问控制允许的源文件头中指定允许的源文件。这是因为我们正在请求一个资源(服务器)。从服务器外部的源文件,也是KaliVM中的一个本地文件。
5、解决此限制的最简单方法是创建一个HTML页面,该页面在HTML表单生成的POST请求中发送相同的参数,因为浏览器在提交表单时不会检查CORS策略。创建另一个HTML文件,CORS-form-request.html,内容如下:
浏览器在提交HTML表单时不检查CORS策略;但是,表单中只能使用GET和POST方法,这就排除了web服务中实现的其他常用方法,如PUT和DELETE。
6、加载CORS-form-request.html,在浏览器中的它应该是这样的:
7、单击Submit form ,请求并查看服务器如何使用包含密钥的JSON对象进行响应:
8、检查Burp suite中的请求,并验证内容类型标头是
application/x-www-form-urlenencoded
工作原理
我们对此小节的测试应用程序是一个web页面(client.php)。使用REST web服务(server.php),检索一个密钥。我们试图在本地系统中使用web页面来执行CSRF攻击,但失败了,因为服务器没有定义CORS策略,浏览器默认情况下拒绝跨源请求。
然后我们制作了一个HTML表单来发送与JavaScript请求中相同的参数,但使用HTML表单格式,它成功了。web服务以多种格式(如XML、JSON或HTML表单)接收信息并不少见,因为它们打算与许多不同的应用程序进行交互;然而,这种开放性可能会使web服务暴露于攻击之下,特别是在CSRF等漏洞没有得到适当处理的情况下。