安全街
一步步,我们的信息安全时代

平时见过不少鸡肋的漏洞,有的XSS和CSRF因为利用环境的局限性和针对性的防护,即使存在也无法被利用,因此会受到厂商的忽略。但当多个鸡肋的漏洞同时存在时,也许会碰撞出意想不到的火花。

使用CSRF盗取SELF-XSS的Cookie

一般来说,个人信息修改页面只有用户自己才能够看得到。
假设网站A右上角的你好,用户这个地方存在XSS,并且在修改昵称为XSS payload后能够触发这个XSS。但是这个网站没有能够让其他用户看到你昵称的类似于留言板讨论区的地方,而管理员也一百年不会去看一下你的昵称,这个XSS就成为了一个鸡肋的SELF-XSS。因为普通用户怎么可能把昵称改成XSS payload来把Cookie送给你,你又没办法把自己的昵称改成恶意代码然后让别人看到,所以只能用来X自己。
但如果同时这个网站有一个CSRF漏洞的话那就不一样了。我们可以通过以下操作来打任意用户的Cookie:

  • 在恶意网站B中写入CSRF payload,使用这个CSRF来修改用户在A网站的昵称为XSS payload
  • 诱惑用户访问恶意网站B,CSRF payload触发,用户在A网站的昵称被修改为XSS payload
  • 用户重新访问A网站时,由于右上角显示了昵称,所以会触发对应的XSS payload,乖乖的把Cookie给你送过来

这样,一个SELF-XSS便被利用了。恶意网站B可以是我们自己建立的,也可以是某些存在XSS漏洞的大型网站,通常大型网站更容易受信任。这些大型网站可能本身设置了HTTP-ONLY导致攻击者无法拿到Cookie,又不好做其他操作。但是用来做攻击其他网站的跳板却是无法防范的。

使用XSS窃取防御CSRF的Token

生成一个随机Token是防御CSRF的经典方法之一。在页面涉及到表单时,会在服务器端生成一个Token,在页面加载时创建一个值为Token的input,插入到表单中,并设置type=”hidden“隐藏。当提交表单时,会将这个Token值一起提交。服务器端验证这个Token是否正确,如果不正确就会扔掉此次请求。
本来只要获取目标页面Token的值,这种防御方法就会无效。但CSRF攻击是在其他网站发起的,由于同源策略,发起攻击的网站B不能读取被攻击的网站A的内容,只能够对其发送请求。因此攻击者是无法获取Token值的,CSRF攻击就此失效。
但当目标网站有一个XSS漏洞时,我们便可以先发送一次请求,通过JS的跨域方法绕过同源策略,从而读取网站A页面中的Token值。再发送第二次请求,带上Token值,完成CSRF攻击。
博主这里使用window.name来跨域窃取Token值。
假如发起攻击的网站为B,受害站点为A。

  • 首先在A网站的URL中构造XSS payload,实现以下功能:
    • 获取本页面的Token值
    • 将Token值赋值给window.name
  • 在B网站中插入实现以下功能的JS:
    • 创建一个iframe,并将iframe.src设为上面构造好的带有XSS payload的A网站的URL
    • 写一个function,首先将iframe.contentWindow.location设为任意一个与B网站同源的页面,然后使window.name = iframe.contentWindow.name

      修改iframe.contentWindow.location的原因是:当iframe中的页面为A网站的页面时,与B网站为不同源的,不能将iframewindow.name赋值给当前B网站窗口的window.name。但是我们把iframe中的页面换为与B网站同源的页面时,是可以进行window.name的赋值的。由于window.name的特性,其值本身与网站无关,是窗口的一个值。因此修改页面后window.name并未改变,我们就可以顺利取出了。

    • 将这个iframe销毁
  • 在B网站中插入真正的CSRF payload,带上已成功获取的window.name中的Token值,进行攻击。

结语

有些看似无法利用的场景,稍作结合就可能出现意想不到的结果。在第二个姿势中,我们还可以不窃取Token值,直接窃取document.cookie。但CSRF相当于批量操作,当进行高价值的操作时,可能会比收集很多cookie一个一个去操作更值得。况且这样的操作可以无视HTTP-ONLY的限制。因此这个场景还是有很大价值的。

*本文为原创,作者T1dDl3R,首发于本博客。转载请注明

这篇文章还没有人发言,快抢第一!

发表评论