V tomto článku bych chtěl poskytnou podrobnější informace o chybě a jejich dopadech, aby si každý mohl udělat obrázek, jak moc závažná pro něj je.
Chybu nalezneme v souboru wp-includes/pluggable.php ve funkci wp_mail:
if ( !isset( $from_email ) ) {
// Get the site domain and get rid of www.
$sitename = strtolower( $_SERVER['SERVER_NAME'] );
if ( substr( $sitename, 0, 4 ) == 'www.' ) {
$sitename = substr( $sitename, 4 );
}
$from_email = 'wordpress@' . $sitename;
}
Je zde vytvářena adresa odesílatele a využívá pro to proměnnou serveru SERVER_NAME. A to je jádro problému. Tuto proměnnou totiž v určitých případech může útočník ovlivnit - konkrétně je to v případě, že se jedná o defaultní (nebo jediný) web serveru, který je zobrazen například i v případě, že na server přistoupíme otevřením jeho IP v prohlížeči. Jsou ohroženy především ty webové servery, které proměnou SERVER_NAME naplňují ve výchozí konfiguraci hodnotou z HTTP hlavičky Host - jedná se například o Apache a IIS. Pokud se útok podaří, tak za doménu webu je možné dosadit útočníkem kontrolovanou doménu - mail se tak bude tvářit, že odešel z adresy wordpress@utocnikova.domena (v hlavičce From:). V tom na první pohled není žádný problém. Pokud by se však útočníkovi podařilo odstavit schránku uživatele a donutit tak server zaslat nedoručenku, tak zpráva s odkazem pro reset hesla dorazí do schránky útočníka a on tak může získat kompletní kontrolu na webovou stránkou.
Je vůbec reálné mailovou schránku odstavit? Možností je několik a ta nejjednodušší je zaplnit ji maily s velkými přílohami. Změnou adresy odesílatele také přicházejí antispamové kontroly zfalšované domény a lze tak donutit cílový server myslet si, že se jedná o spam a pokusit se ho vrátit - většinou je takový mail však zahozen, určitě nalezneme servery, které jej vrátí - to si útočník nejprve určitě vyzkouší. Do úvahy přichází i DDoS útok, ale v tomto případě by se jednalo o technickou chybu a odesílající server by zprávu několik dní zkoušel opětovně doručit - útok by tak musel trvat déle než několik dní (typicky 5) a to by se snad neobešlo bez pozornosti uživatelů a administrátorů. Důvod vrácení zprávy může být však i mnohem jednodušší - stačí nastavená automatická odpověď při dovolené, která vrací v kopii i původní zprávu.
Ke zneužití formuláře pro reset hesla je nutné tedy znát přihlašovací jméno uživatele a pokud chce útočník aktivně zaútočit na jeho mailovou schránku, tak musí znát i jeho mailovou adresu. Oba tyto údaje je však vcelku jednoduché získat - WordPress v základním nastavení ochotně sdělí uživatelská jména navštívením adresy ?author=1 a testem dalších ID uživatelů. Mailovou adresu mohu na mnoha webech naleznout v kontaktech a u novějších verzí WP lze využít REST-API - to nám v případě použití služby Gravatar pro uživatelské avatary (defaultní chování) prozradí MD5 hashe uživatelských jmen. MD5 je dnes již velmi slabý hash a není problém z něj e-mail vydolovat do několika hodin zkoušením na moderní grafické kartě.
Pořád se může zdát, že možnost zneužití je díky komplikaci s odstavením schránky obtížná až nemožná. Je třeba se však oprostit od osobního pohledu s představou vlastního webu, kterého se problém možná netýká, a podívat se na problém z globální perspektivy. Rozšířenost WP je ohromná - běží na něm více než čtvrtina všech webů, mnoho z nich jsou však již dávno opuštěné stránky a e-maily jejich původních autorů již dávno nemusí fungovat a tak je možnost odmítnutí mailu s resetem hesla mnohem pravděpodobnější. Takto získané weby lze použít k dalším nekalým činnostem.
Probrali jsme tedy čím je chyba způsobená, jaké má následky a nyní se podívejme na možnosti obrany, pokud by váš server mohl být touto chybou postižen.
Obrana je možná z několika stran - jak ze strany WP samotného, tak konfiguračně.
- Apache lze jednoduše přemluvit, aby jako SERVER_NAME používal ServerName virtuálního serveru a ne to co dostane v hlavičce Host, k tomu slouží konfigurační direktiva UseCanonicalName On,
- Pokud nemáte k možnost měnit nastavení serveru, je možné problému zabránit přesměrováním v .htaccess v případě, že klient nekomunikuje s nastavenou doménou:
RewriteCond %{HTTP_HOST} !=www.vas.web
]
RewriteRule ^/?(.*)$ https://www.vas.web/$1 [R=301,L - Je k dipozici patch jádra WP, který adresu netvoří zpětné adresy z proměnné SERVER_NAME, ale nakonfigurované domény webu (toto řešení je podle mě správné a doufám, že se brzo dostane do jádra),
- Adresu odesílatele můžete přenastavit například pomocí pluginu - lze to například pomocí mého fixátoru Reply-To hlavičky, kterou WP standardně nenastavuje a maily tak mohou padat do spamu - pro nastavení vlastní adresy stačí odkomentovat a upravit příslušný řádek. Problém může odstranit i použití vlastního SMTP serveru. Touto úpravou vyřešíte problém nezávisle na typu webserveru.
Webový server Nginx zranitelný není. Proměnná SERVER_NAME je nastavována v konfiguraci fastcgi (typicky v souboru fastcgi_params) - ve výchozím nastavení proměnné předává adresu udanou v server_name daného virtual hostu:
fastcgi_param SERVER_NAME $server_name;
O tomto problému jsem se zmínil na přednášce na WordCamp Brno.
WordCamp Brno 2017 - rychlý a bezpečný web , autor Vladimír Smitka
Pojďme si na závěr shrnout, nejdůležitější body, kdy je možné zranitelnost zneužít:
- webová stránka s WP je nastavena jako defaultní, případně je jediná na serveru - nejčastěji se to děje u VPS nebo vlastních serverů,
- používáte Apache nebo IIS,
- využíváte základní nastavení mailů ve WP,
- váš mailový server vrací kopii původní zprávy v nedoručence (většinou zprávy od MAILER-DAEMON), nebo v automatické odpovědi při nepřítomnosti,
- útočníkovi se podaří donutit váš mailový server, aby zprávu vrátil.
Podmínky pro zneužití jsou velmi komplexní a útočník by zřejmě musel být velmi motivovaný, aby ji využil. Pravděpodobnost, že chyba postihne přímo vás je tak vcelku nízká, ale i tak si myslím že je dobré o ní vědět.