16.06.2019 | 13:47

Damian Rusinek

Ukradli swoim klientom 13 mln USD, by nie pozwolić na to złodziejowi

Świat kryptowalut kojarzy się z wielomilionowymi kradzieżami z portfeli giełd. Zupełnie inny scenariusz ataku wykorzystał haker, który okradał od kwietnia 2019 roku użytkowników korzystających z portfela Agama firmy Komodo.

Większość ataków związanych z kryptowalutami to ataki socjotechniczne ukierunkowane na osoby, które zarządzają portfelami, w celu uzyskania dostępu do klucza prywatnego (lub kilku kluczy prywatnych), którym te portfele są zabezpieczone. Pikanterii dodaje fakt, że uzyskując dostęp do klucza, atakujący może w jednej chwili wyczyścić (przelać na swój portfel) zawartość portfela ofiary.

Atak na użytkowników portfela Agama wyglądał inaczej. W wyniku analizy źródła ataku stwierdzono, że w zewnętrznej bibliotece, z której korzystała aplikacja portfela, haker umieścił złośliwy kod. Działał on w ten sposób, że podczas uruchamiania portfela i podawania hasła lub seeda, z którego generowany jest klucz prywatny portfela, były one przesyłane na jeden z serwerów Heroku. Sam proces osadzania tego złośliwego kodu okazał się dobrze przemyślany i kilkuetapowy.

Portfele Komodo

Scenariusz ataku

Na początku marca haker opublikował w npm przydatną i w pełni działającą paczkę o nazwie „electron-native-notify”, która – jak sama nazwa wskazuje – służyła do obsługi powiadomień. Biblioteka nie zawierała wtedy jeszcze żadnego złośliwego kodu, więc nie mogła budzić żadnych podejrzeń.

Po kilku dniach użytkownik sawlysawly dodał tę paczkę do zależności aplikacji EasyDEX-GUI, z której z kolei korzysta portfel Agama firmy Komodo.

Następna wersja paczki „electron-native-notify” została opublikowana 15 dni później (23 marca) i była pierwszą wersją zawierającą złośliwy kod, który wykradał hasła i seedy. Wtedy portfel Agama jeszcze z niej nie korzystał. Dopiero 16 kwietnia, gdy wydano wersję 0.3.5 portfela Agama, paczka ze złośliwym kodem została zaktualizowana i haker zaczął zbierać hasła i seedy.

Reakcja Komodo

4 czerwca 2019 roku zespół Komodo otrzymał informację od zespołu bezpieczeństwa npm (node package manager) o złośliwym kodzie występującym w jednej z bibliotek zewnętrznych, z której korzysta portfel Agama.

Pracownicy Komodo musieli szybko zareagować, ponieważ (jak się później okazało) atakujący już zaczął przelewać kryptowaluty z portfeli ofiar.

W przypadku wycieku bazy haseł Komodo mogłoby wymusić na użytkownikach ich zmianę. Jednakże seedy oraz klucze prywatne, które chronią dostępu do portfeli, są generowane na komputerze klienta i nie są w żadnej formie wysyłane na serwer, przez co operator portfela nie ma do nich dostępu oraz nie ma możliwości ich zmiany.

Zespół Komodo nie miał wyboru – jeśli chciał zapobiec kradzieży, musiał zacząć działać tak samo jak złodziej, czyli okradać swoich użytkowników. Rozpoczął się wyścig o pozostałe środki. Szczęśliwie dla Komodo złośliwy kod umieszczał seedy użytkowników na publicznym serwerze, przez co mieli wgląd do wykradzionych danych. Korzystając z tych seedów, zespół Komodo otworzył zaatakowane portfele i przeniósł fundusze do własnego, bezpiecznego portfela.

Pracownikom Komodo udało się przejąć około 8 milionów KMD oraz 96 Bitcoinów, razem wartych obecnie ok. 13 milionów USD. Zgodnie z ich stanowiskiem wszystkie fundusze mają być zwrócone prawowitym właścicielom. Złodziejowi natomiast udało się ukraść ok. 1 miliona KMD (ok. 1,6 mln USD).

