15:05
22/10/2018

Minęły czasy, kiedy maszynę sprzedającą dało się łatwo wykiwać. Dziś mają one antywłamaniowe witryny UV albo systemy do zdalnego monitoringu. Monety i żetony zamieniono na aplikacje mobilne co utrudniło ataki starego typu. Niestety pewien włoski hacker postanowił atakować te maszyny na nowe sposoby, wykorzystując mobilne udogodnienia.

Pewnego pięknego dnia Matteo Pisani (Dyrektor Technologiczny Remoria VR) wybrał się do swojego rodzinnego miasta, gdzie odwiedził jednego ze swoich profesorów z czasu studiów na Università degli Studi di Cassino. Panowie zdecydowali się napić kawy, więc skierowali się ku najbliższemu automatowi. Przy wspomnianym automacie doszło do krótkiej wymiany zdań – która jak się później okazało – była kluczowa dla dalszego rozwoju opisywanej historii:

  • Matteo: Ja zapłacę, mam dużo drobnych!
  • Profesor: Poczekaj! Zapłacę za kawę za pomocą aplikacji mobilnej, będzie taniej

Argenta

Jak się okazało, maszyna została dostarczona przez firmę ArGenta, bardzo popularnego dostawcę “zautomatyzowanych usług sprzedaży” we Włoszech. Argenta sprzedaje artykuły pierwszej potrzeby – kawę, papierosy, napoje energetyzujące.

Argenta wykorzystuje w swoich automatach technologie Bluetooth Low Energy (BLE) i Near Field Communication (NFC), aby umożliwić użytkownikom łączenie się z nimi i dokonywanie płatności za produkty za pomocą smartfona. Zapewne większość z Was się już domyśliła, że to własnie aplikacja mobilna Argenta skupiła na sobie uwagę Matteo i jak się później okazało, stała się wektorem ataku.

W poszukiwaniu podatności

Matteo w swojej analizie wykorzystał zrootowanego smartfona z systemem Android (z włączoną funkcją debugowania USB), na którym zainstalował aplikację Argenta pochodzącą z oficjalnego sklepu Play. Następnie, przerzucił oryginalny plik *.apk na swojego laptopa za pomocą narzędzia ADB (Android Debug Bridge – interfejs debugowania w systemie operacyjnym Android):

# adb pull /data/app/com.sitael.vending-1/base.apk ./Argenta.apk

Dekompilował plik *.apk za pomocą popularnego narzędzia służącego do inżynierii wstecznej aplikacji bazujących na systemie Android – apktool:

# apktool d ./Argenta.apk ./Argenta

By w końcu dokonać ekstrakcji kodu źródłowego za pomocą jadx:

# jadx ./Argenta.apk

Matteo miał możliwość debugowania aplikacji dzięki edycji pliku AndroidManifest.xml – a konkretnie, poprzez dodanie właściwości android:debuggable=”true”.

W kolejnych krokach, Matteo:

  • przebudował aplikację
  • wygenerował dla niej nowy klucz za pomocą keytoola
  • skorzystał z nowo wygenerowanego klucza do podpisania aplikacji używając jarsignera
  • zoptymalizował wszystko za pomocą zipalign
  • zainstalował “nową” aplikację na swoim telefonie


# apktool b ./Argenta
# keytool -genkey -v -keystore Argenta.keystore -alias Argenta -keyalg RSA -keyize 2048-validity 10000
# jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore Argenta.keystore Argenta.apk Argenta
# zipalign -v 4 Argenta.apk Argenta-signed.apk
# adb install ./Argenta-signed.apk

Matteo zaczął obserwować działanie aplikacji i filtrować logi za pomocą logcata, używając do tego celu nazw pakietów.

# adb logcat –pid=`adb shell pidof -s com.sitael.vending`

Nie znalazł nic ciekawego, dlatego postanowił jeszcze raz przyjrzeć się kodowi źródłowemu aplikacji. Jego uwagę przykuło odniesienie do RushOrm znajdujące się w pliku AndroidManifest.xml. RushOrm to narzędzie dla systemu Android, które mapuje klasy języka Java do tabel SQL. Oznaczało to, że aplikacja mobilna Argenta korzysta z bazy danych, a baza danych to bezcenne źródło informacji dla hackera.

Pisani był w stanie ustalić, że aplikacja korzystała z bazy danych o nazwie “argenta.db”, którą zlokalizował i wyodrębnił na swoim laptopie – jej otworzenie było jednak zabezpieczone za pomocą hasła.

