WordPress gehackt: hoe ik verborgen PHP-malware, cloaking en 14.024 serverfouten onderzocht

Een zakelijke WordPress-website die niet meer werkte, verdachte PHP-bestanden en zoekmachinecontent die niets met het bedrijf te maken had. Wat begon als een technische storing, groeide uit tot een uitgebreid beveiligingsonderzoek. In deze praktijkcase laat ik zien wat ik tegenkwam, welke hulpmiddelen ik gebruikte en wat de serverbestanden daadwerkelijk onthulden.

Het begon met een WordPress-website die niet meer werkte

In oktober 2026 kreeg ik te maken met een probleem bij de WordPress-website van een zakelijke klant, Holland Quality Standbouw.

De website werkte niet meer zoals het hoorde. Bezoekers kregen te maken met serverfouten en de WordPress-installatie functioneerde niet normaal.

Mijn eerste gedachte was dat het om een technische storing ging. Een defecte plugin, beschadigde WordPress-bestanden of een probleem met de PHP-configuratie kunnen immers allemaal een HTTP 500-fout veroorzaken.

Maar tijdens het onderzoek kwam ik steeds meer afwijkingen tegen.

Er waren aanwijzingen voor ongewenste zoekmachinecontent, verdachte bestanden in de installatie en wijzigingen in PHP-code die niet thuishoorden in een normale WordPress-website.

Ik besloot daarom niet alleen de foutmelding te onderzoeken, maar ook de bestanden, de database en de serverlogs.

Wat ik uiteindelijk aantrof, bleek veel omvangrijker dan een gewone WordPress-storing.

Een website kan gehackt zijn zonder dat bezoekers het merken

Een van de opvallendste onderdelen van dit incident was de mogelijke manipulatie van zoekmachineverkeer.

Tijdens de controles kwamen afwijkende resultaten naar voren, waaronder merkgerichte content en verwijzingen die niets met het bedrijf te maken hadden. Ook verschenen verwijzingen naar merken zoals Nike en LEGO.

Dergelijke verschijnselen kunnen passen bij SEO-spam.

Bij SEO-spam proberen aanvallers misbruik te maken van een bestaande website om ongewenste pagina's of links via zoekmachines zichtbaar te krijgen.

Een techniek die daarbij gebruikt wordt, heet cloaking.

Bij cloaking ontvangt een zoekmachine mogelijk andere inhoud dan een gewone bezoeker.

Dat kan er bijvoorbeeld zo uitzien:

  • Een bezoeker opent de normale bedrijfswebsite.
  • Een zoekmachine krijgt een pagina met ongewenste zoekwoorden.
  • Sommige URL's verwijzen naar externe commerciële websites.
  • De websitebeheerder ziet de spam niet wanneer die zelf de homepage opent.

Google beschrijft dit expliciet als een techniek die ook bij gehackte websites voorkomt.

Een bekende verschijningsvorm is de *Japanese keyword hack*, waarbij aanvallers Japanstalige spamcontent of pagina's toevoegen. In deze casus waren er aanwijzingen voor zoekmachinegerichte manipulatie, maar ik kon niet definitief vaststellen dat alle aangetroffen verschijnselen tot die specifieke variant behoorden.

De oorspronkelijke waarnemingen van afwijkende content zijn niet allemaal geschikt om openbaar te delen. Sommige bevatten klantinformatie, interne URL's of andere gegevens die ik niet op een publieke website wil plaatsen.

Daarom richt ik me hieronder op het technische bewijsmateriaal dat wel veilig getoond kan worden.

Ongeveer 14.000 bestanden onderzoeken: waar begin je?

Een WordPress-installatie bestaat uit veel meer dan de pagina's en berichten die u in het dashboard ziet.

Er zijn duizenden PHP-, JavaScript-, CSS- en configuratiebestanden. Daar komen de bestanden van plugins, thema's en uploads nog bij.

Bij deze website ging het om ongeveer 14.000 bestanden.

Die ga je natuurlijk niet allemaal één voor één openen.

Ik heb daarom verschillende hulpmiddelen gecombineerd:

