天天看點

【經典幹貨】Web 前端黑魔法

【經典幹貨】Web 前端黑魔法

收集整理過去發表的 #前端黑魔法# 話題。

在此懷念和 @zswang 交流探讨前端黑魔法的時光

原文連結:

https://github.com/EtherDream/web-frontend-magic

2019

整理中...

下面大多從 weibo 搬運過來,賬号 @EtherDream 去年被禁言,以後在此更新。表情符已替換成 ~(大部分可腦補成狗頭)

2018-12-19

有人說,能用 const 的時候盡量用 const。是以,循環因子也可以。。。

for (const i of range(0, 5)) {
  console.log(i)  // 0, 1, 2, 3, 4
}

function* range(beg, end, step = 1) {
  for (let i = beg; i < end; i += step)
    yield i
}           

有沒有 Python 的感覺~

2018-11-19

思考題:如何擷取閉包内 key 變量的值:

// 挑戰目标:擷取 key 的值
(function() {
  // 一個内部變量,外部無法擷取
  var key = Math.random()

  console.log('[test] key:', key)

  // 一個内部函數
  function internal(x) {
    return x
  }

  // 對外暴露的函數
  apiX = function(x) {
    try {
      return internal(x)
    } catch (err) {
      return key
    }
  }
})()

// 你的代碼寫在此處:
// ...           

答案:

https://github.com/EtherDream/web-frontend-magic/issues/1

思考題:檢測隐形人是否存在

// 挑戰目标:檢測 Math 是否被代理
if (Math.random() < 0.5) {
  console.log('hooked')

  self.Math = new Proxy(Math, {
    get(obj, prop) {
      return obj[prop]
    }
  })
}

// 你的代碼寫在此處:
// 如果控制台有顯示 hooked,那麼你輸出 true,反之 false
// ...           

Demo:

https://jsfiddle.net/k0nupd58/
答案有多個,但有一種特别巧妙,可以參考「如何擷取閉包内 key 變量的值」的思路。

2018-10-26

點一下,CPU 開始咆哮

https://www.etherdream.com/FunnyScript/cpu-hog/
該頁面建立 1000 個 Service Worker 消耗大量 CPU。即使關閉頁面,它們仍在背景運作。想嘗試的話務必在隐身模式中打開,感覺卡了就可以關閉了。

2018-10-18

一種統計 key 的個數,無需使用判斷的寫法:

const map = {}
const str = 'hello world'

str.split('').forEach(key => {
  map[key] = -~map[key]
})