Wnioski Komodo

Projekt portfela Agama został zamknięty, a w jego miejsce wstawiono nowy portfel AtomicDEX, który – zgodnie ze stwierdzeniem Komodo – opiera się na nowszych, bardziej zaawansowanych i bezpieczniejszych technologiach.

Ponadto portfel AtomicDEX – zgodnie z tym, co twierdzi zespół Komodo – wykorzystuje tylko takie zależności, które są sprawdzane przez ekspertów ds. bezpieczeństwa. Nowe środowisko oprogramowania i architektura AtomicDEX mają sprawić, że wystąpienie luk w zabezpieczeniach będzie mniej prawdopodobne.

Okradli mi portfel! Co robić?

Zwykle, gdy ktoś uzyska dostęp do seeda lub klucza prywatnego przypisanego do portfela oraz zdąży przesłać kryptowalutę, zanim zrobi to właściciel portfela, środki można uznać za stracone. Wynika to z faktu, że technologia łańcucha bloków (ang. blockchain) posiada własność niezmienności, co znaczy, że zatwierdzona transakcja nie może zostać wycofana lub zmieniona.

Oczywiście istnieje teoretyczna możliwość cofnięcia się w łańcuchu bloków do momentu sprzed kradzieży i ponowne dodawanie bloków do łańcucha od tamtego momentu, jednakże takie rozwiązania zwykle prowadzą do rozłamów społeczności wspierającej daną kryptowalutę (np. rozłam na Ethereum Classic i Ethereum po ataku na DAO), a na pewno nie zostaną wprowadzone, aby ratować garstkę użytkowników platformy.

W tym konkretnym przypadku sytuacja nie była jednak beznadziejna. Złodziej przesyłał seedy na publiczny serwer, aby zatrzeć swoją tożsamość i doprowadzić do sytuacji, w której każdy, kto odczytał seedy na publicznym serwerze, mógłby zostać uznany za podejrzanego. Dlatego zespół Komodo był w stanie wykorzystać ten sam złośliwy kod i odzyskać część środków.

Jeśli byłeś użytkownikiem tego portfela i skradziono Ci środki, należy wypełnić formularz zwrotu utraconych środków dostępny pod adresem: https://docs.google.com/forms/d/e/1FAIpQLSfpBSjHULYN8ZTN_yPnHWOIZT9K6CK8QTxULb6KukUujmmieg/viewform. Co ciekawe, sam proces zwrotu środków jest oparty na blockchainie i składa się z następujących kroków:

  1. Zespół Komodo przesyła niewielką ilość KMD na zaatakowany adres (co już zostało zrealizowane).
  2. Następnie właściciel okradzionego portfela przekazuje te środki na adres zwrotu przesłany w formularzu.
  3. Na koniec zespół Komodo przesyła całą sumę, która była w portfelu (i została uratowana) na adres zwrotu.

Proces zostanie przeprowadzony automatycznie, jeśli dla jednego okradzionego adresu będzie wypełniony tylko jeden formularz zwrotu.

Warto zwrócić uwagę, że ten proces zwrotu środków ma pewną lukę. Jeśli prawowity użytkownik zapomni o swoich środkach albo nie zauważy, że atak został przeprowadzony (np. nie sprawdza salda codziennie), to złodziej może wysłać formularz w jego imieniu. Być może to ryzyko będzie wyeliminowane i zespół Komodo będzie kontaktował się z użytkownikiem przez e-mail albo identyfikator Discord, które ofiara ataku zostawia w formularzu zwrotu uratowanych środków.

Więcej szczegółów dotyczących procesu zwracania środków można znaleźć tutaj: https://support.komodoplatform.com/support/solutions/articles/29000029973-steps-to-reclaim-funds-after-the-agama-incident.

Korzystam z zewnętrznych bibliotek w swoim projekcie. Co robić?

Można zaryzykować stwierdzenie, że prawie wszystkie duże projekty (szczególnie open source) korzystają z zewnętrznych bibliotek, więc zagrożenie opisane w tej historii jest powszechne.