FileZilla gebruikte ik om bestanden op te halen en de mappenstructuur te bekijken. Via DirectAdmin kon ik onderdelen van de hostingomgeving controleren. Met phpMyAdmin en SQL onderzocht ik de database.

Daarnaast gebruikte ik mijn Linux Mint-terminal en geautomatiseerde analysetools om grote aantallen bestanden gericht te onderzoeken.

Het doel was niet om iedere regel code handmatig te lezen, maar om afwijkingen te vinden.

Ik zocht onder andere naar onverwachte PHP-bestanden, sterk versluierde code, vreemde bestandsnamen en wijzigingen in bestanden die normaal gesproken een vaste WordPress-structuur hebben.

Daarmee kon ik de aandacht richten op een veel kleinere groep bestanden.

En juist daar kwamen de eerste concrete aanwijzingen vandaan.

1. Een opvallend .htaccess-bestand

Een van de bestanden die ik onderzocht, was .htaccess.

Dit configuratiebestand kan op Apache-webservers onder andere bepalen hoe URL's worden verwerkt en welke bestanden toegankelijk zijn.

In de aangeleverde configuratie ontdekte ik een opvallende combinatie van regels.

Eerst werden PHP-bestanden in het algemeen geblokkeerd.

Maar vervolgens werd toegang toegestaan tot een specifieke lijst bestanden.

Daartussen stonden onder andere:

  • `radio.php`
  • `wp-l0gin.php`
  • `wp-the1me.php`
  • `about.php`
  • `lock360.php`

Vooral bestandsnamen zoals wp-l0gin.php en wp-the1me.php trokken mijn aandacht.

Ze lijken op normale WordPress-bestandsnamen, maar gebruiken cijfers op plaatsen waar u letters zou verwachten.

Dat hoeft afzonderlijk nog geen bewijs van malware te zijn. Maar in combinatie met andere verdachte code is het een serieuze aanwijzing dat de toegang tot specifieke scripts bewust is ingericht.

Bewijsvisual 1: Fragment uit het aangetroffen .htaccess-bestand
Fragment uit het aangetroffen .htaccess-bestand. PHP-bestanden worden algemeen geblokkeerd, terwijl geselecteerde bestandsnamen expliciet toegankelijk blijven.

De afbeelding toont een ingekort fragment van het oorspronkelijke bestand. De betekenis zit vooral in het verschil tussen de algemene blokkade en de uitzonderingen.

2. Malware vermomd als WP Super Cache

Daarna onderzocht ik de code die was aangetroffen onder de naam radio.php.

Dit bestand bevatte een opvallende PHP-header:

Plugin Name: WP Super Cache

WP Super Cache is een bestaande WordPress-cacheplugin. Zo'n header kan op het eerste gezicht de indruk wekken dat de code afkomstig is van een normale plugin.

Maar de daadwerkelijke inhoud vertelde een ander verhaal.

In hetzelfde bestand stonden lange reeksen gecodeerde gegevens en constructies waarmee functienamen dynamisch werden samengesteld.

Het bestand bevatte bovendien een aanroep van eval().

Met deze PHP-functie kan code tijdens het uitvoeren van een script worden geïnterpreteerd en uitgevoerd.

Dat maakt eval() niet in iedere denkbare situatie kwaadaardig, maar in combinatie met verborgen functienamen en een grote versluierde payload is het bijzonder verdacht.

De pluginheader vormde dus geen betrouwbaar bewijs van de herkomst van het script.

Bewijsvisual 2: Het aangetroffen bestand presenteert zich als WP Super Cache, maar bevat versluierde PHP-code en een uitvoerconstructie met eval().
Het aangetroffen bestand presenteert zich als WP Super Cache, maar bevat versluierde PHP-code en een uitvoerconstructie met eval().

Dit was een van de duidelijkste voorbeelden van waarom bestandsnamen en beschrijvingen alleen niet voldoende zijn tijdens een beveiligingsonderzoek.

Wat een bestand zegt te zijn, hoeft niet overeen te komen met wat de code daadwerkelijk doet.

