0x0前言

首先说明此类攻击在主流浏览器已近乎失效,此篇文章作为感想记录。

0x1背景

最近在看白盒扫描工具的知识库时,发现一个之前没见过的缺陷(Javascript劫持),出于好奇心想深入了解一下这个缺陷,但写此缺陷的资料比较少,特此写下此篇文章。

0x2原理

Javascript劫持与CSRF攻击原理非常相似,唯一不同的是,CSRF是模拟你的身份去发送请求,JavaScript Hijacking是模拟你的身份,窃取你在服务器上的私隐信息。

  1. Javascript劫持通过重写Object的__defineSetter__方法来实现钩子。
  2. 服务器返回的数据是数组类型。
  3. 浏览器会将数组类型当作JS代码运行,创建了一个数组对象并设置属性。
  4. 重写的方法会先执行,方法中可获得设置的属性,使攻击者能够将JSON数据外发。

0x3攻击步骤

我们先看下攻击代码

<script type="text/javascript">
    Object.prototype.__defineSetter__('profile', function(obj) {
        alert(obj);
    });
</script>
<script type="text/javascript" src="http://127.0.0.1:9000/stored/json"></script>

在用户访问恶意网站时:

<script type="text/javascript" src="http://127.0.0.1:9000/stored/json"</script>
  1. 这段JS代码会要求浏览器发送一个GET请求到http://127.0.0.1:9000/stored/json,于是浏览器按照指示,带上本地的Cookie信息,发送一个http的GET请求。
  2. 服务器接受到请求后,确认身份后,响应请求返回了一个JSON数组/JavaScript代码段。
  3. 浏览器接受到这段JS脚本后,如果返回的是一个JSON数组,比如:[{“Id”:1,“Name”:zac,“profile”:10000}]JSON数组被认为是一段可执行的JavaScript脚本,于是浏览器会解析执行。
  4. 解析执行时,由于创建了个数组对象,并设置了属性,之前重写的Object.prototype.defineSetter()会被执行。

攻击想要成功的一个大前提是,目标服务器返回的json数据是一个数组。

  1. 与CSRF相同,攻击者需要创建一个恶意网页,并诱导受害者点击。
  2. 并攻击者在恶意网页中重写了Object的__defineSetter__方法。重写此方法后导致所有对象设置属性时会先运行这个方法。
  3. 并且在恶意网页中通过<script>标签请求目标服务器的json数据,当返回的json数据是数组类型时,浏览器会将其当作JS代码运行,创建了一个数组对象并设置属性。
  4. 此前重写的方法会先执行,方法中可获得设置的属性,使攻击者能够将属性外发。

0x5 后记

目前的主流浏览器创建数组对象时都默认不运行__defineSetter__设置好的函数,所以此类攻击已经近乎失效。

chrome

java js引擎防注入 js注入和劫持_开发语言


参考资料:

深入理解JavaScript Hijacking原理