Praktické rady na zabezpečení redakčního systému WordPress

27. února 2023

Jako administrátor webhostingových serverů se každý den potkávám s útoky na WordPress. Aktuálně blokujeme zhruba 300 útoků za den pomocí automatické detekce. Díky analýze chování útočníků můžu předat pár praktických rad, na co je potřeba se podívat ohledně zabezpečení.

Přihlášení

Přihlášení do WordPress se provádí pomocí skriptu wp-login.php. Tento skript je jedním z nejčastějších cílů útoku. V logu serveru to vypadá nějak takhle:

ore******67.cz 185.119.81.101 - - [24/Feb/2023:15:03:28 +0100] "GET /wp-login.php HTTP/2.0" 200 2184 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"

ore******67.cz 185.119.81.101 - - [24/Feb/2023:15:03:29 +0100] "POST /wp-login.php HTTP/2.0" 200 2343 "https://www.ore******67.cz/wp-login.php" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"


ore******67.cz 185.119.81.103 - - [24/Feb/2023:15:11:10 +0100] "GET /wp-login.php HTTP/2.0" 200 2184 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"


ore******67.cz 185.119.81.103 - - [24/Feb/2023:15:11:10 +0100] "POST /wp-login.php HTTP/2.0" 200 2340 "https://www.ore******67.cz/wp-login.php" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"


ore******67.cz 185.119.81.103 - - [24/Feb/2023:15:20:13 +0100] "GET /wp-login.php HTTP/2.0" 200 2184 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"


ore******67.cz 185.119.81.103 - - [24/Feb/2023:15:20:13 +0100] "POST /wp-login.php HTTP/2.0" 200 2340 "https://www.ore******67.cz/wp-login.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"

Takže co se s tím dá dělat? Na úrovni webového serveru máme možnost povolit přístup jen z konkrétních IP nebo sítí, a dále také možnost požadovat heslo pro přístup ke konkrétnímu prostředku. Další možností je použít nějaký plugin, např. velmi oblíbený Limit Login Attempts Reloaded.

XML-RPC API

XML-RPC API je ve WordPress zprostředkováno pomocí skriptu xmlrpc.php. Toto API je nejčastějším cílem útoků na WordPress. Způsob jak je tento soubor zneužíván je velmi pěkně popsán na blogu Lucian Nitescu.

V logu to vypadá nějak takhle:

ten*****ti.cz 62.102.148.130 - - [24/Feb/2023:15:14:24 +0100] "POST /xmlrpc.php HTTP/1.1" 200 416 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
tl****ne.com 62.102.148.130 - - [24/Feb/2023:15:14:37 +0100] "POST /xmlrpc.php HTTP/1.1" 200 403 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
ke*****ka.cz 62.102.148.130 - - [24/Feb/2023:15:16:26 +0100] "POST /xmlrpc.php HTTP/1.1" 200 416 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
jo***r.cz 62.102.148.130 - - [24/Feb/2023:15:16:33 +0100] "POST /xmlrpc.php HTTP/2.0" 200 416 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
a**p.cz 62.102.148.130 - - [24/Feb/2023:15:17:50 +0100] "POST /xmlrpc.php HTTP/2.0" 200 416 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
pa****ek.cz 62.102.148.130 - - [24/Feb/2023:15:21:52 +0100] "POST /xmlrpc.php HTTP/2.0" 200 416 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
e**m.cz 62.102.148.158 - - [24/Feb/2023:15:53:19 +0100] "POST /xmlrpc.php HTTP/2.0" 200 416 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
pa****ek.cz 62.102.148.158 - - [24/Feb/2023:15:53:38 +0100] "POST /xmlrpc.php HTTP/2.0" 200 416 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
dv********ais.cz 62.102.148.158 - - [24/Feb/2023:15:53:52 +0100] "POST /xmlrpc.php HTTP/2.0" 200 416 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"

Takže pokud nepoužíváte nějakou aplikaci pro správu WordPress nebo plugin, který XML-RPC API využívá, doporučuji toto API vypnout. V žádném případě soubor xmlrpc.php nemažte. Vypnout toto API můžete pomocí zakázání přístupu na úrovni webového serveru, nebo např. pomocí pluginu Disable XML-RPC-API.