3. Zelfs de index.php was aangepast

Een van de meest opvallende ontdekkingen zat in index.php.

Dit is normaal gesproken een relatief klein bestand dat WordPress opstart.

Het onderzochte bestand zag er totaal anders uit.

Het bevatte een zeer groot blok sterk versluierde PHP-code, vóór de normale WordPress-opstartcode.

In totaal telde ik 4.089 voorkomens van goto in een bestand van 88.711 bytes.

goto is een bestaande PHP-instructie waarmee de uitvoering van code naar een ander punt kan springen.

Maar duizenden dergelijke instructies, gecombineerd met willekeurig ogende labels en versluierde variabelen, maken code nauwelijks leesbaar.

Dit is een bekende vorm van code-obfuscatie: code wordt bewust moeilijk te begrijpen gemaakt.

Dat bemoeilijkt een handmatige beoordeling en kan het herkennen van kwaadaardige functionaliteit vertragen.

Bewijsvisual 3: De oorspronkelijke index.php bevatte duizenden goto-instructies en een omvangrijk versluierd codeblok vóór de normale WordPress-loader.
De oorspronkelijke index.php bevatte duizenden goto-instructies en een omvangrijk versluierd codeblok vóór de normale WordPress-loader.

Bij verdere statische inspectie waren ook constructies zichtbaar die HTTP-verzoeken, externe gegevens en zoekmachinegerelateerde parameters verwerken.

Daarmee ontstond een concreet technisch verband met de eerder waargenomen afwijkende zoekmachinecontent.

Wat de volledige verborgen code onder alle omstandigheden uitvoerde, heb ik niet vastgesteld door de malware daadwerkelijk te starten. Voor het onderzoek was het juist belangrijk de verdachte scripts niet op een actieve website uit te voeren.

Wat heb ik daadwerkelijk kunnen vaststellen?

Niet iedere bevinding heeft dezelfde bewijskracht.

Daarom heb ik de belangrijkste resultaten gescheiden in wat rechtstreeks uit de bestanden blijkt en wat aanvullend onderzoek vereist.

Wat is rechtstreeks vastgesteld?
Onderdeel Aangetroffen Beoordeling
.htaccess Uitzonderingen voor verdachte PHP-bestanden Aantoonbaar
radio.php Pluginheader en versluierde uitvoercode Aantoonbaar
index.php 4.089 goto-instructies en afwijkende code Aantoonbaar
SEO-cloaking Afwijkende content en verdachte verzoekverwerking Sterke aanwijzingen
Eerste toegangsmethode Niet definitief gereconstrueerd Onbekend

Toelichting: de technische beoordeling is gebaseerd op de beschikbare bestanden, waarnemingen en servergegevens. Niet ieder onderdeel is volledig forensisch gereconstrueerd.

4. De serverlogs lieten duizenden fouten zien

Naast de verdachte PHP-bestanden wilde ik weten hoe de server zich in de betreffende periode had gedragen.

Daarvoor onderzocht ik de aangeleverde toegangs- en foutlogs van de hostingomgeving.

De resultaten waren opvallend.

In de beschikbare logs over 13 tot en met 18 oktober 2026 kwamen 14.024 HTTP 500-responses voor.

Een HTTP 500-fout betekent dat de server het verzoek niet correct heeft kunnen verwerken.

Tijdens het onderzoek kwam ook een concrete PHP-fout naar voren.

Het bestand wp-includes/compat-utf8.php ontbrak, terwijl WordPress probeerde het via wp-settings.php te laden.

Dat veroorzaakte een fatale PHP-fout.

Daarmee had ik een aantoonbare technische verklaring voor een deel van de uitval.

Maar het verklaarde niet waarom de andere verdachte scripts aanwezig waren.

Bewijsvisual 4: Analyse van de aangeleverde serverlogs
Analyse van de aangeleverde serverlogs. Tussen 13 en 18 oktober 2026 werden in totaal 14.024 HTTP 500-responses aangetroffen.

Hoe waren de serverfouten verdeeld?