console.log(map)
// {" ": 1, d: 1, e: 1, h: 1, l: 3, o: 2, r: 1, w: 1}```
Demo: [https://jsbin.com/lumexovida/edit?js,console,output](https://jsbin.com/lumexovida/edit?js,console,output)

> ~i = -(i + 1),~undefined = -1  


**2018-10-17**  
自從 Chrome 69 支援 OffscreenCanvas API 後,終于能在 Service Worker 裡調用 GPU 資源了~ 是以使用者關閉網頁後,XSS 還可以繼續使用 100% CPU 和 GPU 資源幾分鐘時間~

拿之前的 SHA256 PoW 改了下貌似可行~

Demo: [https://www.etherdream.com/FunnyScript/glminer/sw-miner/](https://www.etherdream.com/FunnyScript/glminer/sw-miner/)

![image.png](https://ucc.alicdn.com/pic/developer-ecology/574ade3a3c7e46f780019d0566e30e42.png)


![image.png](https://ucc.alicdn.com/pic/developer-ecology/a9d7a9e9ded04d9c86f1d97156734ab0.png) 

![image.png](https://ucc.alicdn.com/pic/developer-ecology/fce92786f484432bab8a059cc668cf78.png)

當然,用 GPU 挖礦意義不大,網頁還是适合挖 CPU 算法的币。

不過 GPU 這種通用的硬體,顯然更适合破解密碼,比如 WiFi 密碼。Shader 好好優化下,破解速度可以達到 hashcat 一半左右。論壇 XSS 每個使用者貢獻幾分鐘,還是不錯的~ WiFi 破解後,還可以劫持流量植入 JS,于是又可以增加一些算力~

關于 Service Worker 各種玩法,可參考 [https://github.com/etherdream/sw-sec](https://github.com/etherdream/sw-sec)

**2018-9-28**  
思考題:如何實作一個網頁版的 CPU 跑分程式,并且帶有使用者排行榜功能。(重點是確定使用者不易作弊,比如自定義送出成績;以及不能使用多核 CPU 甚至 GPU 來加速,隻拼單核性能)

> 哪些密碼學算法是無法利用多線程加速的,并且能在網頁裡高效率運作?  


**2018-9-13**  
《大航海時代 2》風格的 Google Map

Demo: [https://jsfiddle.net/84j1cvt9/29/](https://jsfiddle.net/84j1cvt9/29/)

![image.png](https://ucc.alicdn.com/pic/developer-ecology/e3dc882210e647f2aee1911d33f8d3cf.png)


![image.png](https://ucc.alicdn.com/pic/developer-ecology/7bbec6f9c2634d90ba7588536eba2dfe.png)


**2018-9-12**  
Win1.0 的 calc.exe(非原創)

![image.png](https://ucc.alicdn.com/pic/developer-ecology/f23ff73ddfb343ba96df796ea4024d51.png)


Demo: [https://classicreload.com/Windows-1-01.html](https://classicreload.com/Windows-1-01.html)

> Win1.0 隻比 Win10 差一點而已~  


**2018-9-11**  
直到現在,仍有相當多的使用者甚至開發者都不知道【允許三方 Cookie】存在多大的危險~

一句話概況【允許三方 Cookie】的危險:在不安全的網絡環境下,通路任何一個 HTTP 頁面,各大網站 Cookie 可能瞬間被中間人拿到。

![image.png](https://ucc.alicdn.com/pic/developer-ecology/3d43b329b1a14ca6a557b3c811015f1e.png)


> 原理說過很多次了,不再解釋  


**2018-9-7**    
出個思考題:嘗試讀取 obj 中那個帶随機數的隐藏屬性
           

var obj = {}

Object.defineProperty(obj, '$' + Math.random(), {

get: () => alert('You win!'),

enumerable: false,

})

// write code here:

`

https://jsfiddle.net/2c358wxp/
有多個答案

2018-8-17

有什麼場合,必須使用 ES6 的 Reflect?

https://github.com/EtherDream/web-frontend-magic/issues/2

2018-8-1

思考題:用最少的字元實作下圖效果。

(滑鼠懸浮在超連結上,狀态欄顯示的是網站 A,但點選進入的卻是網站 B)

【經典幹貨】Web 前端黑魔法
【經典幹貨】Web 前端黑魔法

當然這個是上古時代的黑魔法了,稍懂前端的都知道怎麼實作。是以這裡隻問最短的實作~

目前想到的是 55 字元(包括目标域名):

https://www.etherdream.com/FunnyScript/statusbar_spoof_2.html

講解:超連結和 location 很像,都有 href、host 等 URL 屬性。不少人以為隻有 href 屬性可指派,事實上其他屬性也可以。

比如想把目前頁面從 http 跳轉到 https,隻需修改 protocol 即可:

location.protocol = 'https:'           

另外 HTML 内聯事件預設套有 with(this),是以可省略 this. 這幾個字元。

2018-7-27

一種檢測 HTTPS 中間人降級攻擊的猥瑣思路~

<script>
 if ('https://a.com'.startsWith('http:')) {
   // send_log('SSLStrip detected')
 }
</script>           

在公司的腳本上嘗試後發現竟然有不少日志,看來這類攻擊目前還是存在的。。。

HTTPS 中間人降級攻擊,本質上就是把流量中的 https:// 替換成 http:// 。是以又稱 -1s 攻擊~

2018-7-26

由于大部分使用者都不會開啟浏覽器 Do Not Track,是以少數開了的使用者反而成了另類,被用于浏覽器指紋特征了。。。

2018-7-20

思考題:在 JS 中用 0 0 0 0 四個常量計算 24。隻能用符号,表達式越短越好~

目前已知最短的答案 14 字元。

https://jsfiddle.net/qLo2jg7x/

2018-6-6

BitInt 出現後,不用死循環也能實作 CPU 100% 的效果了。一個 2 層幂塔就能卡死浏覽器~

9n ** 9n ** 9n > 0           

為什麼這裡要加 > 0 的判斷,因為

9 ^ 9 ^ 9 ≈ 4.28 x 10^369693099           

這個數字,光是位數就有 369,693,099 之多,相當于控制台要輸出一個 300 多兆的字元串!是以為了不在輸出時卡死,于是加了個判斷。

(事實上基本等不到字元串輸出那步)

2018-5-22

nodejs 惡作劇:給系統建立一個叫 node_modules 的使用者,然後 npm install 就無法使用了~~~

【經典幹貨】Web 前端黑魔法
【經典幹貨】Web 前端黑魔法
如果真遇到項目檔案夾之外有 node_modules 的話,隻要在 npm install 時加上參數 --prefix path 就可以強制指定 node_modules 的路徑。

2018-5-21

之前遇到個網站 WAF 的 JS 腳本,代碼經過多次動态混淆。

為了防止被人調試,前端不斷執行 debugger 指令,然後檢測執行用時 —— 如果控制台開着,debugger 指令會觸發斷點,用時顯然高出平常。于是 JS 會給後端發送日志,然後 IP 就被網站 ban 了。

setInterval(function() {
  var t1 = Date.now();
  debugger;
  var t2 = Date.now();
  if (t2 - t1 > 100) {
    console.log('debug detected');
    // send_log('ban this ip');
  }
}, 500);           

簡單示範:

https://codepen.io/anon/pen/rvPYxR?editors=0010

當然,在經過幾次 IP 更換後,很快就摸索出了一個超級簡單的規避方案。猜猜是如何實作~

其實非常簡單,禁用調試器斷點功能就可以,比如 Chrome DevTool 的箭頭圖示。

【經典幹貨】Web 前端黑魔法

不過想要一次成功,還是需要些小技巧的,畢竟剛打開 DevTool 的時候還是會觸發 debugger 斷下來的:

【經典幹貨】Web 前端黑魔法

是以正确的打開方式,應該先随便開一個網頁,打開 DevTool 禁用斷點:

【經典幹貨】Web 前端黑魔法

然後再打開想要通路的網頁,這時 debugger 就不會觸發了:

【經典幹貨】Web 前端黑魔法

大寫的 αß 服不服~

'αß'.toUpperCase()    // "ΑSS"           
類似的還有 'ffi'.toUpperCase() === 'FFI'。然而 '嬲'.toUpperCase() !== '男女男' ~

2018-5-21

随着 JS 引擎優化能力的提升,越來越多的性能黑魔法将會消失~

【經典幹貨】Web 前端黑魔法
【經典幹貨】Web 前端黑魔法

2018-5-15

思考題:定義 x 使得滿足條件判斷,字數越少越好。目前我的答案是 28 個字元,看看有沒有更短的~

const x = _______
const win = ('a' in x) && !('a' in x)
console.log(win)    // true           
https://jsfiddle.net/r6gk1ob8/

2018-5-14

思考題:有些 JS 代碼混淆後,會變成 eval(一大坨代碼) 的形式。當然解密也非常容易,把 eval 換成 console.log 就能原形畢露。

下面請思考,如何在「一大坨代碼」中加入陷阱,跟蹤有哪些人把 eval 換成了其他的函數?

https://codepen.io/anon/pen/odMbBX?editors=0010

(eval 換成 console.log 即可觸發陷阱)

如何使用 JS 緩解網站 DDOS 的攻擊?

https://yq.aliyun.com/articles/236585

大緻原理:網頁多用強緩存(目前是 Service Worker),發生故障時可毫秒級切換流量到 N 個後備節點。網站被打垮也隻影響新使用者,老使用者照樣可以流暢通路~

當然這其中細節問題很多,以後會在

https://github.com/EtherDream/js-anti-ddos

中讨論。

2018-5-8

相冊裡翻到個上古時代用

【經典幹貨】Web 前端黑魔法

示範:

https://www.etherdream.com/creative/BaiduCube.html
DXImageTransform.Microsoft.Matrix。當年硬着頭皮用國中數學知識琢磨 Martix 的計算規律,陸續花了幾個月才寫出來~

2018-5-6

思考題:JS 如何自我檢測代碼是否被人修改?

舉個栗子,有個腳本混淆後去除了換行、縮進等格式,并且變量名故意弄得特别長,幹擾分析。這時破解者通常會格式化代碼,然後變量名短化,儲存後再運作分析。是以,腳本如何自我檢測是否被篡改?

分享之前寫的一個 PPT

《前端加密與混淆》

,其中提到 JS 如何檢測自身子產品是否被篡改。以及檢測到異常情況後,該如何優雅的讓程式逐漸錯誤,而不是立即崩潰~

2018-5-4

分享曾經折騰的一種 JS 混淆思路:

(function(id, name, age, lang) {
  var PTR = arguments

  console.log(id, name, age, lang)  // 1001 "alice" 20 "en"

  PTR[0] = 1002
  PTR[1] = 'bob'
  PTR[2] = 30
  PTR[3] = 'us'

  console.log(id, name, age, lang)  // 1002 "bob" 30 "us"

})(1001, 'alice', 20, 'en')           

把函數中所有的局部變量都定義在形參裡,然後建立一個叫 PTR 的變量(模拟指針)指向 arguments。

之後通過 PTR[數字] 即可讀寫局部變量,而不用對具體變量指名點姓的通路,增加分析難度~

當然,後來 strict mode 普及之後就再沒考慮這方案了。

2018-5-3

現代浏覽器 referrer-policy 的出現,使得大量網站可當圖床使用~

是以 referrer 為空也是一種盜鍊

2018-4-25

思考題:現有一款浏覽器安全插件,會對 performance.now 接口進行 Hook,以降低 JS 擷取到的時間精度,減少邊信道攻擊的風險。

該插件會将如下代碼注入到頁面最先運作(包括架構頁、空白頁等):

(function() {
  const obj = performance
  const rawfn = Performance.prototype.now

  Performance.prototype.now = function() {
    let val = rawfn.apply(obj, arguments)
    return ((val * 10) | 0) / 10    // 精度降低到 0.1ms
  }
})()           

下面思考,有哪些方案可繞過該插件的防護,進而擷取到原生的高精度時間。

并且對于這種繞過方案,怎樣改進才能防範?

答案參考「有什麼場合,必須使用 ES6 的 Reflect」的思路。另外,new Event(0).timeStamp 也可以擷取高精度時間。

2018-4-23

記得很久前就有人提過,使用 localStorage 緩存 html、js 存在較大的安全隐患,萬一出現 XSS 可能會導緻惡意代碼長期感染,進而形成 Rootkit。

盡管現在用 localStorage 的已經不多,但類似的緩存方案仍存在。目前最主流的方案是 Cache Storage + Service Worker,不少 PWA 都采用這種緩存方式。然而不幸的是,Cache Storage 同樣存在上述安全隐患 —— 由于「Service Worker」和「頁面」是共享同個 Cache Storage 的,是以一旦頁面修改了 Storage 的資源,同樣會影響 Service Worker 擷取的内容。

我們随便找一個使用 Cache Storage + Service Worker 緩存的網站,幾乎都存在這個問題。在頁面裡修改 Cache Storage 中的某個 JS 内容,之後重新開機浏覽器,惡意代碼仍然生效。

【經典幹貨】Web 前端黑魔法
【經典幹貨】Web 前端黑魔法
【經典幹貨】Web 前端黑魔法
【經典幹貨】Web 前端黑魔法

2018-4-19

嘗試用指令 + 寄存器的思路,在 WebAssembly 中操作 JS 和 DOM~

【經典幹貨】Web 前端黑魔法
https://webassembly.studio/?f=mxnrb7oofth

2018-4-18

思考題:上傳檔案的過程中,如果使用者重新整理或關閉頁面,那麼就前功盡棄了。之後使用者還得重新打開檔案選擇框、重新上傳。

下面請思考,如何實作:

1.使用者隻需打開一次檔案選擇框,之後即使重新整理頁面,也無需再選擇檔案,繼續之前的上傳?

2.使用者即使關閉頁面(但未退出浏覽器),檔案仍能持續傳輸一段時間?

2018-4-17

思考題:如何産生這種效果~

(不能重寫 document.cookie,而是真有這麼多重複的鍵值)

【經典幹貨】Web 前端黑魔法
Demo

2018-4-8

整理檔案時發現過去寫的一個 JS 思考題:用最簡單的辦法讓 console.log(1) 輸出 0。被自己的答案驚呆。。。

【經典幹貨】Web 前端黑魔法
寫的不嚴謹,應該說是傳回 0,而不是輸出 0。

2018-3-22

分享一個網站去中心化的探索~

原理:把網站資源上傳到各大圖床、相冊上,前端通過 Service Worker 代理,然後從圖檔中還原出原始資料。于是自己的網站隻需放置一個極小的 HTML 和 JS 檔案,即可享受無限帶寬。

https://fanhtml5.github.io/

因為 Service Worker 具有持續性,是以隻要通路過一次,之後就算網站挂了,使用者仍能正常通路 —— 除非所有的備用節點都挂了。(裝上 Service Worker 就去中心了)

此外,這個方案還可用于 DDOS 防禦 —— 網站即使被打垮了,但之前通路過的使用者,仍能通路。

相比傳統 DNS 負載均衡至少有好幾秒的延時,Service Worker 通過 JS 實作節點切換,延時可以精确到 ms 級别;并且 DNS 協定是公開的,很容易周遊對應的 IP,而 JS 則可加上代碼混淆,增加分析的難度。。。

關于前端負載均衡,之前寫的一些思路:

https://yq.aliyun.com/articles/236582

打開浏覽器隐身模式,通路

https://fanhtml5.github.io/big-pic.png

出現的是個圖檔,但用 curl 通路并不是圖檔。這就是這個方案有趣的地方~

2018-3-17

打開浏覽器 console 會觸發浏覽器加載 js 尾部的 source map url,于是後端就可以收到日志。

并且動态建立的腳本也支援 source map url,是以 url query 裡還可以加上使用者相關的參數,跟蹤哪些人開了控制台~

2018-3-9

控制台 FBI WARNING 惡作劇~

【經典幹貨】Web 前端黑魔法
https://jsfiddle.net/tb54ywa3/

(暫隻支援 Chrome)

2018-3-9

分享跳轉 opener 的另類玩法~

大家知道 Service Worker 可以持續運作一段時間,可以用來挖礦、破解密碼等等。。。不過 XSS 沒法安裝 SW,因為 SW 的腳本必須和頁面同源;iframe 也沒法安裝,因為浏覽器規定隻有首頁面才可以安裝。

是以,唯一可行的就是把 opener (假如存在的話)跳轉到自己網站上,裝完 SW 再自動傳回~

關于 Service Worker 各種玩法,可參考 https://github.com/etherdream/sw-sec

2018-1-25

紅白機遊戲《超級瑪麗》彙編指令重編譯成 JavaScript:

【經典幹貨】Web 前端黑魔法

Demo:

https://www.etherdream.com/FunnyScript/smb-js/game.html

原理:

https://www.cnblogs.com/index-html/p/6492418.html

2017

2017.md

繼續閱讀