Chodzi mi o ten temat: Apache Foundation Hit by Targeted XSS Attack. Warto przyjrzeć się jak ten atak wyglądał i dlaczego zakończył się powodzeniem.
Uczmy się na błędach: apache.org incident report
Kilka elementów układanki
W większości przypadków udane włamanie nie wynika z jednego błędu, ale z udanego połączenia kilku sprzyjających atakującemu sytuacji. Tak było również i w tym przypadku, poniżej kilka istotnych, moim zdaniem, punktów. Warto przyjrzeć się im, jak również dokładniejszemu opisowi tego incydentu dostępnemu pod adresem https://blogs.apache.org/infra/entry/apache_org_04_09_2010. Trzeba uczyć się na błędach, najlepiej tych cudzych.
Skracanie URLi jest ZŁE i nie tylko
Wszystko zaczęło się od stworzenia wpisu w JIRA, który zawierał następującą treść:
ive got this error while browsing some projects in jira http://tinyurl.com/XXXXXXXXX [obscured]
Łatwo się domyślić, że w "oryginalnej wersji" tego URL zaszyty był payload wykorzystujący podatność XSS, przy czym XSS ten był typu reflected. We wpisie Scenariusze wykorzystania Cross-Site Scripting przedstawiłem właśnie taki scenariusz dla wykorzystania reflected xss.
Przy okazji warto zwrócić uwagę, że miejsce umieszczenia tego linka skłaniało w sposób naturalny innych użytkowników do kliknięcie w niego. Ktoś przecież zgłasza błąd, którego szczegóły pokazał pod tym adresem, więc szybki click i... Można przy okazji zastanawiać się jakie znaczenie dla uśpienia czujności użytkowników miał fakt, że wpis ten znalazł się w systemie śledzenia błędów znanej Apache Foundation, a nie na forum domorosłych hakerów czy innej mniej "zaufanej" stronie.
Użycie mechanizmu skracania linków nie było tu kluczowym elementem ataku, nie mogłem sobie jednak odmówić przyjemności wspomnienia o tym (patrz: Skracanie linków jest ZŁE!).
Brak ochrony cookie sesyjnego
Flaga httpOnly nie jest remedium wszystkich problemów związanych z XSS. Jest jednak dość skutecznym środkiem ograniczającym skutki wystąpienia podatności tego typu, w szczególności uniemożliwia dostęp do oznaczonych nią cookies przez JavaScript, a więc również przez wstrzyknięty payload.
Oczywiście są przypadki, w których mechanizm ten nie jest skuteczny. Moim ulubionym przykładem jest uporczywe ustawianie tego samego cookie sesyjnego przy każdym żądaniu klienta. Jak w takim przypadku dostać się do cookie? Wystarczy skorzystać z XMLHttpRequest i odczytać zwrócone przez serwer nagłówki.
Dodam jeszcze, że weryfikacja ochrony identyfikatora sesji, czyli sprawdzenie flag Secure oraz httpOnly jest jednym ze standardowych elementów testów mechanizmu uwierzytelnienia oraz zarządzania sesją.
Przy okazji warto zwrócić uwagę na jeden fakt: How do you configure HttpOnly cookies in tomcat / java webapps?. Cytuję:
httpOnly is supported as of Tomcat 6.0.19 and Tomcat 5.5.28.
Właśnie z tego powodu całkiem spora ilość wdrożeń aplikacji J2EE jest bardziej podatna na przejęcie sesji.
Praca ze zbyt dużymi uprawnieniami
Znów fragment ze szczegółów tego incydentu:
When this issue was opened against the Infrastructure team, several of our administators clicked on the link. This compromised their sessions, including their JIRA administrator rights.
Można się zastanawiać, czy nie lepszym rozwiązaniem byłoby użycie dwóch różnych kont: jednego zwykłego do normalnej pracy z JIRA, a drugiego administracyjnego do zadań administracyjnych właśnie. Nie znam tego rozwiązania na tyle dobrze, by stwierdzić, czy taka separacja uprawnień była możliwa, w szczególności czy była używalna (czy po jej zastosowaniu użytkownicy nadal mogliby wykonywać swoje zadania w sposób efektywny).
Alternatywnym sposobem rozwiązania problemu (obsłużenia zdarzenia "przejęcie sesji") może być wymaganie ponownego uwierzytelnienia przy wykonaniu określonych operacji, w tym wypadku - operacji administracyjnych. Oczywiście ten mechanizm na niewiele się zda w przypadku, w którym atakujący zna hasło użytkownika, ale wówczas nie mówimy już o przejęciu sesji.
Podatność na zgadywanie haseł
Równolegle z oczekiwaniem na rezultaty ataku XSS, prowadzone były również "aktywne" próby zdobycia hasła:
At the same time as the XSS attack, the attackers started a brute force attack against the JIRA login.jsp, attempting hundreds of thousands of password combinations.
W zasadzie nie wiadomo, która z prób zdobycia hasła/przejęcia sesji zakończyła się sukcesem, przynajmniej dla mnie nie jest to jasne:
On April 6th, one of these methods was successful. (...)
Skuteczność ataku XSS mogła zostać obniżona poprzez dodanie flagi httpOnly, w przypadku zgadywania haseł również można było zastosować dodatkowe zabezpieczenia:
- odpowiednia polityka haseł,
- blokowanie kont lub mechanizm opóźnień w przypadku błędnej próby logowania (patrz: O implementowaniu haseł oraz Lekcja 11: Przykład opóźnienia w trakcie logowania),
W^X
Kolejny krok był również ciekawy:
Having gained administrator privileges on a JIRA account, the attackers used this account to disable notifications for a project, and to change the path used to upload attachments. The path they chose was configured to run JSP files, and was writable by the JIRA user.
Tak, W^X powinien kojarzyć się z OpenBSD, ale dobrze wpisuje się w ten przypadek. Problem polegał na tym, że atakujący mogli przekazać na serwer (w tym wypadku - jako załączniki do zgłoszeń) pliki "wykonywalne". W tym wypadku chodziło o pliki JSP, po prostu konfiguracja serwera była taka, że plik JSP umieszczony w tej ścieżce był interpretowany (wykonywany). Uzyskano w ten sposób możliwość uruchomienia kodu na atakowanym serwerze.
Czy można było bronić się przed tego typu akcją? Trudno powiedzieć, na tym etapie atakujący posiadali już uprawnienia administracyjne w JIRA. Można jednak próbować tak konfigurować serwer, by interpretowane/wykonywane były pliki wyłącznie w kilku katalogach, tych niezbędnych do działania aplikacji. Do katalogów tych użytkownik nie powinien mieć zapisu (w domyśle - również ten użytkownik, w którego kontekście działa aplikacja). We wszystkich innych miejscach, w szczególności tych, do których użytkownik (a więc i potencjalny atakujący) może pisać, interpretowanie/wykonywanie plików powinno być wyłączone. Czyli właśnie W^X (write-or-execute).
Jedno hasło...
Tak, taki typowy błąd. Najpierw wprowadzenie:
By the morning of April 9th, the attackers had installed a JAR file that would collect all passwords on login and save them. They then sent password reset mails from JIRA to members of the Apache Infrastructure team. These team members, thinking that JIRA had encountered an innocent bug, logged in using the temporary password sent in the mail, then changed the passwords on their accounts back to their usual passwords.
A teraz gwóźdź programu:
One of these passwords happened to be the same as the password to a local user account on brutus.apache.org, and this local user account had full sudo access. The attackers were thereby able to login to brutus.apache.org, and gain full root access to the machine.
Czy trzeba lepszego przykładu, który dobitniej pokaże, że posiadanie jednego hasła do różnych usług to ZŁY pomysł?
Jakiś czas temu na Niebezpieczniku pojawił się wpis Jeden 0day na WordPressa i leżymy! Co do zasady muszę się zgodzić z prezentowanym w tym wpisie stanowiskiem, ale... No właśnie, czy tak musi być?Dziś pojawiła się informacja o dość istotnym błędzie w Ser
Przesłany: Dec 22, 22:46
Ciekawa lektura: Anonymous speaks: the inside story of the HBGary hack. Warto przeczytać i zobaczyć jak wiele "małych" błędów prowadzi do całkiem sporej wtopy. A błędy były proste i typowe: wykorzystanie "autorskiego", podatnego na SQL injection CMS (a
Przesłany: Feb 21, 07:30