HTTP 500-fouten per datum
Datum HTTP 500-fouten
13 oktober 2.413
14 oktober 2.813
15 oktober 3.134
16 oktober 2.962
17 oktober 2.653
18 oktober* 49
Totaal 14.024

18 oktober betreft een gedeeltelijk beschikbare logperiode. Dit zijn aantallen serverresponses, geen aantallen unieke bezoekers.

Deze aantallen laten zien dat het probleem niet alleen bestond uit een enkele mislukte pagina-aanvraag.

De server had gedurende meerdere dagen duizenden foutresponses geregistreerd.

Dat betekent niet automatisch dat alle 14.024 responses rechtstreeks door de malware zijn veroorzaakt. De ontbrekende WordPress-bestanden vormden immers een afzonderlijk vastgesteld probleem.

Juist dat onderscheid vond ik belangrijk.

5. Het zoekmachineverkeer viel eveneens op

Tijdens de loganalyse kwamen ook grote aantallen verzoeken met een Googlebot-identificatie naar voren.

In de onderzochte gegevens waren 130.652 verzoeken aanwezig waarbij de user-agent zich als Googlebot identificeerde.

Dat getal vraagt wel om een belangrijke kanttekening.

Een user-agent is een tekstwaarde die een aanvrager meestuurt. Die kan worden vervalst.

Een verzoek dat de naam Googlebot gebruikt, hoeft dus niet werkelijk afkomstig te zijn van Google.

Daarvoor is aanvullende verificatie nodig, bijvoorbeeld op basis van de officiële crawler-IP-reeksen of DNS-controles.

Ik beschouw het getal daarom als een bevinding uit de logs, niet als bewijs dat Google zelf al die verzoeken heeft uitgevoerd.

De combinatie met verdachte zoekmachinegerichte code maakte het wel relevant voor het onderzoek.

Waarom is dit belangrijk voor SEO?

Wanneer een website andere content aan zoekmachines aanbiedt dan aan bezoekers, kan dat grote gevolgen hebben.

Ongewenste URL's kunnen worden geïndexeerd. Spamcontent kan onder de domeinnaam verschijnen. Ook kunnen beveiligingswaarschuwingen of indexeringsproblemen ontstaan.

Google Search Console is daarom een belangrijk hulpmiddel bij het vervolgonderzoek.

U kunt daar onder andere beveiligingsmeldingen, geïndexeerde pagina's en afwijkingen in de zoekprestaties controleren.

In deze casus waren niet alle zoekmachinewaarnemingen geschikt voor publicatie. Sommige bevatten interne gegevens of informatie van derden. Die heb ik daarom niet als screenshot opgenomen.

Dat verandert niets aan de technische bevindingen die wel met de aangeleverde bestanden onderbouwd kunnen worden.

6. Een verdachte PHP-file met de naam Monarx

In een afzonderlijk ZIP-archief trof ik ook een about.php-bestand aan.

Dit bestand bevatte een header waarin Monarx werd genoemd.

Monarx is een naam die in beveiligingssoftware voorkomt. Maar de aanwezigheid van die naam in een bestand zegt niet automatisch iets over de werkelijke herkomst.

De rest van de inhoud was namelijk opvallend.

Er waren versluierde variabelen en constructies aanwezig waarmee gegevens werden gedecodeerd of verwerkt.

Dat maakte het bestand relevant voor het beveiligingsonderzoek.

Bewijsvisual 5: Een PHP-bestand met een Monarx-vermelding en versluierde code
Een PHP-bestand met een Monarx-vermelding en versluierde code. De header alleen bewijst niet dat het bestand daadwerkelijk afkomstig is van Monarx.

Ik wil hier bewust geen verkeerde conclusie aan verbinden.

Een beveiligingsnaam in de broncode is niet hetzelfde als bewijs dat een beveiligingsleverancier het bestand heeft geplaatst of veroorzaakt.

Het verdachte karakter zat in de combinatie van de inhoud, de constructies en de context waarin het bestand was aangetroffen.

7. Ook de WordPress-database en gebruikersaccounts moesten worden onderzocht

