Je WordPress-site is gehackt: dit doe je in de eerste 24 uur
Je ontdekt het meestal niet zelf. Een klant belt dat er gokreclame op je homepage staat, je ziet in Google het label "Deze site kan zijn gehackt" onder je eigen bedrijfsnaam, of je hoster zet je account plat wegens spamverkeer. Wat je nu doet in de eerste uren bepaalt of je er een halve dag of twee weken mee bezig bent. Dit is de volgorde die werkt, en de valkuil zit vooral in de verleiding om meteen te gaan opruimen.
Stap één: zet de site uit de lucht, maar op de goede manier. Niet door de DNS te slopen en niet door de site simpelweg te verwijderen, maar door hem in onderhoudsmodus te zetten die een 503-statuscode teruggeeft. Een 503 vertelt Google dat je site tijdelijk niet beschikbaar is en dat de pagina bewaard moet blijven. Een 404 of een lege pagina vertelt Google dat je content weg is, en dat kost je posities die je daarna weer moet terugverdienen. Draait er een webshop op, overweeg dan alleen het besmette deel af te schermen in plaats van de hele winkel.
Stap twee: maak eerst een volledige kopie van de besmette site voordat je iets aanraakt. Bestanden én database. Dat voelt tegennatuurlijk, want je wilt de rotzooi juist weg. Maar zodra je begint met verwijderen ben je je bewijsmateriaal kwijt: je kunt dan niet meer nagaan hoe ze binnenkwamen, welke bestanden er zijn toegevoegd en wanneer het begon. En als je opruimactie de site sloopt, is die kopie je enige weg terug. Zet hem ergens neer waar hij niet uitvoerbaar is, dus niet in een submap van je webroot.
Stap drie: wachtwoorden. Allemaal, niet alleen die van WordPress. Elke beheerder in wp-admin, je hostingpaneel, FTP en SFTP, de databasegebruiker in wp-config.php, en elke API-sleutel die in je site of plugins staat. Gebruik nieuwe, unieke wachtwoorden en zet tweefactorauthenticatie aan waar dat kan. Als je hetzelfde wachtwoord ergens anders gebruikte, verander dat daar ook. Aanvallers verkopen inloggegevens door, dus reken erop dat wat gelekt is ook elders geprobeerd wordt.
Stap vier: vervang de salts in wp-config.php. Dat zijn de acht regels met AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY en de bijbehorende salts. WordPress biedt hiervoor een officiële salt-generator op api.wordpress.org: je haalt daar een verse set op en plakt de nieuwe regels over de oude heen. Het effect is simpel en cruciaal: alle bestaande sessies worden ongeldig. Ook die van de aanvaller. Zonder deze stap kan iemand die al ingelogd was gewoon blijven rondlopen nadat je alle wachtwoorden hebt gewijzigd.
Stap vijf: de keuze tussen back-up terugzetten of schoonmaken. Back-up terugzetten is sneller en betrouwbaarder, mits je twee dingen weet: dat die back-up van vóór de besmetting is, en dat je de content sindsdien kunt missen. Dat eerste is het lastige deel, want besmettingen worden vaak pas weken na de inbraak zichtbaar. Als je back-up van gisteren is en de aanvaller zit er al drie weken in, zet je gewoon de hack terug. Kijk daarom naar wijzigingsdatums van bestanden en naar je logbestanden om het startpunt te bepalen.
Schoonmaken is de route als je die datum niet kunt vaststellen, of als er sinds de inbraak bestellingen, inzendingen of artikelen zijn binnengekomen die je niet mag verliezen. Bij een webshop is dat bijna altijd het geval. De aanpak: vervang WordPress core volledig door een verse download van dezelfde versie, vervang alle plugins en het thema door verse kopieën uit de officiële bron, en behandel alleen wp-content/uploads en de database als materiaal dat je handmatig moet nalopen. Alles wat je kunt vervangen in plaats van repareren, moet je vervangen.
Waar zit die malware dan? De uploads-map als eerste. Daar horen alleen afbeeldingen, PDF's en documenten te staan, dus elk PHP-bestand in wp-content/uploads is per definitie verdacht. De tweede plek is wp-content/mu-plugins, de map voor must-use plugins. Die laden automatisch en je kunt ze niet deactiveren, maar ze zijn niet onzichtbaar: in wp-admin staan ze onder Plugins in een apart tabblad Must-Use. Kijk daar dus, en kijk daarna alsnog in de map zelf. WordPress laadt namelijk alleen PHP-bestanden die direct in mu-plugins staan en niet die in submappen, en precies daar maken aanvallers gebruik van: een onopvallend loader-bestand op het eerste niveau haalt de echte payload uit een submap die verder nergens opvalt. Een kort, onbekend bestand op het eerste niveau naast een submap die je niet herkent is dus reden om te kijken. De derde is de gebruikerstabel in de database, waar een extra beheerdersaccount met een onopvallende naam kan staan.
Verder kijk je naar .htaccess-bestanden met omleidingsregels die je zelf niet hebt gezet, naar geplande taken in de WordPress-cron die een script periodiek opnieuw installeren, naar injecties bovenaan index.php of wp-config.php, en naar je thema-bestanden functions.php en header.php. Let op code die begint met base64_decode, eval, gzinflate of lange strings hexadecimale tekens: dat is versleutelde payload en heeft in een normaal thema niets te zoeken. Draai je met wp-cli, dan geeft wp core verify-checksums je binnen een minuut een lijst met gewijzigde core-bestanden. Voor plugins bestaat wp plugin verify-checksums, maar dat vergelijkt uitsluitend tegen de checksums van de wordpress.org-repository. Premium plugins, plugins van een eigen server en nulled kopieën vallen er dus buiten, en voor thema's bestaat er helemaal geen checksum-commando. Juist bij premium en nulled plugins, verderop in dit artikel aangewezen als een van de meest voorkomende ingangen, helpt de checksum-controle je dus niet: daar vergelijk je handmatig met een verse kopie van de leverancier.
Een besmetting die je zelf niet ziet, is de vervelendste soort. Sommige malware toont de gewone site aan bezoekers en alleen spam aan zoekmachines, door te kijken naar de user-agent of de verwijzende zoekopdracht. Test daarom niet alleen in je browser: bekijk de site zoals Googlebot hem ziet via de URL-inspectie in Search Console, en zoek in Google op site:jouwdomein.nl om te zien of er pagina's in de index staan die jij nooit gemaakt hebt. Vind je daar Japanse tekens, medicijnnamen of casinotermen, dan zit de besmetting in je zoekresultaten en niet alleen in je site.
Dan Google. Staat er in Search Console een melding onder Beveiligingsproblemen, dan blijft die staan tot jij een beoordeling aanvraagt. Doe dat pas als de site aantoonbaar schoon is én het gat gedicht, want een afgewezen aanvraag kost je een nieuwe wachtperiode. Bij de aanvraag beschrijf je kort wat je hebt gevonden en opgelost. Ruim tegelijk de spampagina's op: verwijder ze, laat ze een 410 teruggeven en gebruik het verwijderingsverzoek in Search Console voor de meest zichtbare. Controleer daarna een paar weken lang of er geen nieuwe onbekende URL's opduiken.
Pas hierna dicht je het gat, en dit is de stap die het vaakst wordt overgeslagen. Een schoongemaakte site met hetzelfde lek is binnen dagen opnieuw besmet, en de tweede keer duurt het herstel langer omdat de aanvaller inmiddels een achterdeurtje heeft achtergelaten. Update alles naar de actuele versie, verwijder elke plugin en elk thema dat je niet gebruikt in plaats van het te deactiveren, en gooi nulled of via een dubieuze site gedownloade premium plugins er zonder discussie uit. Die zijn een van de meest voorkomende ingangen.
Zet daarna een paar dingen vast die het herhalen moeilijker maken. Blokkeer uitvoering van PHP in de uploads-map op serverniveau. Beperk of hernoem de inlogpagina en zet een limiet op mislukte inlogpogingen. Zet tweefactorauthenticatie aan voor elke beheerder. Geef redacteuren geen beheerdersrol omdat het makkelijk is. Zorg dat je PHP-versie nog ondersteund wordt. En controleer of je back-ups nu wél buiten de server staan, want als je die deze week nodig had gehad, wist je het antwoord al.
Heb je klantgegevens op je site staan, dan is er nog een spoor dat losstaat van de techniek. Bij een mogelijk datalek geldt de meldplicht uit de AVG en moet je dat in beginsel binnen 72 uur na ontdekking melden bij de Autoriteit Persoonsgegevens, die op de eigen site beschrijft wanneer een melding nodig is. Of dat aan de orde is hangt af van wat er is buitgemaakt, en juist dat is achteraf vaak niet met zekerheid vast te stellen. Leg daarom vanaf minuut één vast wat je ziet, wanneer je het zag en wat je hebt gedaan. Die tijdlijn heb je nodig, ook richting je eigen klanten.
Wanneer schakel je hulp in? Als je geen bruikbare back-up hebt. Als de besmetting terugkomt nadat je hem hebt verwijderd, want dan zit er nog een achterdeur. Als je hoster je account heeft geblokkeerd. Als er een webshop of klantdata bij betrokken is. En simpelweg als je na twee uur zoeken niet weet waar je naar kijkt. Herstel is geen kwestie van een plugin installeren, en hoe langer een besmetting loopt hoe dieper hij in je zoekresultaten zit. Wij doen dit soort werk onder WordPress-hulp: opsporen, schoonmaken, gat dichten en de Google-melding afhandelen.
En daarna: zorg dat het niet nog eens gebeurt. Vrijwel elke hack die wij zien komt binnen via een plugin die maanden achterliep of een beheerderswachtwoord dat elders gelekt was. Beide zijn te ondervangen met saai, structureel werk: geteste updates, back-ups buiten de server en iemand die af en toe kijkt. Dat is precies wat een onderhoudscontract hoort te zijn. Staat je site bovendien op een overvolle shared server zonder isolatie tussen accounts, kijk dan ook naar managed hosting waar een besmetting bij de buurman niet jouw probleem wordt.
Veelgestelde vragen over een gehackte WordPress-site
Mijn WordPress-site is gehackt, wat doe ik als eerste?
Zet de site in onderhoudsmodus met een 503-statuscode, wijzig daarna alle wachtwoorden voor WordPress, hosting, FTP en database, en maak een volledige kopie van de besmette site voordat je iets opruimt. Die kopie is je bewijsmateriaal en je weg terug.
Back-up terugzetten of schoonmaken?
Back-up terugzetten als je zeker weet dat die van vóór de besmetting is en je de content sinds die datum kunt missen. Schoonmaken als je het startmoment niet kent of als er bestellingen en inzendingen bij zijn gekomen. In beide gevallen moet je daarna alsnog het lek dichten.
Waar verstopt malware zich in WordPress?
PHP-bestanden in de uploads-map, de map wp-content/mu-plugins waar must-use plugins automatisch laden (zichtbaar in wp-admin onder Plugins, tabblad Must-Use, maar alleen bestanden op het eerste niveau laden mee), extra beheerders in de gebruikerstabel, geplande cron-taken, omleidingsregels in .htaccess en injecties in wp-config.php, index.php of functions.php.
Hoe haal ik de hackwaarschuwing van Google weg?
Via het rapport Beveiligingsproblemen in Google Search Console vraag je een beoordeling aan, met een korte beschrijving van wat je hebt opgelost. Doe dat pas als de site echt schoon is en het lek gedicht, want een afwijzing kost je extra wachttijd.
Welke wachtwoorden moet ik veranderen?
Alle WordPress-beheerders, je hostingaccount, FTP en SFTP, de databasegebruiker en elke API-sleutel in je site. Vervang daarnaast de salts in wp-config.php, zodat alle bestaande sessies ongeldig worden, ook die van de aanvaller.
Moet ik een datalek melden?
Als er persoonsgegevens betrokken kunnen zijn, zoals klantaccounts of formulierinzendingen, geldt de meldplicht datalekken uit de AVG en meld je dat in beginsel binnen 72 uur na ontdekking. Laat het beoordelen als je twijfelt.
Hoe lang duurt herstel van een gehackte site?
Met een recente, aantoonbaar schone back-up vaak een paar uur. Zonder bruikbare back-up, met verouderde plugins en een besmetting die al weken loopt, praat je over een tot enkele dagen inclusief controle en de herbeoordeling door Google.
Kan mijn site opnieuw gehackt worden na het opruimen?
Ja, en dat gebeurt vaak. Als je alleen de zichtbare rommel weghaalt maar het lek of een achtergelaten achterdeur laat zitten, is de site binnen dagen opnieuw besmet. Opruimen zonder het gat te dichten is halve arbeid.
Wil je hier meer over weten?
Neem contact op voor een vrijblijvend gesprek of bekijk onze diensten.