Nie minęło wiele czasu zanim Matteo po raz kolejny powrócił do kodu źródłowego aplikacji – tym razem udało mu się znaleźć plik konfiguracyjny RushOrm, którego analiza pozwoliła mu na ustalenie, że dostęp do bazy danych aplikacji chroniony jest za pomocą numeru IMEI (International Mobile Equipment Identity) telefonu. Bingo!

W skład bazy danych wchodziło – co oczywiste – wiele tabel, jednak tą, która zwracała na siebie szczególną uwagę, nazywała się “UserWallets” i zawierała edytowalne pole “walletCredit”.

Jak łatwo się domyślić, wpis ten mówił aplikacji o ilości kredytów, jaką dany użytkownik może wykorzystać w automatach firmy Argenta. Matteo stworzył narzędzie które pozwoliło mu na zautomatyzowanie interakcji z bazą danych i przeprowadzenia zmian w wirtualnym portfelu aplikacji.

Wnioski

Przez inspekcję kodu źródłowego znalazłem mnóstwo czystego kodu – bez zaciemniania – co oznaczało brak zastosowania jakichkolwiek środków zapobiegawczych mających na celu zabezpieczenia danych użytkowników i uczynienia aplikacji bezpieczną – twierdzi Matteo, który swoje ustalenia opisał w Hackernoon.

Podsumowując, dzięki swojemu odkryciu, nie posiadając żadnych środków na koncie aplikacji, atakujący był w stanie:

  • dowolnie zmienić ilość kredytów w aplikacji
  • kupować towar
  • wyczerpać ilość kredytów w aplikacji
  • ponownie zmienić ilość kredytów w aplikacji

I tak w kółko, aż do przekroczenia progu śmiertelnej ilości kofeiny we krwi 🙂

Około miesiąca przed upublicznieniem swojego odkrycia Matteo zwrócił się do firmy odpowiedzialnej za stworzenie aplikacji i delikatnie zasugerował opracowanie nieco bezpieczniejszego rozwiązania.

Jeśli jesteście zainteresowani obejrzeniem “live demo” to jest ono dostępne w serwisie YouTubie.

PS. Jeśli ktoś chciałby dowiedzieć się jak analizować aplikacje mobilne pod kątem bezpieczeństwa, to zapraszamy na nasze 2 dniowe warsztaty pt. “Bezpieczeństwo Aplikacji Mobilnych” — w listopadzie będziemy we Wrocławiu, Gdańsku i Warszawie.

Przeczytaj także:

24 komentarzy