Ochrona przed podatnościami i złośliwym kodem w bibliotekach zewnętrznych powinna być wdrażana wielostopniowo. Na początkowym etapie należy uwzględnić ryzyko pochodzące z zewnętrznych bibliotek w modelowaniu zagrożeń oraz utrzymywać listę zależności wraz z wykorzystywanymi wersjami. W przypadku wielu technologii taka lista jest standardem (np. plik pom.xml dla Javy). Ciekawostka: GitHub umożliwia wygenerowanie grafu zależności, jeśli w repozytorium znajduje się plik w obsługiwanym formacie z listą zależności (https://help.github.com/en/articles/listing-the-packages-that-a-repository-depends-on).

Kolejny krok to monitorowanie zmian w bibliotekach zewnętrznych oraz wysyłanie powiadomień, gdy pojawi się aktualizacja, szczególnie gdy jest to aktualizacja bezpieczeństwa. Istnieją usługi, które automatycznie analizują listę zależności i powiadamiają, gdy w wykorzystywanej wersji zgłoszona została podatność bezpieczeństwa. Taki mechanizm nie uchroni naszego oprogramowania przez lukami, które jeszcze nie zostały zgłoszone (0-day), jednakże pozwala szybko zareagować na zgłoszenie takiej podatności.

Innym, ale również realnym zagrożeniem jest to opisane w powyższej historii, czyli celowe dodanie złośliwego kodu przez osobę, która posiada dostęp do repozytorium (a więc jest to zagrożenie wewnętrzne). Zaufanie do oprogramowania open source opiera się na tym, że podatności lub celowo osadzony złośliwy kod zostaną wykryte przez innych użytkowników. Oczywiście szansa na to maleje, jeśli używamy niszowych rozwiązań, tak więc  w celu zminimalizowania ryzyka należy przede wszystkim wykorzystywać te biblioteki, które są popularne i utrzymywane. W przypadku aplikacji wysokiego ryzyka – w mojej ocenie – warto zamrozić wersję wykorzystywanych bibliotek na liście zależności, po czym reagować na powiadomienia o hotfixach i ręcznie je weryfikować. Dzięki takiemu podejściu przy kolejnym budowaniu aplikacji nie skorzystamy z najnowszej wersji biblioteki, ale zminimalizujemy liczbę wymaganych weryfikacji zmian w bibliotekach, ponieważ będziemy reagować jedynie na hotfixy w obrębie ustalonej wersji.

Natomiast w sytuacji, gdy aplikacja będzie wymagała aktualizacji biblioteki lub wykorzystywana wersja biblioteki nie będzie dalej utrzymywana, należy przeprowadzić test bezpieczeństwa nowej wersji biblioteki i zaktualizować ją na liście zależności.

Znowu ten niebezpieczny blockchain

Opisywana historia nie dotyczy ataku na technologię blockchain, w szczególności nie jest to słynny atak 51%. Wektor ataku na supply chain jest powszechnie znany i dotyczy każdej technologii. Co ciekawe, zgodnie ze stanowiskiem zespołu bezpieczeństwa npm scenariusz, w którym atakujący publikuje paczkę npm, czeka na jej wykorzystanie i następnie wprowadza zmianę ze złośliwym kodem, zyskuje na popularności.

Natomiast specyficzna dla technologii blockchain jest procedura obsługi opisywanego ataku. W związku z niezmiennością blockchaina oraz brakiem scentralizowanej bazy danych dostępowych użytkowników zaatakowana organizacja nie ma możliwości przywrócenia backupu bazy danych, czy wymuszenia na użytkownikach zmiany kluczy prywatnych.

Jedyne, co pozostaje, to próba ratowania pozostałych środków, które nie zostały jeszcze skradzione. Akurat w przypadku Komodo na korzyść użytkowników zadziałało to, że atakujący opublikował listę wykradzionych seedów, przez co zespół Komodo mógł go pokonać (częściowo) jego własną bronią. Powyższa historia reagowania na ataki w technologii blockchain polegająca na wyścigu między złodziejem a atakowaną organizacją lub etycznymi hakerami nie jest odosobniona.

W roku 2017 podobny przypadek zdarzył się na platformie Ethereum, wykorzystującej blockchain do przechowywania i uruchamiania tzw. inteligentnych kontraktów (ang. smart contract). Kontrakty te mogą być rozumiane jako programy i biblioteki przechowywane i uruchamiane na komputerze rozproszonym po całym świecie.

W wyniku wystąpienia błędu w kontrakcie Parity Wallet odbył się wyścig o wielką stawkę. Kontrakt Parity Wallet pełnił funkcję zewnętrznej biblioteki, która była używana przez inne kontrakty implementujące funkcjonalność portfela kryptowalut. Wykryty w bibliotece błąd umożliwiał każdemu przelanie wszystkich środków Ether (kryptowaluta w platformie Ethereum) z portfela ofiary do swojego portfela.

Kiedy pojawiła się grupa złodziei opróżniających po kolei wszystkie portfele korzystające z podatnej biblioteki, grupa etycznych hakerów postanowiła przeprowadzić ten sam atak, aby uratować pozostałe środki i docelowo oddać je prawowitym właścicielom. Efektem wyścigu między złodziejami i etycznymi hakerami (zwanymi White Hat) była kradzież ok. 150 000 Etherów oraz uratowanie ok. 377 000 Etherów. Dzisiaj jest to równowartość odpowiednio 36 i 90 milionów USD.

Powyższa historia pokazuje, że aplikacje, które korzystają z technologii blockchain albo się z nią integrują, mogą być podatne na ataki niezależne od tej technologii. Aczkolwiek oprócz ogólnych zagrożeń pojawiają się jeszcze zagrożenia specyficzne dla blockchaina oraz inteligentnych kontraktów. W dokumencie Developing Secure Blockchain Applications poruszyliśmy najważniejsze kwestie związane z inteligentnymi kontraktami oraz technologią blockchain i zajęliśmy się popularnymi mitami na ich temat. Wyjaśniliśmy również różnicę między publicznym i prywatnym blokiem bloków, aby zwrócić uwagę na aspekty bezpieczeństwa tych infrastruktur.

Autorem tekstu jest Damian Rusinek z firmy Securing.

Zewnętrzne odnośniki:
https://komodoplatform.com/update-agama-vulnerability/
http://blog.npmjs.org/post/185397814280/plot-to-steal-cryptocurrency-foiled-by-the-npm

Powrót

Komentarze

  • 2019.06.16 15:19 Luke

    Czemu jest tyle różnych zawirowań z npm, a o podobnych akcjach np. z pip-em się nie słyszy?

    Odpowiedz
  • 2019.06.17 09:06 maciek

    ’haker opublikował w npm przydatną i w pełni działającą paczkę o nazwie „electron-native-notify”’
    Skąd wiadomo że haker? może ktoś potem przejął dostęp?
    Dobrze rozumiem że ten oszust (nie haker) działał złośliwie jeszcze nie wiedząc gdzie trafi jego kod?

    Odpowiedz
    • 2019.06.17 11:26 Damian

      Niestety nie jesteśmy teraz w stanie zweryfikować, czy ten sam użytkownik dodał oryginalną paczkę oraz złośliwy kod, ponieważ Gita paczki już nie ma. Natomiast możemy sie powołać na słowa zespołu NPM Security, który tak twierdzi.

      Ten oszust działał złośliwie z zamiarem, czyli wcześniej opublikował zwykłą paczkę, a dopiero później przystąpił do ataku i dodał ją do infekowanego repozytorium, z którego korzystał portfel.

      Odpowiedz

Zostaw odpowiedź

Jeśli chcesz zwrócić uwagę na literówkę lub inny błąd techniczny, zapraszamy do formularza kontaktowego. Reagujemy równie szybko.

Ukradli swoim klientom 13 mln USD, by nie pozwolić na to złodziejowi

Komentarze