点击劫持

点击劫持本质上是一种视觉欺骗手段。 攻击者使用一个透明不可见的 iframe 覆盖在一个网页上,然后诱使用户在不知情的情况下点击透明的 iframe 页面。

<html>
  <body>
    <button>这是一个很安全的按钮</button>
    <iframe
      src="https://attact-site-url"
      style="position:fixed;opacity:0;"
      scrolling="no"
    ></iframe>
  </body>
</html>

攻击类型

  1. flash 点击劫持

  2. 图片覆盖

  3. 拖拽劫持

  4. 触屏劫持

Flash 点击劫持

Flash 点击劫持就是在 flash 内容上隐藏了一个看不见的 iframe。

图片覆盖

顺着点击劫持本质上是一种视觉欺骗手段这个思路,产生了跨站图片覆盖(Cross Site Image Overlaying)攻击。

XSIO 不同于 XSS , 它利用的是图片的 style 或能够控制 CSS。 如果应用没有限制 style 的 position 为 absolute,图片就可以覆盖到页面上的任意位置,形成点击劫持。

<html>
  <body>
    <iframe src="https://attact-site-url"></iframe>
    <a href="https://钓鱼网站">
      <!-- 调整图片样式至被攻击站点的相同的位置 -->
      <img src="https://attact-site-domin/image-url" style="position:fixed;" />
    </a>
  </body>
</html>

拖拽劫持

在浏览器开始支持 Drag & Drop API 后。 浏览器的拖拽对象可以是一个链接,也可以是一段文字,还可以从一个窗口拖拽到另一个窗口。

拖拽劫持的思路是诱导用户从不见的 iframe 中“拖拽”出攻击者希望得到的数据,然后放到攻击者能够控制的另一个页面中,从而窃取数据。

触屏劫持

通过讲一个不可见的 iframe 覆盖到当前页面上,可以劫持用户的触屏操作。

在移动互联占据主要市场的这个时代,大多数手机浏览器为了节约空间,隐藏了地址栏,因此手机上的视觉欺骗变得更加容易实施。

防御手段

  1. frame busting

  2. x-frame-options

Frame Busting

通常可以写一段 JavaScript 代码禁止 iframe 嵌套:

<style>
  body {
    display: none;
  }
</style>
<script>
  // 最佳 Frame Busting:
  if (self == top) {
    document.getElementsByTagName('body')[0].style.display = 'block';
  } else {
    top.location = self.location;
  }
</script>

常见 iframe busting:

  • if (top != self)

  • if (top.location != self.location)

  • if (top.location != location)

  • if (parent.frames.length > 0)

  • if (window != top)

  • if (window.top !== window.self)

  • if (window.self != window.top)

  • if (parent && parent != window)

  • if (parent && parent.frames && parent.frames.length>0)

  • if ((self.parent&&!(self.parent===self))&&(self.parent.frames.length!=0))

破坏框架的条件语句:

  • top.location = self.location

  • top.location.href = document.location.href

  • top.location.href = self.location.href

  • top.location.replace(self.location)

  • top.location.href = window.location.href

  • top.location.replace(document.location)

  • top.location.href = window.location.href

  • top.location.href = "URL"

  • document.write(’’)

  • top.location = location

  • top.location.replace(document.location)

  • top.location.replace(’URL’)

  • top.location.href = document.location

  • top.location.replace(window.location.href)

  • top.location.href = location.href

  • self.parent.location = document.location

  • parent.location.href = self.document.location

  • top.location.href = self.location

  • top.location = window.location

  • top.location.replace(window.location.pathname)

  • window.top.location = window.self.location

  • setTimeout(function(){document.body.innerHTML=’’;},1);

  • window.self.onload = function(evt){document.body.innerHTML

Frame Busting 可以通过各种手段绕过。 比如 H5 中 iframe 的 sandbox 属性、IE 中 iframe 的 security 属性

x-frame-options

x-frame-options 就是为了解决点击劫持产生的 HTTP 响应头

X-Frame-Options 有三个可能的值:

X-Frame-Options: deny
X-Frame-Options: sameorigin
X-Frame-Options: allow-from https://example.com/

在不支持 x-frame-options 的浏览器中,只能继续使用 Frame Busting。

Content-Security-Policy

可以通过 Content-Security-Policy 的 frame-ancestors 指令 控制哪些页面能够 <frame>, <iframe>, <object>, <embed>, 或 <applet> 嵌入当前页面。

Content-Security-Policy: frame-ancestors <source>;

Reference

最后更新于