Bij een WordPress-hack is het verleidelijk om alleen naar de bestanden te kijken.

Maar WordPress bewaart belangrijke informatie in een database.

Daarin staan onder andere gebruikers, instellingen, pagina's, berichten en pluginconfiguraties.

Met phpMyAdmin en SQL heb ik daarom ook de database onderzocht.

Daarbij zijn gebruikersaccounts gecontroleerd en is tijdens het herstel onder andere het account site_admin verwijderd.

Daarnaast onderzocht ik via DirectAdmin de beschikbare sessiegegevens en inloggeschiedenis.

In het aangeleverde overzicht waren tien vermeldingen in de inloggeschiedenis te zien, verspreid over meerdere datums.

Een dergelijke geschiedenis kan helpen bij het reconstrueren van een incident, maar vormt zonder aanvullende gegevens geen bewijs dat een specifieke persoon onbevoegd toegang heeft gehad.

*Van deze gegevens publiceer ik bewust geen screenshot.*

De oorspronkelijke afbeeldingen bevatten IP-adressen, sessiegegevens en informatie over de hostingomgeving. Die zijn relevant voor het onderzoek, maar niet noodzakelijk om het technische verhaal openbaar te onderbouwen.

De belangrijkste les uit dit deel van het onderzoek was dat een website na het verwijderen van verdachte bestanden nog steeds risico kan lopen wanneer ongewenste accounts of toegangsrechten blijven bestaan.

8. Het herstellen van WordPress was niet hetzelfde als het verwijderen van alle malware

Tijdens het herstel werden verschillende onderdelen van de WordPress-installatie aangepakt.

Beschadigde en ontbrekende WordPress-kernbestanden moesten worden hersteld. Verdachte scripts werden onderzocht en de bestaande configuratie werd gecontroleerd.

Ook werd Filester verwijderd en WPCode uitgeschakeld.

Daarmee is overigens niet bewezen dat deze plugins de oorspronkelijke toegangsmethode vormden.

Uiteindelijk is ook een oudere back-up gebruikt om de website weer werkend te krijgen.

De website kwam weer online.

Dat was een belangrijk herstelresultaat, maar ik beschouwde het niet als sluitend bewijs dat de volledige hostingomgeving schoon was.

Daarvoor moest immers ook worden beoordeeld of de back-up zelf betrouwbaar was en of er elders nog toegangsmogelijkheden bestonden.

Na het herstel kwam bovendien opnieuw een malwaremelding binnen.

Die melding maakte duidelijk dat de beveiligingscontrole niet mocht eindigen zodra de homepage weer zichtbaar was.

*Een website herstellen en een beveiligingsincident volledig afsluiten zijn twee verschillende werkzaamheden.*

9. Was de hostingprovider verantwoordelijk?

De website draaide bij hostingprovider Zylon.

Tijdens een beveiligingsonderzoek kijk ik niet alleen naar WordPress, maar ook naar de serveromgeving.

Daarbij spelen zaken als logging, toegangsrechten, softwareversies, back-ups en beveiligingsmaatregelen een rol.

Maar het feit dat een website bij een bepaalde hostingprovider is ondergebracht, bewijst niet dat de aanval daar is begonnen.

In deze casus kon ik de oorspronkelijke toegangsmethode niet definitief vaststellen.

Dat kan bijvoorbeeld een kwetsbare plugin zijn geweest, misbruikte toegangsgegevens of een andere beveiligingszwakte.

Zonder sluitende gegevens over de eerste ongeautoriseerde toegang is het niet mogelijk om één specifieke oorzaak aan te wijzen.

Voor mij was het belangrijk om onderscheid te blijven maken tussen technische fouten, aangetroffen malware en de nog onbekende herkomst daarvan.

10. Wat heeft dit onderzoek mij geleerd?

Ik werk regelmatig aan WordPress-websites, zoekmachineoptimalisatie en technische websiteproblemen.

Maar bij dit onderzoek kwamen die onderwerpen op een andere manier samen.

