Wnioski z ataków wykorzystujących ostatnią lukę bezpieczeństwa w WordPressie

Ataki

Ostatnie dwa tygodnie były dla mnie dość pracowite, tak więc tylko kątem oka przyglądałem się temu, co działo się wokół krytycznej luki bezpieczeństwa w WordPressie 4.7 i 4.7.1. Zawierająca poprawkę błędu wersja 4.7.2 została wydana 26 stycznia, o czym wspomniałem na Facebooku i uznałem temat za zamknięty. Nie znalazłem niestety czasu na dokładniejsze opisanie tej podatności, a szkoda, bo luka jest nie tylko bardzo poważna, ale również nietypowa, a wykorzystujące ją zmasowane ataki, które rozpoczęły się na początku lutego, trwają do dzisiaj.

Zgłębiając temat doszedłem do kilku wniosków, którymi chciałbym się z wami podzielić.

Co to w ogóle za luka i dlaczego jest taka groźna?

WordPress 4.7.2 zawierał poprawki czterech błędów związanych z bezpieczeństwem. Najpoważniejszym z nich był błąd związany z uprawnieniami w REST API.

REST API to interfejs, nad którym twórcy WordPressa pracowali od dawna i który nazywany jest często „przyszłością WordPressa” (z czym jako wielki fan tego rozwiązania muszę się zgodzić). „Infrastrukturę” dla REST API, czyli możliwość tworzenia własnych interfejsów, wprowadzono już w wersji 4.4, ale dopiero wersja 4.7 przyniosła gotowe interfejsy dla wszystkich danych. Oznacza to, że za pośrednictwem REST API można teraz odczytywać i (co ważne) zapisywać wszystkie informacje dostępne w panelu administracyjnym.

Oczywiście do modyfikacji danych potrzebujemy odpowiednich uprawnień (nie każdy użytkownik może to przecież robić). Odkryty błąd pozwalał na modyfikację treści wpisów bez konieczności autoryzacji – czyli mógł to zrobić każdy. Na dodatek z technicznego punktu widzenia wykorzystanie tej luki jest trywialne, w związku z czym niedługo po podaniu informacji na temat błędu do publicznej wiadomości dostępne już były gotowe narzędzia do atakowania stron opartych na dziurawych wersjach WordPressa (4.7 i 4.7.1), a pierwsze poważne ataki rozpoczęły się w mniej niż 48 godzin po publikacji.

Nietypowość tego ataku polega na tym, że w jego efekcie nie są modyfikowane żadne pliki, a większość skanerów wykrywa infekcje na podstawie zmian w plikach. Dodatkowo atak ten jest możliwy do przeprowadzenia nawet w serwisach, w których całkowicie uniemożliwiono modyfikację plików.

Rodzaje i skala ataku

Skala ataków wykorzystujących opisaną wyżej lukę nie jest wbrew pozorom jakaś gigantyczna. W większości przypadków zadziałał wbudowany w WordPressa mechanizm automatycznych aktualizacji, który samoczynnie (bez konieczności interakcji ze strony administratora) instaluje kolejne uaktualnienia w ramach wersji głównej (czyli na przykład z 4.7.1 do 4.7.2). Dlaczego ten mechanizm nie zadziałał wszędzie? O tym za chwilę.

Jeśli natomiast chodzi o rodzaje ataków, to (jak wynika z tego opracowania) większość z nich ma na celu po prostu zniszczenie atakowanej strony przez podmienienie jej oryginalnej treści. Problem w tym, że prawdopobnie już trwają bardziej dyskretne ataki, których celem może być na przykład wstrzykiwanie do treści atakowanych stron linków pozycjonujących – tego typu „infekcje” potrafią pozostać niezauważone przez całe miesiące, przynosząc atakującym wymierne korzyści materialne (a nie tylko dziwnie pojmowany rozgłos).

Warto też dodać, że część atakujących próbuje wykorzystać wtyczki Insert PHP lub Exec-PHP, które pozwalają na wykonywanie wstawionego do treści wpisów kodu PHP, co daje atakującemu ogromne wręcz możliwości.

Co z mechanizmem automatycznych aktualizacji?

Wspomniany wcześniej mechanizm automatycznych aktualizacji z całą pewnością zminimalizował skalę ataków. Pojawia się jednak pytanie, co ze stronami, na których on nie zadziałał? Mówimy w końcu o dziesiątkach tysięcy zainfekowanych serwisów!

W większości przypadków winni są właściciele tych stron. Sam widziałem wiele serwisów, których administratorzy celowo wyłączali automatyczne aktualizacje z obawy, że „coś się może popsuć”. O ile takie działanie można jeszcze wytłumaczyć niewiedzą, o tyle wyłączanie automatycznych aktualizacji przez osoby tworzące strony dla klientów jest po prostu niedopuszczalne (a z takimi przypadkami również się spotkałem).

