OK, dat was even een einde aan mijn zondagochtend die net wat anders liep dan verwacht. Eigenlijk wilde ik gewoon even een bericht plaatsen op het Activegeek weblog (komt zo meteen alsnog). Maar ik merkte dat de site heel erg traag was.
Toen ik ging kijken binnen Virtualmin (de beheeromgeving van de server) hoe dat zou kunnen, zag ik daar dat de server inderdaad stond te blazen. De CPU load averages kwamen ver boven de 40 uit, terwijl die idealiter bij deze server onder de 2.0 zou moeten blijven. De server bereiken via het admin-scherm ging gelukkig nog, maar WordPress trok het niet meer.
Toen ik in de Apache Access log keek om te zien wat of wie er dan zoveel beslag legde op de server, werd al snel duidelijk wat er aan de hand was: mijn server had te maken met een “WordPress Brute Force Attack“.
Het logbestand liep namelijk vol met verzoeken voor het bestand wp-login.php
vanuit een groot aantal verschillende IP-adressen.
Ik heb, nu de aanval voorbij is, het logbestand even gedownload en geanalyseerd. In totaal duurde de aanval 2 uur (totdat ik hem kon stoppen) en in die tijd werd er 21.715 keer geprobeerd in te loggen vanuit 1.957 verschillende IP-adressen.
Hoe stop je zo’n aanval?
Mocht je hier komen via Google en jouw server staat ook te stomen, eerst maar even de oplossing die mijn server weer adem gaf: Dat was het (tijdelijk) aanpassen van het .htaccess bestand op je server. Ik heb daarin de volgende regel (bovenaan) toegevoegd: RewriteRule ^wp-login http://google.nl/ [L]
Hierdoor wordt elk verzoek voor de login-pagina doorgestuurd naar Google. Eigenlijk niet netjes omdat ik nu de aanval doorstuur naar Google, het zou ook hiermee moeten werken: RewriteRule ^wp-login http://%{REMOTE_ADDR}/$ [L]
(je stuurt hem nu door naar zichzelf) maar ik kon op dat moment even niets beters verzinnen.
Zoals je in de grafiek boven bij het bericht kunt zien, zakte de aanval (ik voerde de aanpassing om 12:30 uur in) daarna snel in en de CPU load zakte ook weer naar zijn normale niveau terug.
Wat is een Brute Force Attack?
Bij een Brute Force Attack probeert een hacker heel lomp (met brute kracht) toegang te krijgen tot je WordPress installatie door simpelweg een groot aantal combinaties van wachtwoorden uit te proberen. Dat doet zo’n hacker niet vanaf één computer, maar vanaf een groot aantal computers die hij/zij in een eerder stadium al eens gehackt heeft. Als ik pech gehad had, dan was de aanval gelukt voordat ik het opgemerkt had en dan had de hacker admin toegang gehad tot mijn WordPress weblog..
Hoe voorkom je zo’n aanval?
Er is een pagina op de WordPress website waarin een aantal verschillende opties wordt besproken om zo’n aanval af te slaan. Een aantal van de eenvoudige opties had ik gelukkig al uitgevoerd: mijn weblogs hebben niet langer een administrator-account dat als usernaam “admin” of “administrator” heeft. Ook de naam van je weblog zelf (“activegeek” in mijn geval) is niet verstandig, ik zag namelijk dat ook die als username geprobeerd werd. Het idee achter het aanpassen van die account-naam is je anders een hacker al 50% van het totale geheim (account-naam + wachtwoord) cadeau geeft. Zolang een Brute Force Attack op mijn weblog een account-naam gebruikt die niet bestaat, komt zo’n hacker op die manier in ieder geval nooit binnen. En zorg voor een sterk wachtwoord!
Daarnaast heeft mijn weblog geen gebruiker meer met user-id = 1. Dat is standaard wel zo, dat is namelijk normaal gesproken het admin-account dat bij installatie wordt aangemaakt. Bij een Brute Force Attack heeft een hacker er niets aan, maar bij een fout in een plugin waarbij hij op afstand SQL-code op mijn database los kan laten kan dat zo’n hacker wel helpen (en nu dus niet).
Ook is de prefix van de tabellen in mijn database niet langer “wp_”, ook dat maakt het moeilijker om via SQL-code iets te veranderen in de database.
Je hoeft die aanpassingen gelukkig niet allemaal zelf door te voeren. Er zijn een aantal WordPress plugins die hiermee kunnen helpen. Eentje die ik zelf gebruik is “Better WP Security“. Daarmee kun je de admin naam en ID aanpassen, een backup voor je database plannen (ook belangrijk!), het aantal keren dat iemand tevergeefs probeert in te loggen instellen en nog veel meer. In dat laatste geval is het al handig dat je een mail krijgt als zo’n aanval plaats vindt. Dan kun je er op dat moment alsnog voor kiezen om tijdelijk de .htaccess hack toe te passen en het inloggen helemaal uit te zetten. Alleen is dat natuurlijk niet zo handig als je met meerdere personen ook daadwerkelijk gebruik wilt kunnen maken van de site.
Een andere optie die ook genoemd wordt is het gebruik van CloudFlare. Daar heb ik nog geen ervaring mee, het aanpassen van mijn nameservers voor de .nl domeinen die ik heb moet via de helpdesk van Bhosted (waar ze geregistreerd zijn) gebeuren.
Wel heb ik dit codeblok aan mijn .htaccess toegevoegd:
<lIfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .(wp-comments-post|wp-login)\.php*
RewriteCond %{HTTP_REFERER} !.*activegeek.nl.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) http://%{REMOTE_ADDR}/$ [R=301,L]
</ifModule>
Het zou moeten voorkomen dat een hacker de login-pagina aanroept zonder dat het formulier vanaf de site opgestuurd wordt, maar het lijkt er op het moment op dat dat zeker niet 100% van de pogingen tegen houdt, want de afgelopen uren werden toch nog 13 IP-adressen automatisch geblokkeerd omdat ze te vaak hadden geprobeerd in te loggen. Gelukkig geen nieuwe aanval, maar wel iets om in de gaten te houden.
p.s. de grafiek boven bij het bericht laat het aantal login-pogingen per minuut zien. Zelfs bij zo’n 250 login pogingen per minuut kwam mijn server, die normaal dus niet veel te doen heeft al tot stilstand. Dat vind ik zelf redelijk snel, dus als iemand daar nog tips voor heeft, dan hou ik me aanbevolen.
@bemeall .htaccess aanpassen bleek het beste te werken. wp-login.php herbenoemen deed niet veel – http://t.co/cgpNJQJ2Zk
In een reactie via Google+ verwijst Hans Wolters naar fail2ban (zie ook dit bericht voor WordPress). Die optie kende ik nog niet, zal ik (ook) naar kijken.
WordPress Brute Force Attack!: OK, dat was even een einde aan mijn zondagochtend die net wat anders liep dan … http://t.co/4px8Ejhais
Oef! Ik zou echt schrikken als t op mijn server zou gebeuren.
Ik gebruik nu al wel 3 maanden CloudFlare. Zonder problemen. Eenmaal ingesteld heb je er eigenlijk geen omkijken naar.
Daarnaast heb ik nog BruteProtect. http://wordpress.org/plugins/bruteprotect/
Succes!
Hi Pierre,
Jij ook al? Mooi verslag, mijn blockacties waren vergelijkbaar, maar in plaats van Google te ‘belasten’ met de aanval stuurde ik het verkeer ‘netjes’ door naar het NCSC 🙂
“Zelfs bij zo’n 250 login pogingen per minuut kwam mijn server, die normaal dus niet veel te doen heeft al tot stilstand. Dat vind ik zelf redelijk snel, dus als iemand daar nog tips voor heeft, dan hou ik me aanbevolen.”
-> 250 requests per minuut is voor een PHP-site op Apache2 met standaardinstellingen (in apache2.conf of httpd.conf) redelijk normaal. Als je dit substantieel wilt verhogen is het gebruik van NginX als frontend-webserver aan te raden. Ik heb dit zelf een paar keer gedaan (NginX als frontend webserver en Apache2 als reverse proxy) en het aantal requests dat kon worden uitgevoerd verTIENvoudigde hiermee. Zie: http://www.howtoforge.com/how-to-set-up-nginx-as-a-reverse-proxy-for-apache2-on-ubuntu-12.04 voor de basics.
W3 Total Cache levert in geval van WordPress ook een enorme verbetering, en het checken van je site met http://tools.pingdom.com/ en http://gtmetrix.com/ geeft ook aardig inzicht in je site en de meest voor de hand liggende verbeterpunten.
Tja, ik ben soms te eerlijk in mijn verslaggeving. Maar liever dat ik toegeef dat mijn eerste oplossing niet de meest handige/nette was en zo wellicht iemand anders weerhoud ervan, dan dat ik doe alsof ik het meteen in alle hectiek “perfect” aangepakt heb.
NginX had ik inderdaad van gehoord als veel “beter” (lichter) alternatief voor Apache. Ik gebruik VirtualMin en ook daar kun je NginX mee gebruiken, maar de officiële documentatie zegt “Switching a system from the Apache webserver (installed by default by Virtualmin) to Nginx should only be done if no virtual servers with websites have been created yet. Ideally the change should be done on a freshly installed system” terwijl ik al heel wat domeinen geïnstalleerd heb staan.
Ik gebruik Quick Cache voor WordPress. Dat is ook een goede oplossing, maar beiden helpen je niet bij zo’n aanval. Vanuit het login script is er namelijk niets om te cachen. De pagina zelf wordt niet eens aangeroepen, ze sturen steeds een username + password naar het script, dat moet dan in de database gaan kijken of dat een geldige combinatie is en (gelukkig altijd) een foutmelding genereren als dat niet zo is.
Hi
Thank you for this article!
Please consider emphasizing “two-factor authentication” as an important security measure that helps against phishing and bruteforce attacks. I recommend the Rublon for WordPress plugin for this because it’s the easiest one in the world:
http://wordpress.org/plugins/rublon/
Rublon protects your account from sign ins from unknown devices, even if your password gets stolen. It’s invisible two-factor authentication. In contrast to other solutions, with Rublon you have to use your smartphone only once to define your Trusted Devices. Check out our website for detailed info: http://www.rublon.com.
We have raving 5-star reviews from our clients:
– https://rublon.com/clients
– http://wordpress.org/support/view/plugin-reviews/rublon
In case of any questions, please don’t hesitate to contact me 🙂
Best
Michal
Rublon
http://www.rublon.com