Komentáře

Dalším oblíbeným útokem na WordPress je komentářový spam. Pokud v administraci WordPress nevypnete možnost přidávání komentářů tak si Vaši prezentaci najde nějaký robot a začne Vám přidávat ke článkům komentáře. Většinou se jedná o nějaké affiliate linky na zábavu pro dospělé, ale i reklamu na nejrůznější produkty.

Komentářový spam je problém i v okamžiku, kdy máte nastavené, že každý komentář musíte schválit. Komentáře čekající na schválení se ukládají do databáze a ta roste a roste. Roboti většinou nejsou moc aktivní, stačí pár komentářů za hodinu.

V logu to pak vypadá nějak takhle:

a**u.cz 5.188.210.84 - - [12/Feb/2023:10:42:24 +0100] "POST /wp-comments-post.php HTTP/1.0" 302 - "https://www.a**u.cz/news/me**************************aly/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.46" **0/195297**
a**u.cz 5.188.210.80 - - [12/Feb/2023:10:46:44 +0100] "POST /wp-comments-post.php HTTP/1.0" 302 - "https://www.a**u.cz/news/me**************************aly/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36" **0/167307**
a**u.cz 5.188.210.21 - - [12/Feb/2023:10:57:17 +0100] "POST /wp-comments-post.php HTTP/1.0" 302 - "https://www.a**u.cz/news/me**************************aly/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.49" **0/160449**
a**u.cz 5.188.210.84 - - [12/Feb/2023:11:01:27 +0100] "POST /wp-comments-post.php HTTP/1.0" 302 - "https://www.a**u.cz/news/vir*************************tugal-2/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" **0/168997**
a**u.cz 5.188.210.91 - - [12/Feb/2023:11:02:06 +0100] "POST /wp-comments-post.php HTTP/1.0" 302 - "https://www.a**u.cz/news/me**************************aly/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.46" **0/188616**
a**u.cz 5.188.210.84 - - [12/Feb/2023:11:02:36 +0100] "POST /wp-comments-post.php HTTP/1.0" 302 - "https://www.a**u.cz/news/vir*************************tugal-2/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" **0/164978**
a**u.cz 5.188.210.30 - - [12/Feb/2023:11:09:06 +0100] "POST /wp-comments-post.php HTTP/1.0" 302 - "https://www.a**u.cz/news/me**************************aly/" "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.46" **0/180875**
a**u.cz 5.188.210.80 - - [12/Feb/2023:11:13:17 +0100] "POST /wp-comments-post.php HTTP/1.0" 302 - "https://www.a**u.cz/news/vir*************************tugal-2/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36" **0/155826**
a**u.cz 5.188.210.93 - - [12/Feb/2023:11:40:19 +0100] "POST /wp-comments-post.php HTTP/1.0" 302 - "https://www.a**u.cz/news/me**************************aly/" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36" **0/167796**

Co se s tím dá dělat je popsané například na stránkách codex.wordpress.org.

JSON REST API

REST API je jako všechno dobrý sluha, ale zlý pán.  Stejně jako v případě XML-RPC API i tohle je zneužíváno k útokům. Pokud nepoužíváte nějaké pluginy, které ho vyžadují, doporučuji ho vypnout. Nejjednodušší postup je na popsán na webu wpbeginner.com.

Nejčastěji je JSON REST API zneužíváno k nalezení uživatelského jména pomocí tzv. enumerace uživatelských účtů. Pokud Vás to zajímá blíže, doporučuji skvělý článek na book.hacktricks.xyz.

Vyhledávání

Další oblíbený útok je DDoS útok na vyhledávání. Zpravidla vede k nedostupnosti prezentace a často i k pádu systému.

V logu to vypadá např. takhle:

ai****e.cz 103.107.197.3 - - [27/Apr/2022:01:21:36 +0200] "GET /ru/?s=%D0%9D%D0%B5+%D0%B2%D1%80%D0%B5%D0%BC%D1%8F+%D1%83%D0%BC%D0%B8%D1%80%D0%B0%D1%82%D1%8C+%D1%81%D0%BC%D0%BE%D1%82%D1%80%D0%B5%D1%82%D1%8C+%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD+frameanalytics.com%2Fblog.html HTTP/1.1" 200 10692 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/62BFE7"
ai****e.cz 103.107.197.3 - - [27/Apr/2022:01:21:39 +0200] "GET /ru/?s=%D0%9D%D0%B5+%D0%B2%D1%80%D0%B5%D0%BC%D1%8F+%D1%83%D0%BC%D0%B8%D1%80%D0%B0%D1%82%D1%8C+%D1%81%D0%BC%D0%BE%D1%82%D1%80%D0%B5%D1%82%D1%8C+%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD+frameanalytics.com%2Fblog.html HTTP/1.1" 200 10692 "https://ai****e.cz/ru/?s=%D0%9D%D0%B5+%D0%B2%D1%80%D0%B5%D0%BC%D1%8F+%D1%83%D0%BC%D0%B8%D1%80%D0%B0%D1%82%D1%8C+%D1%81%D0%BC%D0%BE%D1%82%D1%80%D0%B5%D1%82%D1%8C+%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD+frameanalytics.com%2Fblog.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/62BFE7"
ai****e.cz 103.107.197.3 - - [27/Apr/2022:01:21:41 +0200] "GET /ru/?s=%D0%9D%D0%B5+%D0%B2%D1%80%D0%B5%D0%BC%D1%8F+%D1%83%D0%BC%D0%B8%D1%80%D0%B0%D1%82%D1%8C+%D1%81%D0%BC%D0%BE%D1%82%D1%80%D0%B5%D1%82%D1%8C+%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD+frameanalytics.com%2Fblog.html HTTP/1.1" 200 10692 "https://ai****e.cz/ru/?s=%D0%9D%D0%B5+%D0%B2%D1%80%D0%B5%D0%BC%D1%8F+%D1%83%D0%BC%D0%B8%D1%80%D0%B0%D1%82%D1%8C+%D1%81%D0%BC%D0%BE%D1%82%D1%80%D0%B5%D1%82%D1%8C+%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD+frameanalytics.com%2Fblog.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/62BFE7"

Jak se s tím vypořádat je asi nejlépe popsané na wpbeginner.com.

Nepoužívané šablony a pluginy

Po instalaci WordPress většina uživatelů nechá nainstalované neaktivní šablony. Ty sice nic nedělají, ale pořád tam jsou a dá se k nim dostat. Základní zásadou je: nenechávejte v systému nic, co nepoužíváte. I když budete pravidelně aktualizovat celý WordPress včetně šablon, nikdo Vám nikdy nezaručí, že tam není nějaká bezpečnostní díra a že ji někdo nezneužije, nebo v horším případě již nezneužil. Většina zneužitých webů, co jsem měl možnost je prozkoumat, byla aktivně zneužita až několik měsíců po té, co byly napadeny.

Totéž platí i pro pluginy. Pokud to nepoužíváte, pryč s tím.

Aktualizace

WordPress a i systém běžící pod ním neustále prochází vývojem. Zpravidla to znamená vyšší výkon, což se projeví rychlejším načítáním obsahu a tím i lepším zážitkem z procházení webu. Proto je potřeba neustále udržovat systém aktuální. V případě WordPress je potřeba pravidelně aktualizovat jak samotný WordPress, tak pochopitelně i veškeré šablony a pluginy. V případě že si sami nespravujete systém a nemáte možnost vybrat si verzi PHP na kterém WordPress běží, kontaktujte svého poskytovatele a požádejte ho o upgrade PHP na některou z aktuálních verzí.  Sami se můžete podívat, že v době psaní článku většina WordPress běží na komunitou již nepodporované verzi PHP 7.4 – více na oficiálních stránkách WordPressu.

Bezpečnostní hlavičky

I přes to, že máte aktuální WordPress, všechny pluginy a šablonu a celý web Vám běží na aktuálním systému, může se stát, že něco nebude dobře zabezpečeno. Proto existují bezpečnostní hlavičky. Nebudu opakovat, co jsem o tom napsal již dříve v článku CSP hlavičky.