Oczywiście istnieją też na pewno przypadki, w których mechanizm aktualizacji nie zadziałał z przyczyn technicznych, takich jak konfiguracja serwera czy problem z uprawnieniami. Wciąż jednak wina leży po stronie właścicieli stron, do których wysyłane są wiadomości o problemach z wykonaniem uaktualnienia.

Odchodząc na chwilę od tematu wpisu: regularnie na różnych grupach czy forach czytam wypowiedzi ludzi, którzy nie aktualizują WordPressa i wtyczek, bo się boją, że „coś zepsują”. Naprawdę nie rozumiem, dlaczego takie osoby nie wykonają kopii bezpieczeństwa i nie spróbują po prostu kliknąć przycisku „Aktualizuj” – w razie niepowodzenia w ciągu kilkunastu minut można przywrócić stronę do stanu sprzed nieudanej aktualizacji. A jeśli tak bardzo się boją, to dlaczego nie poproszą o pomoc kogoś, kto nie będzie bał się dbać o bezpieczeństwo ich strony?

Ze stroną internetową jest trochę jak z samochodem. Trzeba go regularnie serwisować, bo jeśli nie będziemy tego robić, to prędzej czy później odmówi posłuszeństwa. A jeśli nie potrafimy sami zadbać o swój samochód, to przekazujemy go raz na jakiś czas w ręce fachowca, który dokona przeglądu i zrobi co trzeba.

Dla WordPressa to wizerunkowa klapa

WordPress nigdy nie miał dobrej opinii wśród programistów. Od zawsze wytykano mu kiepsko napisany, przestarzały kod, złe podejście do tworzenia nowych lub przepisywania istniejących kawałków kodu czy kulawy proces rozwoju. I ten błąd tylko umocni wszystkie krytyczne głosy.

Bo tak naprawdę winni tej sytuacji są tylko i wyłącznie osoby pracujące nad rozwojem WordPressa. Nie ludzie, którzy nie aktualizują swoich stron, ale osoby, które napisały wadliwy kod i osoby, które udawały, że go testują. Prace nad REST API rozpoczęły się na początku 2013 roku – czy naprawdę przez cztery lata nie można było zrobić tego dobrze?

Dużym błędem było domyślne włączenie interfejsu REST API. To funkcja, której tak naprawdę potrzebuje niewielki procent użytkowników WordPressa, tak więc zdecydowanie powinna być ona domyślnie wyłączona. Aby samodzielnie wyłączyć REST API trzeba zainstalować dodatkową wtyczkę lub skorzystać z kawałka gotowego kodu – nie tak to powinno wyglądać. Oczywiście gdyby domyślnie funkcja ta była nieaktywna, to opisywanego tutaj problemu prawdopodobnie w ogóle by nie było.

Dla jasności dodam, że nie uważam tego typu błędów za powód do zmiany CMSa, bo oprogramowanie bez błędów nie istnieje, a u konkurencji wcale nie jest lepiej. Uważam jednak, że w tym konkretnym przypadku problemu dało się uniknąć i osobom pracującym bezpośrednio przy rozwoju WordPressa należy się za to żółta kartka.

