De meest voorkomende manieren waarop dit aan het licht komt:
- Hoster stuurt waarschuwing: "Outgoing mail rate exceeded" of "Suspicious mail activity detected"
- Hosting account is al geschorst (mailfunctie uit, soms hele site offline)
- Je krijgt honderden bounces ("Mail Delivery Failed", "Returned mail: User unknown") naar je admin-mailbox van mails die je niet hebt verzonden
- Klanten klagen dat ze spam krijgen "van jou"
- Je domein staat ineens op een blacklist (Spamhaus, SpamCop, Barracuda)
- Authentieke mail (contactformulier, orderbevestigingen) komt niet meer aan — verdrukt door slechte reputatie
- Verkeer-graphs tonen ineens duizenden POST-requests naar contact- of formulier-URLs
Eerst: ben je écht gehackt of is dit spoofing?
Belangrijk verschil voordat je gaat opruimen. Twee fundamenteel verschillende scenario's:
Scenario A — Echte compromittering
Iemand heeft daadwerkelijk toegang tot je hosting/site en gebruikt jouw mailserver om vanaf jouw IP en domein te versturen. Dit is een hack, en dit artikel gaat hierover.
Symptomen:
- Hosting toont in mail-statistieken hoge outbound volumes
- Bounces ontstaan vanaf jouw eigen IP/server
- Hoster heeft mail-rate-limiet bereikt of geactiveerd
Scenario B — Spoofing zonder hack
Iemand verstuurt mail die doet alsof 'ie van jouw domein komt, maar gebruikt z'n eigen server. Jouw infrastructuur is volkomen schoon. Bounces komen toch bij jou terecht omdat het from-adres jouw domein is.
Symptomen:
- Veel bounces, maar je hosting toont géén verhoogde outbound volume
- Mail-headers laten zien dat de mail vanaf een buitenlandse IP komt, niet jouw server
- Geen verdachte processen of bestanden op je hosting
Dit is geen hack van je site, maar een misbruik van je domeinnaam. Vraagt om een andere aanpak: SPF/DKIM/DMARC strenger zetten zodat ontvangers die spoofing afwijzen. Geen file-cleanup nodig. Zie SPF, DKIM en DMARC instellen voor jouw domein.
Hoe onderscheid je de twee?
Open één van de bouncemails die je terugkreeg. Klik op "View original" / "Show source" / "Bekijk bronnen" en zoek naar de Received-headers. Die tonen het IP van de werkelijke verzender:
Received: from mail.attacker.example
by mx.gmail.com with SMTP id ...
for <recipient@example.com>
Received: from your-website.nl ([212.45.67.89])
by mail.attacker.example...
Komt het IP overeen met je hosting-IP? Echte hack. Een willekeurig buitenlands IP? Spoofing.
De rest van dit artikel gaat over scenario A — een echte compromittering.
Stap 1: stop de bloeding (eerste 30 minuten)
Hoogste prioriteit: voorkom dat er meer spam uitgaat. Elke minuut extra mail = meer schade aan je reputatie.
Eis dat hosting outbound mail tijdelijk uitschakelt
Als je hoster nog niet ingegrepen heeft, vraag direct: "Schakel outbound mail tijdelijk uit op mijn account terwijl ik onderzoek doe." De meeste hosters doen dit binnen 5-10 minuten. Liever 1 dag down dan 1 week op een blacklist.
Verander alle wachtwoorden
- WordPress admin (alle users)
- Hosting paneel
- FTP/SFTP/SSH
- Database
- Mailbox-wachtwoorden (vooral als hetzelfde wachtwoord ergens anders gebruikt)
Gebruik wachtwoordmanager-gegenereerde wachtwoorden van 20+ tekens.
Roteer secret keys in wp-config.php
De AUTH_KEY, SECURE_AUTH_KEY, NONCE_KEY etc. genereer je opnieuw via api.wordpress.org/secret-key/1.1/salt/. Vervang het volledige blok in wp-config.php. Iedereen wordt uitgelogd, gestolen sessies zijn ongeldig.
Forensische backup
Maak een backup van de huidige (gehackte) staat naar een externe locatie. Bij verkeerde verwijdering kun je terug, en je hebt evidence als hosting forensische details vraagt.
Stap 2: vind de bron
Bij een gehackte mailer zijn er typisch vier vectoren waardoor de spam wordt verstuurd. Ga ze stuk voor stuk af.
Vector 1: misbruik van een bestaand contactformulier
Klassieker. Je contact-form gebruikt een onveilige PHP-mailer (vaak een oudere versie van PHPMailer met de CVE-2016-10033-bug, of een custom-script zonder fatsoenlijke validatie). Aanvaller stuurt POST-requests met geprepareerde data en de form verstuurt mail naar willekeurige adressen.
Detectie:
# Check access_log voor verdachte POST-requests
grep "POST.*contact" ~/logs/access_log | wc -l
grep "POST.*form" ~/logs/access_log | tail -50
# Top IP-adressen die POSTs doen
awk '$6=="\"POST" {print $1}' ~/logs/access_log | sort | uniq -c | sort -rn | head -10
Honderden POSTs naar één URL vanaf één IP? Dat is je bron.
Fix:
- Update WordPress core, plugins en theme (CF7, WPForms etc.)
- Voeg een goede captcha toe — Cloudflare Turnstile, hCaptcha, of reCAPTCHA
- Honeypot-veld in formulier (verborgen veld dat alleen bots invullen)
- Rate-limit op formulier-endpoint via
.htaccessof fail2ban - Bij custom mail-script: vervang door PHPMailer 6.x of switch naar SMTP-plugin (zie WordPress emails komen niet aan)
Vector 2: geüploade mailer-script (webshell)
Aanvaller heeft een PHP-bestand geüpload waarmee 'ie spam kan versturen via direct mail() of SMTP. Bekend onder namen als "PHPMailer Pro", "AnonMailer", "Bulk Mailer Inbox" — typische scriptkiddie-tools die overal hetzelfde uitzien.
Detectie via SSH:
# Recent gewijzigde PHP-bestanden
find . -name "*.php" -mtime -30 -type f
# Bestanden in uploads-map die niet daar horen
find wp-content/uploads/ -name "*.php" -type f
# Bestanden met typische mailer-content
grep -rln "mail_to" --include="*.php" .
grep -rln "PHPMailer.*VERSION" --include="*.php" . | grep -v "wp-includes"
grep -rln "SwiftMailer" --include="*.php" . | grep -v "vendor/"
# Verdachte functienamen
grep -rln "smtp_send\|smtp_relay\|bulkmailer" --include="*.php" .
Fix: bestand verwijderen. Maar niet alleen dat — als één webshell bestaat, zijn er meestal meerdere. Doorzoek systematisch.
Vector 3: gehackte plugin met mail-functionaliteit
Een legitime plugin (mail-marketing, contact-formulier, e-commerce) is gehackt of door een verouderde versie misbruikt om mail te versturen. Voorbeelden: oude Mailpoet-versies, kwetsbare nieuwsbrief-plugins, lekke WooCommerce-extensies.
Detectie:
- WordPress mail-log (via WP Mail Logging plugin) — wat is recent verstuurd, en welke plugin triggerde 't?
- Update-status van mail-gerelateerde plugins controleren
- Database
wp_optionschecken op queue-tabellen vol pending mails
Fix: plugin updaten of vervangen. Bij verouderde versies waar geen update meer voor is — verwijderen en alternatief zoeken.
Vector 4: gehackt admin-account dat mailings stuurt
Een aanvaller heeft een admin-account te pakken (gestolen wachtwoord of brute-force) en gebruikt een legitime mailing-plugin om bulk te versturen.
Detectie:
- Lijst van users in wp_users — onbekende admin-accounts? Check ook userrole in
wp_usermeta - Last login-tijden — admin die je niet kent loggde gisteren in?
- Recent geactiveerde mail-plugins die jij niet hebt geactiveerd
wp user list --role=administrator
wp user list --orderby=user_registered --order=DESC --number=10
Fix: onbekende admin-accounts verwijderen, alle wachtwoorden van legitime admins resetten, 2FA verplicht maken.
Stap 3: complete cleanup
Nu de bron geïdentificeerd is, complete schoonmaak. Ga ervan uit dat de aanvaller op meerdere plekken backdoors heeft achtergelaten — vrijwel altijd zo.
Zoek alle webshells
# Bekende payload-patronen
grep -rln "eval(\$_POST" --include="*.php" .
grep -rln "eval(\$_GET" --include="*.php" .
grep -rln "eval(base64_decode" --include="*.php" .
grep -rln "preg_replace.*\/e" --include="*.php" .
grep -rln "assert(\$_" --include="*.php" .
grep -rln "system(\$_" --include="*.php" .
grep -rln "shell_exec(\$_" --include="*.php" .
# Verdacht-grote PHP-bestanden in uploads/
find wp-content/uploads/ -name "*.php" -size +5k -ls
# Gefuncte filenames
find . -name "*.php" \( -name "wp-feed.php" -o -name "wp-defunct.php" -o -name "wp-cli.php" \)
Voor elk verdacht bestand: bekijk inhoud, vergelijk met een schone WordPress-installatie, verwijder bij twijfel. Bewaar forensische backup.
Re-installeer core en plugins
wp core download --force
wp plugin install $(wp plugin list --status=active --field=name) --force
Custom thema's en plugins met eigen aanpassingen: vergelijk handmatig met je laatste schone backup.
Check cron-jobs op persistentie
Aanvallers gebruiken cron om backdoors automatisch te herstellen. Zie Cron jobs uitgelegd.
wp cron event list
crontab -l # via SSH
Onbekende cron-events die PHP-scripts uitvoeren of curl naar verdachte URL's? Verwijderen.
Database opruimen
wp_users: onbekende admin-accounts verwijderenwp_options→active_plugins: lijst checken op onbekende plugin-namen- Mail-queue tabellen (afhankelijk van plugin) leegmaken
wp_posts: gemaakte posts/pages controleren op spam-injecties (vooral als ook SEO-spam vermoed)
Stap 4: domein-reputatie herstellen
Site is schoon, maar het kwaad aan je reputatie is gedaan. Stappen om dat te herstellen:
Check op blacklists
Tools:
- MXToolbox blacklist check — checkt 100+ blacklists tegelijk
- Spamhaus lookup — de belangrijkste blacklist
- Google Postmaster Tools — toont reputatie van je domein bij Gmail specifiek
Test zowel je domein als je verzend-IP. Op shared hosting kun je het IP zelden zelf delisten — daar moet de hoster bij. Het domein kun je vaak wel zelf laten weghalen.
Vraag delisting aan
Vrijwel elke blacklist heeft een delisting-formulier. Vereisten:
- De spam-bron is daadwerkelijk weg (zonder is delisting zinloos)
- SPF, DKIM, DMARC zijn correct ingesteld (zie SPF, DKIM, DMARC artikel)
- Beschrijving van de oorzaak en wat je hebt gefikst
Spamhaus reageert meestal binnen 24-48 uur na delisting-aanvraag. Andere lijsten variëren.
Zet SPF/DKIM/DMARC strenger
Na een hack-incident: maak het toekomstig misbruik moeilijker. DMARC op p=quarantine of p=reject (na een paar weken monitoring) zorgt dat als iemand later weer probeert vanaf jouw domein te spoofen, ontvangers het direct weigeren.
Zie SPF, DKIM, DMARC instellen.
Switch naar dedicated SMTP-provider
Als je hosting-IP een tijdje op een blacklist heeft gestaan, blijft de reputatie maanden achter. Beste route: gebruik een professionele transactionele mail-provider (Brevo, Mailgun, SendGrid, Amazon SES) voor outbound mail. Hun IPs hebben uitstekende reputatie en je hosting-IP is dan niet meer relevant voor je deliverability. Zie WordPress emails komen niet aan.
Stap 5: preventie
- Update-discipline: WordPress core, alle plugins en theme's altijd up-to-date. Een verouderde mail-plugin is vector #1
- Verwijder ongebruikte plugins/theme's: niet alleen deactiveren, fysiek weg. Verouderde inactieve plugins zijn aanvalsoppervlak
- 2FA op alle admin-accounts: voorkomt brute-force account-overname
- Captcha op alle publieke formulieren: Cloudflare Turnstile is gratis en niet-irritant
- Honeypot-velden in custom formulieren — bots vullen ze in, mensen niet
- Rate-limit op contact-form endpoints via fail2ban of WAF-regels
- Disable file editing in wp-admin:
define('DISALLOW_FILE_EDIT', true);in wp-config.php - Disable PHP-execution in uploads-map via
.htaccessinwp-content/uploads/:<FilesMatch "\.(php|php3|phtml|phar)$"> Require all denied </FilesMatch> - Outbound mail-monitoring: hosting heeft vaak alerts bij verhoogde mail-rate. Zorg dat ze naar een werkend e-mail komen
- SPF/DKIM/DMARC permanent goed: voorkomt dat na herstel toekomstige spoofing succesvol is
- Plus alle 10 stappen uit WordPress beveiligen — 10 essentiële stappen of laat de volledige hardening door mij uitvoeren
Verwante hacks die vaak gecombineerd voorkomen
Wie toegang heeft om spam te versturen, heeft vaak ook andere monetisaties geïnstalleerd. Check ook:
- SEO-spam — Chinese, Pharma, Japanse varianten. Zie Japanse SEO-spam, Chinese spam, Pharma hack
- Hidden admin-users
- Cron-jobs voor persistentie
- Backdoors in core- of plugin-bestanden
Wanneer schakel je hulp in?
- Hosting heeft je account geschorst en je hebt deadline van 24-48 uur om aan te tonen dat 't is opgelost
- Je vindt webshells of backdoors maar weet niet zeker of je alles weg hebt
- Spam blijft uitgaan ondanks dat je de "duidelijke" boosdoener hebt verwijderd — diepere persistentie
- Je domein staat op meerdere blacklists en delisting-aanvragen worden afgewezen
- Klanten klagen massaal en je hebt geen tijd voor stap-voor-stap onderzoek
- Site combineert mailspam met andere hack-symptomen (SEO-injectie, ranking-schade)
- WooCommerce-shop met live transacties en je kunt geen uur extra downtime hebben
- Je bent niet zeker of het echte hack of spoofing is en de aanpak verschilt fundamenteel
Spam-uitstoot van een gehackte site is op te lossen, maar 't is een race tegen de klok: hoe sneller je de bron stopt, hoe minder schade aan je reputatie. De stappen hierboven dekken het volledige proces — van noodstop tot herstel — maar in een live-paniek-scenario waar elke minuut telt, is iemand met dagelijkse ervaring efficiënter dan trial-and-error. Belangrijkste boodschap: handel binnen het uur, niet binnen de dag.