Potřebné hlavičky by měly jít nastavit i např. pomocí tohoto pluginu Headers Security Advanced & HSTS WP.

Cache

Pokud někdo zaútočí na WordPress, tak si musíte uvědomit, že se veškerý obsah generuje z databáze. Bohužel to jsou i stovky dotazů na vygenerování jedné jedinné stránky. Pokud nemáte ve WordPress nainstalován žádný plugin, zajišťující cache databázových dotazů, systém se  složí. Nejnovější verze WordPress naštěstí na tuto skutečnost upozorňují a doporučují využít memcached. Memcached pluginů existuje celá řada, já osobně mám nejraději W3 Total Cache.

Cron

Spouštění plánovaných úloh ve WordPress zajišťuje soubor wp-cron.php. Na hodně navštěvovaných webech, ale i při útoku na web, dojde k tomu, že se tento soubor opakovaně volá a provádí úlohy které mají být provedeny. Např. se zjišťuje dostupnost aktualizací, zasílají se upozornění na nové komentáře atd. I tento jednoduchý skript bývá velmi častou příčinou nedostupnosti služeb, případně i pádu systému.

Doporučuji zakázat výchozí funkcionalitu a spouštět wp-cron.php pomocí cron, nebo nějakého jiného plánovače úloh. Toto nastavení je velmi jednoduché – do souboru wp-config.php přidáte řádek:

define('DISABLE_WP_CRON', true);

Celé je to pěkně popsané v článku na webu lucasrolff.com.

Cizí skripty a .bak soubory

Poslední rada je: Smažte všechno, co do WordPress nepatří.

Například nacházím v hacklých prezentacích prehistorickou verzi Adminer, kterou se dá velmi jednoduše vykrást obsah souboru wp-config.php ve kterém je mj. uloženo připojení k databázi. Popsáno to bylo před lety např. na blogu sucuri.net.

Další aktivně vyhledávanou věcí jsou .bak soubory. Zatím co zavolání wp-config.php nevrátí žádný obsah, wp-config.php.bak vypíše obsah tohoto souboru.

Rovněž se vyhledávají nejrůznější známé názvy záloh databází atd.

V logu to vypadá např. takhle:

ke**o.sk 3.139.56.152 - - [27/Feb/2023:00:51:06 +0100] "HEAD /backup.zip HTTP/1.1" 301 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.75 Safari/537.36" **0/230**
ke**o.sk 3.139.56.152 - - [27/Feb/2023:00:51:08 +0100] "HEAD /backup.zip HTTP/1.1" 404 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.75 Safari/537.36" **0/551**
ke**o.sk 3.139.56.152 - - [27/Feb/2023:00:51:11 +0100] "HEAD /backups.zip HTTP/1.1" 301 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.75 Safari/537.36" **0/174**
ke**o.sk 3.139.56.152 - - [27/Feb/2023:00:51:13 +0100] "HEAD /backups.zip HTTP/1.1" 404 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.75 Safari/537.36" **0/659**
ke**o.sk 3.139.56.152 - - [27/Feb/2023:00:51:54 +0100] "GET /.env.backup HTTP/1.1" 301 294 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" **0/163**
ke**o.sk 3.139.56.152 - - [27/Feb/2023:00:51:55 +0100] "GET /.env.backup HTTP/1.1" 404 958 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" **0/621**

Takže smažte z webu všechno co není součástí WordPress.

Závěr

Věcí co se dají zabezpečit a zlepšit by se našlo daleko víc, ale pokud uděláte tohle všechno, minimalizujete, v lepším případě, riziko, že Váš web nebude dostupný a v nejhorším případě, že Váš web někdo hackne a ukradne citlivé údaje nebo ho zneužije k nějaké trestné činnosti.

Mohlo by vás také zajímat

Nejnovější

1 komentář

  1. Tanamil

    Dub 2, 2024 v 10:55

    Well written, really insightful, and helpful post. Thank you very much for your knowledge. I must admit that it is only due of your clarification of many of my questions that I have learned more about this subject. Continue to publish stuff about WordPress.

    Odpovědět

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *