Tässä kirjoituksessa käsittelen WordPressin tietoturvaa hyökkääjän näkökulmasta. Kirjoitus perustuu tunkeutumisenestojärjestelmän lokitiedostojen analyysiin, jonka pohjalta olen tehnyt päätelmiä hyökkääjän toimintatavoista ja työkaluista.
Hyökkääjän toimintatapojen kuvauksen lisäksi annan suosituksia hyökkäyksiltä suojautumiseen.
Kilpajuoksu tiivistyy
Jokaista WordPress-asennusta vastaan tehdään päivittäin hyökkäysyrityksiä. Tarkalleen ottaen kaikkia verkossa olevia palvelimia ja laitteita vastaan hyökätään jatkuvasti, eikä WordPress ole siinä suhteessa mitenkään erityinen kohde. Kun uusi IP-osoite liitetään verkkoon, viimeistään muutaman minuutin kuluessa se alkaa vastaanottaa esimerkiksi SSH-porttiin tulevia kirjautumisyrityksiä.
Päivittäisten hyökkäysten määrä vaihtelee joistakin kymmenistä useisiin tuhansiin. Ylärajaa ei periaatteessa ole, mikäli palvelin pysyy pystyssä ja ylläpitäjä ei aktiivisilla toimenpiteillä estä hyökkääjien toimia. Yhteistä hyökkäyksille on, että ne tehdään lähes poikkeuksetta automaattisilla työkaluilla, valmiita kohdelistoja hyödyntäen.
Erilaiset skannerit ovatkin tyypillinen näky tunkeutumisenestojärjestelmän lokitiedostoissa. Osa skannereista toimii passiivisesti keräten tietoja, kuten lisäosien nimiä ja versionumeroita, tulevia hyökkäyksiä varten ja osa suorittaa aktiivisia toimenpiteitä sivuston murtamiseksi. Skannerin jäljiltä lokiin jää seuraavan tyyppisiä pyyntöjä:
/wp-content/plugins/user-meta/readme.txt
/wp-content/plugins/nextgen-gallery/changelog.txt
Koska hyökkäyksissä hyödynnetään valmiita kohdelistoja, haavoittuvuuksien julkaisun ja hyödyntämisyritysten välinen aika on pienentynyt jatkuvasti. Kriittisten haavoittuvuuksien kohdalla ensimmäiset hyödyntämisyritykset näkyvät lokeissa alle 24 tunnin kuluessa haavoittuvuuden julkaisusta. Tästä syystä on erityisen tärkeää huolehtia WordPressin ja lisäosien päivityksistä jatkuvasti ja seurata julkaistavia haavoittuvuuksia esimerkiksi wpvulndb.com-sivuston kautta.
Motiivista riippumatta hyökkääjän ensisijaisena tavoitteena on päästä suorittamaan omaa koodia kohdepalvelimella. Koodin suoritus voi tapahtua suoraan haavoittuvuutta hyödyntämällä tai hankkimalla ensin pääkäyttäjätason pääsy julkaisujärjestelmään ja jatkamalla siitä eteenpäin joko julkaisujärjestelmän ominaisuuksia tai haavoittuvuutta hyödyntäen.
Piiloutumalla voittaa harvoin
Tyypillisesti yhden hyökkäyksen aikana testataan usean eri julkaisujärjestestelmän ja teknologian tunnetut haavoittuvuudet, käyttöjärjestelmätason haavoittuvuuksia unohtamatta. Piiloutuminen ei siis ole suositeltava strategia, koska hyökkääjä yleensä kokeilee kaikkia käytettävissä olevia menetelmiä, eikä kohdenna hyökkäystä palvelimelle asennettujen sovellusten perusteella.
Toisaalta ei ole mitään syytä paljastaa käyttöjärjestelmästä tai sovelluksesta enempää kuin on tarpeen, joten versionumerot, versionhallintatiedot, lokit ja status-sivut kannattaa pitää jatkossakin piilossa.
Helpot tavat ensin
Hyökkääjän kannalta ei ole mielekästä käyttää yhtään enempää voimaa ja resursseja kuin on tarpeen. Lokitiedostoja analysoimalla näkee selvästi, että ensin kokeillaan helpot tavat ja vasta niiden epäonnistuessa siirrytään monimutkaisempiin tapoihin.
Hyökkääjän kannalta ehkä helpoin tapa murtaa WordPress on päästä asentamaan se omilla ehdoilla. Tämän vuoksi hyökkääjät etsivät kesken jääneitä WordPress-asennuksia /old/wp-admin/setup-config.php -tyyppisillä pyynnöillä.
Kun kesken jääneeseen asennukseen liitetään hyökkääjän oma tietokanta, asennus päästään suorittamaan loppuun. Tämän jälkeen palvelimella on helppo suorittaa hyökkääjän omaa koodia esimerkiksi WordPressin sisäisen koodieditorin kautta tai asentamalla hyökkääjän oma ”lisäosa”, jolla päästään tutkimaan palvelimen sisältöä ja suorittamaan lisää haitallisia toimenpiteitä.
Suositukset suojautumiseen:
Ensisijaisesti tämän tyyppisiltä hyökkäyksiltä kannattaa suojautua estämällä pääsy WordPressin asennustiedostoihin (setup-config.php/install.php) kokonaan palvelimen konfiguraation avulla ja asentamalla WordPress esimerkiksi WP CLI -komentorivityökalun kautta.
Lisäksi WordPressin sisäinen koodieditori ja uusien lisäosien asentaminen kannattaa poistaa käytöstä tuotantopalvelimelta, jotta mahdollisesti pääkäyttäjänä sisään päässyt hyökkääjä ei pääse jatkamaan hyökkäystä pidemmälle helposti. Levylle kirjoittaminen kannattaa rajoittaa ainoastaan uploads-hakemistoon ja varmistaa konfiguraation avulla, että kyseisestä hakemistosta ei voida suorittaa php-koodia.
Sisään heikon salasanan avulla
Salasanan arvaukseen tähtäävät hyökkäykset ovat kehittyneet vähitellen älykkäämmäksi. Enää hyökkäyksissä ei käytetä pelkästään valmiita tunnuslistoja ja vakiokäyttäjätunnuksia, kuten admin, vaan hyökkääjä pyrkii ensin keräämään listan oikeista käyttäjätunnuksista, joiden salasanaa pyritään arvaamaan. Onnistumisen todennäköisyys kasvaa, kun kahden tuntemattoman muuttujan (tunnus/salasana) sijasta pitääkin saada arvattua ainoastaan salasana.
Hyökkääjän on helppo hankkia oikeat käyttäjätunnukset joko kirjoittaja-arkiston tai REST-rajapinnan kautta. WordPressin vakioasennus paljastaa käyttäjätunnuksen, kun tehdään pyyntö /?author=1 tai /wp-json/wp/v2/users/1 -polkuihin.
Kun tunnukset on kerätty, hyökkääjä kokeilee kullekin tunnukselle eri salasanoja siihen asti, kunnes joku tunnuksista murtuu. Hyökkääjän kannalta yhdenkin tunnuksen murtaminen riittää, mikäli käyttöoikeustaso on riittävä. Mikäli hyökkäykseen ei ole varauduttu, aika on hyökkääjän puolella.
Suositukset suojautumiseen:
Käyttäjätunnuksena ei kannata käyttää mitään vakiokäyttäjätunnusta, kuten admin tai administrator. Käyttöoikeudet kannattaa jakaa ainoastaan tarpeeseen perustuen ja huolehtia vahvojen salasanojen pakotuksesta. Myös testaus- ja koulutuskäyttöön luotujen tunnusten kanssa tulee käyttää vahvaa salasanaa.
Epäonnistuneiden kirjautumisyrityksen määrää kannattaa rajoittaa ja lisätä käyttäjä tarvittaessa palomuurin estolistalle.
Pääsy käyttäjätunnukset paljastaviin polkuihin kannattaa estää palvelimen konfiguraation avulla.
Pelkkää estoa tehokkaampi tapa on rakentaa ns. hunajapurkki hyökkääjää varten palauttamalla käyttäjätunnusten kalastelupyyntöihin satunnainen merkkijono ja estää kaikki käyttäjät, jotka käyttävät kyseistä merkkijonoa kirjaututumisyrityksissä. Tällä menetelmällä saadaan arviolta yli 90% ei-toivotuista kirjautumisyrityksistä estettyä.
Ylipäätään suojautuminen kannattaa tehdä palvelintasolla mikäli mahdollista, koska tällöin hyökkääjä ei voi siirtyä seuraavaan hyökkäystapaan, mikäli yhdenkin hyökkäyksen tunnusmerkit täyttyvät.
Takaovesta tietokantaan
Mikäli pääsy WordPressiin ei onnistu tunnusten avulla, vaihtoehtoinen tapa päästä käsiksi sivustoon on murtautua tietokannan kautta.
Yksi suosittu tapa tietokannan tunnusten hankkimiseen on etsiä wp-config.php-tiedoston varmuuskopioita tai editorin tekemiä automaattitallennuksia, kuten wp-config.bak tai wp-config.php~. Mikäli www-palvelinta ei ole konfiguroitu käsittelemään kyseisiä tiedostomuotoja, ne saattavat latautua tekstimuotoisena hyökkääjän koneelle.
Toinen tapa saada tietokannan tunnukset hankittua on hyödyntää tiedostoja käsittelevien lisäosien suunnitteluvirheitä. Yhteistä näille on, että ne saavat parametrina tiedostopolun, joka on käsittelyn kohteena.
Mikäli käsittelijälle annettavaa polkua ei käsitellä oikein, hyökkääjä saattaa päästä käsiksi tietokantatunnukset sisältävään tiedostoon, kuten wp-config.php:hen tai .my.cnf:iin.
Tietokantatunnusten kalasteluun tähtäävät pyynnöt näkyvät lokeissa esimerkiksi seuraavasti:
/wp-content/themes/theme/css.php?files=../../../../wp-config.php
/wp-admin/admin-ajax.php?action=revslider_show_image&img=../../.my.cnf
Suositukset suojautumiseen:
Kaikkiin wp-config* -alkuisiin tiedostoihin pääsy kannattaa estää palvelintasolla ja käyttää wp-config.php-tiedostossa niin tiukkoja lukuoikeuksia kuin mahdollista.
Käytettäville lisäosille kannattaa tehdä tietoturva-auditointi ja varmistaa, että ne eivät mahdollista kuvattua directory traversal -haavoittuvuutta, jonka kautta päästään käsiksi tiedostoihin tai kansioihin, joihin käyttäjällä ei normaalisti pitäisi olla pääsyä. Käytännössä polku on helppo validoida esimerkiksi PHP:n realpath-funktiolla.
Lisäksi tietokannan käyttö kannattaa rajata aina ainoastaan sovelluspalvelimen käyttöön, jotta tietokannan tunnukset saanut hyökkääjä ei voi käyttää tunnuksia tietokantaan yhdistämiseen.
Muita yleisiä hyökkäys ja kalasteluyrityksiä
- phpMyAdmin-tietokantatyökalun kesken jääneiden asennusten etsintä: /phpmyadmin/scripts/setup.php
- SSH-avainten etsintä: /root/.ssh/id_rsa
Kohti kokonaisvaltaista tietoturvaa
Otsikoinnista huolimatta olen sitä mieltä, että ei ole olemassa erikseen WordPressin tietoturvaa vaan ainoastaan yksi tietoturvan kokonaisuus, joka sisältää edellä mainittujen asioiden lisäksi paljon muitakin osa-alueita, kuten
- Toimitilojen ja palvelintilojen kulunvalvonta
- Palvelinten käyttöjärjestelmien ja ohjelmistojen päivitykset
- Palvelinten palomuurit, pääsynhallinta ja SSH-avainten hallinta
- Palvelinten konfiguraationhallinta ja konfiguraatiovirheiden välttäminen
- Tietoturvalliset kehityskäytännöt
- Työvälineiden tietoturva ja salaus
- Varmuuskopiointikäytänteet
Tietoturvan kokonaisuuden tunnistamisen lisäksi on tärkeää, että kokonaisuutta kehitetään jatkuvasti. Jatkuvaa tietoturvan kehittämistä kannattaa vaatia myös verkkopalvelukumppanilta, riippumatta mitä järjestelmää käytetään.
Osa jatkuvaa kehittämistä on hyökkääjän ymmärtäminen, koska se mahdollistaa uusien suojausmenetelmien kehittämisen. Se on työtä, joka ei näy mihinkään, mutta sillä on yhä enemmän merkitystä.