Dodaj komentarz
  1. ” Argenta sprzedaje artykuły pierwszej potrzeby – kawę, papierosy, napoje energetyzujące.”

    Myślałem, że chleb i woda są artykułami pierwszej potrzeby. No, można dodać papier toaletowy.:)

    • Hmmm ja jak się budzę rano to pierwsze o czym myślę, to żeby szczenę umyć i o kawie. Drugie to że więcej kawy… o chlebie i wodzie jakoś nie… :D

    • Jednak Pierwsza potrzeba, a pierwsza myśl to różne różnice ;)

    • @wariat: a w tej kawie to nie masz wody? Chyba, że tylko chrupiesz ziarna, albo wciągasz zmieloną ;)

    • A ja pierwsze co pomyślałem to gumy, bynajmniej nie te do rzucia :P. Również często sprzedawane w automatach.

  2. B. ciekawy artykuł

  3. Ale, że co? Czy poniższe oznacza, że ów Matteo uważa, że zaciemnienie kodu czyni aplikację bezpieczną?
    “Przez inspekcję kodu źródłowego znalazłem mnóstwo czystego kodu – bez zaciemniania – co oznaczało brak zastosowania jakichkolwiek środków zapobiegawczych mających na celu zabezpieczenia danych użytkowników i uczynienia aplikacji bezpieczną.”
    Przecież to jest wierutna bzdura i nic głupszego nie można by powiedzieć. Nawet script-kiddies wiedzą, że security-by-obscurity nie daje żadnego bezpieczeństwa…

    • Może i nie ale przynajmniej odsiewa części domorosłych hackerów, niektórym zaciemnienie wystarczy żeby dali sobie spokój. Btw, Uber też nie zaciemniał kodu w starej apce… Ale zabezpieczenie bazy numerem IMEI to już niezły babol.

    • Zwieksza koszt ataku, jesli analiza czystego kodu zajmie ci miesiac, a kodu “zabezpieczonego” m.in. poprzez obfuskacje wzrosnie do np. 6 miesiecy, to koszt jest zdecydowanie wiekszy, pytanie czy 6 miesiecy analizy to duzo dla aplikacji z eWalletem, to inna dyskusja. Oczywiscie wiele deobfuskatorow radzi sobie ze standardowymi technikami, na to rowniez trzeba uwazac

  4. Piję kawę. Co robić? Jak żyć?

  5. czyli, ze popelnianie przestepstw popłaca?

  6. Artykuł bardzo ciekawy. Dziwi mnie jednak, że Matteo potrzebował dekompilować kod, aby trafić do argenta.db – pliki, z jakich korzysta (tworzy, otwiera, usuwa, etc) dana aplikacja, sprawdzą się na Androidzie innymi narzędziami (np. “File Monitor” z F-Droid).

    Na marginesie – ‘apktool d’ nic nie dekompiluje, .apk to są zwykłe pliki zip. To polecenie po prostu rozpakowało zawartość do wskazanego folderu. Manifest można sobie wyedytować i leafpad’em (geditem, czy czymtam), bez udziału jadx – kluczowe było ponowne podpisanie przepakowanego apk’a.

    Które i tak nic nie dało ;) bo debugi w syslog nie mówiły nic ciekawego. Rozpakowany .apk okazał się bardziej pomocny, bo było widać jak kretyńsko zahasłowano bazę danych – ale, nawet nie to jest największą wtopą aplikacji. Oczywistym idiotyzmem jest przechowywanie info o kredytach w lokalnej bazie danych, bez weryfikacji z serwerem samej firmy.

    • I tak i nie. Apktool przetwarza binarki dla dalvika na smali który jest czymś w rodzaju dalvikowego asm. Jako że w zasadzie to nadal jest zwyczajnie lista instrukcji to imo poprawny termin to transpilacja.

    • Zgadza się, I stand corrected. W swoim wpisie chciałem głównie zaznaczyć, że słowo “dekompilacja” jednak tu trochę razi, jednocześnie, aby zrobić to, co zrobił włoch w pierwszej sekcji (edycja manifestu, włączenie debug, przepakowanie 8 podpisanie) żadna -lacja nie jest potrzebna.

  7. To jest beznadzieja, że aplikacja mówi stacji “Jestem bogaty, daj mi co tylko masz” a stacja ślepo temu ufa.

    Nie powinno mieć miejsca wypuszczenie na rynek stacji która nie autoryzuje się z serwerem online w kwestii sprawdzenia zgodności transakcji (czy płacimy kredytami, czy tez eurogąbkami).

    Ilość wydawanych kredytów nie może być większa niż ilość zakupionych kredytów, bez spełnienia tego kryterium stacja do sprzedaży nie powinna nigdy zostać wypuszczona na rynek.

    Pozostaje mieć nadzieję, że w bazie danych były zcache’owane tylko informacje użytkownika zalogowanego a nie “SELECT *”

    • Bartlomiej,
      Producent mogl swiadomie zdecydowac sie na taka architekture systemu aby bez koniecznosci autoryzacji z serwerem nadal mógł działać. Prawdopodobnie wiecej by stracil z powodu niezadowolonych klientow ktorzy nie mogliby zrobic transakcji bez dostępu do netu niz w przypadku naduzyć

    • I tak i nie. Kwestia analizy zysków i strat. Czasem warto postawić automat nawet tam gdzie nie ma dostępu do sieci i sprzedawać towar przy założeniu że klient na telefonie ma poprawną ilość moniaków. A i klient w tym samym czasie nie musi mieć dostępu on-line.
      Jeśli komuś się ten biznes kręci to nie musi od razu inwestować w jakieś dziwne zabezpieczenia.

    • Wystarczy ocenić jakie jest ryzyko wyłudzenia kawy w porównaniu z frustracją klientów kiedy internet nie działa.

    • > To jest beznadzieja, że aplikacja mówi stacji “Jestem bogaty, daj mi co tylko masz” a stacja ślepo temu ufa.
      Czy już zapomnieliście czasy hakowania budek telefonicznych i kart magnetycznych? Czy każda usługa przedpłacona musi koniecznie działać on-line?

  8. Tak na szybko szkic rozwiązania bardziej bullet-proof:

    Każde rozwiązanie które przechowuje środki na telefonie w takiej postaci że klient może te środki samodzielnie generować jest skazane na porażkę. Security-by-obscurity (hasło do bazy zaszyte w aplikacji, itp) to nie zabezpieczenie, jak widać. Jedyne zabezieczenie to takie w którym klient nie ma możliwości samodzielnej edycji środków- są one generowane przez serwer i przesyłane do klienta.

    Atak w takiej formie byłby niemożliwy do przeprowadzenia, gdyby każdy kredyt był tokenem- przesłanym z serwera, podpisanym kluczem prywatnym serwera.
    Automat (nawet offline) mógłby łatwo sprawdzić autentyczność i unikalność tokena. A użytkownik tokenów sobie sam nie wygeneruje bo nie ma klucza prywatnego serwera.
    W takim przypadku jedyne co można zrobić to reużyć tych samych tokenów w różnych automatach (na to pewnie też da się coś wymyślić).
    Powyższe przy założeniu że zarówno automat jak i telefon są offline.

    Jeśli telefon musi być online do transakcji, to możemy wymagać tokenów generowanych (i podpisanych) w momencie transakcji przez serwer.
    Ważność tokenu (nie więcej niż kilkanaście sekund od momentu wygenerowania) automat również może sprawdzić offline.

    Czy da się żeby taki porftel umożliwiał zakupy 100% offline i zabezpieczał przed reużyciem tych samych środków wiele razy w różnych automatach? Z tego co widzę nie, ale pewnie się mylę- może ktoś odpowie w komentarzach?

  9. Tak jak to już kilka osób zauważyło, czasem zabezpieczenie będzie kosztowało więcej, niż potencjalne straty.
    W tym przypadku – skoro modyfikacja bazy danych oryginalnej apki wymaga roota, to można wyciągnąć wniosek, że nie będzie masowego wyłudzania w ten sposób.
    Żeby kraść bez roota, trzeba napisać własną apkę.

    Zatem właściwe pytanie brzmi: jak zabezpieczyć komunikację, aby mieć pewność, że gadamy z własną apką, przy założeniu, że chcemy się zabezpieczyć jedynie przed nierootowanymi telefonami i działamy offline?

  10. Akurat w tym przypadku analizę powinno się także dać przeprowadzić uruchamiając aplikację korzystając z emulatora. Więc bez roota na telefonie prawdopodobnie można by przeprowadzić tą samą analizę i dojść do tych samych wniosków (kredyty w bazie, hasło do bazy w aplikacji).

    Root na telefonie prawdopodobnie jest niezbędny żeby grzebać w bazie danych aplikacji na telefonie- inaczej powinna zadziałać izolacja aplikacji. Przy tym założeniu jeśli chcemy się zabezpieczyć tylko przed nie-zrootowanymi telefonami to nie musimy nic robić. Pewnie można nawet napisać aplikację żeby działała tylko na nie-zrootowanych telefonach (chociaż w ten sposób wkurzymy pewną grupę użytkowników która niekoniecznie chce hackować).

    Ciągle pozostaje wektor ataku gdzie ktoś może po prostu podszyć się pod aplikację i w imieniu aplikacji przeprowadzić komunikację z automatem. W ten sposób nie trzeba żadnej bazy danych, kredytów ani nawet konta w systemie. Prawdziwa aplikacja przed zakupem sprawdzi stan kretytow, odejmie koszt zakupu z portfela. Jeśli powyższe się nie powiedzie aplikacja (po stronie klienta) nie przeprowadzi zakupu.

    Fałszywa aplikacja nie musi być taka skrupulatna. Może po prostu akceptować dowolne żądania płatności, na dowolną kwotę bez aktualizacji jakiegoś tam portfela kredytów:)

    Żeby się przed tym zabezpieczyć kredyty muszą być czymś więcej niż liczbą. Np (jak napisałem w komentarzu wyżej) liczbą ale wygenerowaną przez serwer w momencie zakupu, podpisaną kluczem prywatnym serwera. Automat łatwo jest w stanie sprawdzić autentyczność i unikalność (offline tylko unikalność w obrębie jednego automatu) takiego kredytu (weryfikacja kluczem publicznym). Klient nie będzie w stanie sam takiego kredytu wygenerować (nie zna klucza prywatnego serwera).

  11. Panowie! Ile kosztuje kawa w automacie? 1euro? 2 euro? Ilu klientów jest w stanie zhakować aplikację do zakupu kawy? Można zabezpieczyć i weryfikować transakcję zakupu kawy szyfrem kwantowym transmitowanym strumieniem kwarków zmiennoprzecinkowych, tylko po co? Dla 1 euro?

    • Są automaty sprzedające droższy towar, sporo droższy – np Raspberry Pi, iPady, karty pamięci, karty SIM etc. Żeby nie pozostać gołosłownym – Google: “The Ultimate Geek Vending Machine” (nie wiem, czy Niebezpiecznik akceptuje linki). Poza tym, uczulanie firm na dbanie o bezpieczeństwo jest istotne – jeśli teraz ta firma dostanie po łapkach za niezabezpieczenie automatu z kawą, to może w przyszłości podejdzie poważnie do tematu, kiedy będzie robić system rezerwacji lotów?

Odpowiadasz na komentarz Slawek

Kliknij tu, aby anulować

Zamieszczając komentarz akceptujesz regulamin dodawania komentarzy. Przez moderację nie przejdą: wycieczki osobiste, komentarze nie na temat, wulgaryzmy.