Een probleem dat aanvankelijk op een gewone PHP-storing leek, bracht mij uiteindelijk bij serverlogs, versluierde code, databasecontroles en mogelijke SEO-cloaking.

En bij elk onderdeel kwam dezelfde vraag terug:

Wat kan ik daadwerkelijk aantonen?

Een vreemde bestandsnaam is geen sluitend bewijs. Een HTTP 500-fout vertelt niet automatisch waarom een website is gehackt. En een script dat zich voordoet als een beveiligingsprogramma hoeft niet daadwerkelijk afkomstig te zijn van die leverancier.

Daarom werkte ik met de oorspronkelijke bestanden, de beschikbare logs en gerichte technische controles.

De combinatie van Linux-terminal, FileZilla, DirectAdmin, phpMyAdmin, SQL en geautomatiseerde bestandsanalyse maakte het mogelijk om veel gerichter te zoeken.

Vooral dat laatste scheelde enorm veel tijd.

Ongeveer 14.000 bestanden handmatig nalopen is niet realistisch. Door afwijkingen geautomatiseerd te selecteren, kon ik me concentreren op de bestanden die extra aandacht verdienden.

Dit onderzoek liet mij ook zien dat cybersecurity en SEO dichter bij elkaar liggen dan op het eerste gezicht lijkt.

Wanneer een aanvaller zoekmachinecontent manipuleert, raakt dat niet alleen de veiligheid van een website, maar mogelijk ook de vindbaarheid en reputatie van het domein.

Wat kunt u zelf doen wanneer uw WordPress-website mogelijk gehackt is?

Bij een vermoedelijke WordPress-hack is het belangrijk om niet onmiddellijk alle verdachte bestanden te verwijderen.

Begin met het vastleggen van de bestaande situatie.

Bewaar waar mogelijk de oorspronkelijke bestanden, de database en relevante serverlogs. Controleer vervolgens welke bestanden zijn gewijzigd en of er onbekende accounts zijn toegevoegd.

Kijk niet alleen naar de WordPress-adminomgeving. Ook .htaccess, de PHP-bestanden en de serverconfiguratie kunnen belangrijk zijn.

Controleer daarnaast Google Search Console op onbekende geïndexeerde URL's, afwijkende pagina's en beveiligingsmeldingen.

Herstel vervolgens vanuit een aantoonbaar betrouwbare bron, beveilig de toegangsgegevens opnieuw en blijf de website monitoren.

Conclusie: wat zichtbaar is op de website, is niet altijd wat er werkelijk gebeurt

Deze praktijkcase begon met een WordPress-website die niet meer werkte.

Uiteindelijk vond ik onder andere een aangepaste .htaccess, een verdachte cache-pluginheader, sterk versluierde PHP-code, een gemanipuleerde index.php en duizenden HTTP 500-fouten in de serverlogs.

Ook waren er aanwijzingen voor zoekmachinegerichte manipulatie en ongewenste content.

Een deel daarvan kon ik rechtstreeks met bestanden en loggegevens onderbouwen. Andere waarnemingen kon ik vanwege privacy niet met screenshots publiceren, of vereisten aanvullend onderzoek voordat een definitieve conclusie mogelijk was.

De website is tijdens het herstel weer werkend gekregen. Daarmee was echter nog niet bewezen dat iedere beveiligingskwetsbaarheid was weggenomen.

*Het belangrijkste dat ik van dit incident heb meegenomen, is dat de zichtbare fout vaak maar een klein onderdeel van het werkelijke probleem is.*

Wie een WordPress-website beheert, moet soms verder kijken dan het dashboard, de homepage en de pluginlijst.

Juist in de bestanden, de database en de serverlogs kan informatie zitten die verklaart wat er werkelijk is gebeurd.


Deze praktijkcase beschrijft eigen onderzoeks- en herstelwerkzaamheden uit oktober 2026. De getoonde codefragmenten zijn afkomstig uit aangeleverde bestanden en voor publicatie ingekort. Privégegevens, volledige kwaadaardige scripts en gevoelige informatie over de hostingomgeving zijn niet openbaar gemaakt.

Technische bronnen