Bezpośredni link

  • superstrona

    Mały odnośnik do fragmentu o (nie)aktualizowaniu WP – też sporo miałem i mam czasami do czynienia z takimi osobami i serwisami, gdzie aktualizacje „wiszą” nieraz całymi miesiącami z obawy o to, że coś się rozsypie. Uświadamianie takich osobników o konieczności aktualizacji czasami przypomina mi postać Smerfa Marudy – nie cierpię aktualizować i koniec kropka! A jak w końcu coś sie wysypie? Nie cierpię tego WP bo się wysypał! Zawsze coś lub ktoś inny jest winny, są setki powodów i wyjaśnień dlaczego tak akurat musiało być – bardzo rzadko za to słychać głos samokrytyki i przyznania sie do błędu lub niewiedzy. Kiedy widzę na forach, że ktoś zaczyna od „jestem totalnie zielony, postawiłem swojego pierwszego wordpressa” to już podskórnie czuję i wiem, że za chwile skończy z milionem dziwnych, dawno nieaktualizowanych wtyczek i przestarzałą wersją WP. A stąd już tylko mały krok do katastrofy i blagalnego płaczu „magicy od WP, ratujcie!” A przecież wcale nie trzeba być magikiem, wystarczy solidnie się przygotować i nie bać pytań oraz związanych z tym głosów krytyki 😊

  • Ciężkie czasy nastały – 1 luka mijają 48h i każdy początkujący hacker może wykorzystać taką lukę dla zabawy….

  • Mały błąd i już więcej od 1,5 mln włamań :)

  • Moim zdaniem nie powinniśmy tak bardzo obwiniać WordPressa za taki stan rzeczy. Jest to tak rozbudowany skrypt, że przetestowanie zmian zajęłoby bardzo dużo czasu, co bardzo opóźniłoby wdrażanie nowych funkcji. Nie oczekujcie, że darmowy skrypt będzie mieć taką jakość kodu jak komercyjne rozwiązania, gdzie zmiany wychodzą znacznie rzadziej, a i tak zdarzają się błędy.

    Często w pracy spotykam się ze stronami firmowym opartymi o Wordpressa. Wiele z nich opartych jest na nieznacznie przerobionych szablonach standardowych, zatem szansa na ich uszkodzenie przez aktualizacje jest naprawdę marginalna. Dlatego też nie rozumiem takie opieszałości w aktualizacji, szczególnie w przypadku stron firmowych, gdzie niezałatana strona szybko może paść ofiarą botów. Później kończy się to odwirusowaniem i luką w działaniu serwisu, przez co firma traci reputacje oraz potencjalnych klientów. A przecież powiadomienie przychodzi na e-mail :)

    • I sądzisz, że wprowadza się zmiany bez ich testowania, żeby zaoszczędzić trochę czasu? ;) Na szczęście się mylisz. Poza tym właśnie w celu wyeliminowania tego typu błędów wprowadzono testy jednostkowe (unit tests), które od jakiegoś czasu są tworzone dla WordPressa. A REST API jako nowy moduł jest nimi objęty, tak więc najwyraźniej coś poszło nie tak.

      Mylisz się również co do jakości kodu. Otwarte rozwiązania mają najczęściej znacznie lepszy kod niż rozwiązania zamknięte (komercyjne), głównie dlatego, że każdy może do tego kodu zajrzeć, sprawdzić go, poprawić czy po prostu skrytykować. Zresztą na ten temat napisano już wiele i nie chce mi się powtarzać argumentów przemawiających na korzyść otwartego oprograwowania – jeśli temat Cię interesuje, to poszukaj w Google. ;)

      Motywy nie mają nic wspólnego z aktualizowaniem WordPressa, bo podczas aktualizacji nie są w ogóle dotykane.

    • iOoOi

      powiem tak, ja wole mieć bezpieczniejszy core CMS, niż zabawki i funkcjonalności bez których jakoś dało się żyć.

  • siwybob

    Czyli w wersji 4.7.2 REST API jest domyślnie wyłączone? Z drugiej strony jak można to sprawdzić? Jak teraz je włączać i wylączać (https://wpzen.pl/nie-uzywasz-rest-api-to-go-wylacz/)

  • iOoOi

    Bartosz planujesz może recenzje książki „WordPress i joomla – zabezpieczanie i ratowanie stron WW” wyd. Helion – tak, to jest nowość

  • Marek

    Moim zdaniem blokowanie aktualizacji automatycznych jest jak najbardziej dopuszczalne i w wielu wypadkach zalecane. Systematyczne i zaplanowane aktualizacje powinien wykonywać pracownik, który ma odpowiednią wiedzę, zrobi pełne kopie bezpieczeństwa przed i po aktualizacji, sprawdzi spójność danych, przetestuje działanie wszystkich elementów funkcjonalnych witryny. Planowanie aktualizacji jest bardzo ważne. Nie ma nic gorszego jak niezależne od nas wymuszenie działania np. w piątek po południu.

    • Masz sporo racji, ale… ;)

      Przede wszystkim kopia bezpieczeństwa powinna być tworzona automatycznie i powinna być zawsze w takim stanie, aby dało się z niej odtworzyć ostatnią wersję strony (pisałem o tym nieco szerzej: https://wpzen.pl/jak-prawidlowo-robic-kopie-bezpieczenstwa/ ). Oczywiście przed aktualizacją warto zrobić dodatkową kopię, ale i tak powinniśmy być w stanie odtworzyć stronę z ostatniej zrobionej automatycznie kopii.

      Aktualizacje, o których mówimy, to aktualizacje w ramach wersji głównej – zawierają one tylko poprawki błędów i nie wprowadzają nowych funkcji ani żadnych poważniejszych zmian. Dlatego też ryzyko, że po takiej aktualizacji coś przestanie działać, jest naprawdę minimalne. Sprawdzanie spójności danych nie ma tu żadnego sensu, bo baza danych nie jest najczęściej w ogóle dotykana.

      Podsumowując: ryzyko ataku z wykorzystaniem luki w nieaktualnej wersji WordPressa jest znacznie wyższe niż ryzyko wystąpienia problemów po automatycznej aktualizacji.