Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00124 005150 15183764 na godz. na dobę w sumie
Android. Podręcznik hackera - ebook/pdf
Android. Podręcznik hackera - ebook/pdf
Autor: , , , , , Liczba stron: 520
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-9943-8 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie mobilne >> android
Porównaj ceny (książka, ebook (-20%), audiobook).

Obroń Twój system przed atakiem!

System Android to niezaprzeczalny lider wśród systemów operacyjnych dla urządzeń mobilnych. Jednak bycie liderem ma pewną zasadniczą wadę — wszyscy chcą przełamać jego zabezpieczenia. Jeżeli jesteś specjalistą odpowiedzialnym za bezpieczeństwo sieci, jeżeli jesteś administratorem odpowiadającym za bezpieczeństwo urządzeń mobilnych, to trafiłeś na książkę, która stanie się Twoją obowiązkową lekturą na najbliższe dni!

Dzięki niej poznasz działanie systemu Android oraz zaimplementowaną w nim architekturę zabezpieczeń. W kolejnych rozdziałach nauczysz się rozpoznawać szczegóły implementacji zabezpieczeń oraz komplikacje wynikające z faktu, że Android to otwarty system. Gdy już zdobędziesz solidne fundamenty teoretyczne, przejdziesz do analizy różnych technik ataku na urządzenia pracujące pod kontrolą Androida. Ponadto poznasz możliwe płaszczyzny ataku, publicznie dostępne exploity oraz słabości jądra systemu. Książka ta musi się znaleźć na półce każdego, komu bezpieczeństwo platformy Android nie jest obojętne!


Dzięki tej książce nauczysz się: Obowiązkowa lektura specjalistów odpowiedzialnych za bezpieczeństwo platformy Android!
Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: Android™ Hacker’s Handbook Tłumaczenie: Andrzej Stefański ISBN: 978-83-246-9940-7 Translation copyright © 2015 by Helion S.A. Copyright © 2014 by John Wiley Sons, Inc., Indianapolis, Indiana. All Rights Reserved. This translation published under license with the original publisher John Wiley Sons, Inc. No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning, or otherwise without either the prior written permission of the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie bierze jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Wydawnictwo HELION nie ponosi również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Pliki z przykładami omawianymi w książce można znaleźć pod adresem: ftp://ftp.helion.pl/przyklady/andrph.zip Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/andrph Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność O autorach O korektorze merytorycznym Podziękowania Wprowadzenie Omówienie książki i technologii Jak podzielona jest ta książka Kto powinien przeczytać tę książkę Potrzebne narzędzia Co znajduje się na stronie internetowej Powodzenia! Rozdział 1. Rzut oka na ekosystem Korzenie Androida Historia firmy Historia wersji Dostępne urządzenia Otwarte (najczęściej) źródła Udziałowcy Androida Google Producenci sprzętu Operatorzy Programiści Użytkownicy Spis treści 13 15 17 19 20 20 22 22 23 23 25 25 25 26 28 29 31 32 33 35 35 36 3 Kup książkęPoleć książkę 4 Spis treści Obraz złożoności ekosystemu Fragmentacja Kompatybilność Problemy związane z aktualizacją Bezpieczeństwo kontra otwartość Upublicznienie informacji Podsumowanie Rozdział 2. Projekt i architektura bezpieczeństwa Androida Architektura systemu Android Ograniczenia i zabezpieczenia Środowisko izolowane Androida Uprawnienia Androida Dokładniejsza analiza warstw Aplikacje Androida Android Framework Wirtualna maszyna Dalvik Kod natywny przestrzeni użytkownika Jądro Skomplikowane zabezpieczenia, skomplikowany exploit Podsumowanie Rozdział 3. Odblokowanie urządzenia Układ partycji Ustalenie układu partycji Proces uruchamiania systemu Dostęp do trybu pobierania Zablokowane i odblokowane programy ładujące Oryginalne oraz zmodyfikowane obrazy ratunkowe Uzyskiwanie pełnego dostępu z odblokowanym programem ładującym Uzyskiwanie pełnego dostępu przy zablokowanym programie ładującym Uzyskiwanie dostępu na uruchomionym systemie Blokady NAND, tymczasowy root, trwały root Utrwalanie programowego roota Historie znanych ataków Jądro: Wunderbar/asroot Tryb ratunkowy: Volez Udev: Exploid Adbd: RageAgainstTheCage Zygote: Zimperlich i Zysploit Ashmem: KillingInTheNameOf i psneuter Vold: GingerBreak PowerVR: levitator 38 38 40 41 43 44 45 47 47 49 49 52 55 55 59 60 62 67 74 75 77 78 79 80 81 82 83 85 87 88 89 91 92 92 93 93 94 94 95 95 96 Kup książkęPoleć książkę Spis treści Libsysutils: zergRush Jądro: mempodroid Ataki związane z uprawnieniami plików oraz linkami symbolicznymi Adb restore Exynos4: exynos-abuse Diag: lit / diaggetroot Podsumowanie Rozdział 4. Przegląd bezpieczeństwa aplikacji Częste błędy Problemy z uprawnieniami aplikacji Niezabezpieczone przesyłanie wrażliwych danych Przechowywanie niezabezpieczonych danych Wycieki informacji przez logi Niezabezpieczone zakończenia IPC Studium przypadku: Mobile Security App Profilowanie Analiza statyczna Analiza dynamiczna Atak Studium przypadku: SIP Client Drozer Rozpoznanie Snarfing Wstrzykiwanie Podsumowanie Rozdział 5. Płaszczyzny ataku Androida Podstawy terminologii Wektory ataku Płaszczyzny ataku Klasyfikacja płaszczyzn ataku Właściwości płaszczyzny Sposób klasyfikacji Płaszczyzny ataku dostępne zdalnie Zagadnienia sieciowe Stosy sieciowe Udostępnione usługi sieciowe Technologie mobilne Płaszczyzna ataku po stronie użytkownika Infrastruktura Google 5 96 97 97 98 99 99 100 101 101 102 103 104 105 106 108 108 110 124 132 134 134 134 136 138 140 141 141 142 143 144 144 145 145 146 150 151 152 153 158 Kup książkęPoleć książkę 6 Spis treści Sąsiedztwo fizyczne Komunikacja bezprzewodowa Inne technologie Lokalne płaszczyzny ataku Przeglądanie systemu plików Odnajdywanie innych lokalnych płaszczyzn ataku Fizyczne płaszczyzny ataku Demontaż urządzenia USB Inne fizyczne płaszczyzny ataków Zewnętrzne modyfikacje Podsumowanie Rozdział 6. Wyszukiwanie słabości za pomocą fuzzingu Pochodzenie fuzzingu Identyfikowanie celu Tworzenie zniekształconych danych wejściowych Przetwarzanie danych wejściowych Monitorowanie wyników Fuzzing w Androidzie Fuzzing odbiorców komunikatów Identyfikacja celu Generowanie danych wejściowych Dostarczanie danych wejściowych Monitorowanie testów Fuzzing Chrome dla Androida Wybór celu Generowanie danych wejściowych Przetwarzanie danych wejściowych Monitorowanie testów Fuzzing płaszczyzny ataku USB Wyzwania fuzzingu USB Wybór trybu Generowanie danych wejściowych Przetwarzanie danych wejściowych Monitorowanie testów Podsumowanie Rozdział 7. Wyszukiwanie błędów i analiza słabości Zebranie wszystkich dostępnych informacji Wybór zestawu narzędzi 164 164 170 170 171 172 176 177 178 181 182 182 183 183 185 185 186 187 187 188 189 190 190 191 193 193 195 197 199 201 202 202 203 205 206 207 209 209 211 Kup książkęPoleć książkę Spis treści Debugowanie błędnego zakończenia Logi systemowe Tombstone Zdalne debugowanie Debugowanie kodu maszyny wirtualnej Dalvik Debugowanie przykładowej aplikacji Wyświetlanie kodu źródłowego Android Framework Debugowanie istniejącego kodu Debugowanie kodu natywnego Debugowanie z NDK Debugowanie z Eclipse Debugowanie z AOSP Zwiększanie automatyzacji Debugowanie z symbolami Debugowanie urządzenia niewspieranego przez AOSP Debugowanie w trybie mieszanym Alternatywne techniki debugowania Wyrażenia do debugowania Debugowanie w urządzeniu Dynamiczne modyfikowanie binariów Analiza podatności Ustalanie pierwotnej przyczyny Ocena możliwości wykorzystania Podsumowanie Rozdział 8. Wykorzystywanie oprogramowania działającego w przestrzeni użytkownika Podstawy błędów pamięci Przepełnianie bufora stosu Wykorzystanie sterty Historia publicznie znanych eksploitów GingerBreak zergRush mempodroid Wykorzystanie przeglądarki Android Zrozumienie błędu Kontrola sterty Podsumowanie Rozdział 9. Return Oriented Programming Historia i uzasadnienie Oddzielna pamięć podręczna danych i instrukcji 7 212 212 213 214 215 216 218 220 224 224 228 230 235 237 243 244 244 244 245 246 247 247 260 261 263 263 264 267 274 275 278 281 282 283 285 288 289 289 290 Kup książkęPoleć książkę 8 Spis treści Podstawy ROP w ARM Wywoływanie podprocedur w ARM Łączenie gadżetów w łańcuch Identyfikacja potencjalnych gadżetów Studium przypadku: linker Androida 4.0.1 Modyfikacja wskaźnika stosu Wykonanie dowolnego kodu z zaalokowanej pamięci Podsumowanie Rozdział 10. Hakowanie i atakowanie jądra Jądro Linuksa w Androidzie Wyodrębnianie jądra Wyodrębnianie z oprogramowania fabrycznego Pobieranie z urządzenia Pobranie jądra z obrazu startowego Rozpakowanie jądra Uruchamianie zmodyfikowanego kodu jądra Pozyskanie kodu źródłowego Przygotowanie środowiska kompilacji Konfigurowanie jądra Korzystanie z własnych modułów jądra Kompilacja zmodyfikowanego jądra Tworzenie obrazu startowego Uruchamianie zmodyfikowanego jądra Debugowanie jądra Raporty błędów jądra Zrozumienie Oops Debugowanie na żywo z KGDB Wykorzystanie jądra Typowe jądra Androida Wyodrębnianie adresów Studia przypadku Podsumowanie Rozdział 11. Atakowanie RIL Wprowadzenie do RIL Architektura RIL Architektura smartfona Stos telefonu w Androidzie Dostosowanie stosu telefonu Usługi RIL (rild) API vendor-ril 292 293 295 296 297 298 300 304 317 317 318 319 321 323 323 324 324 327 328 329 332 335 337 342 342 344 348 352 352 354 356 367 311 312 312 313 313 315 315 318 Kup książkęPoleć książkę Spis treści SMS (Short Message Service) Wysyłanie i odbieranie wiadomości SMS Format wiadomości SMS Komunikacja z modemem Emulacja modemu na potrzeby fuzzingu Fuzzing SMS w Androidzie Podsumowanie Rozdział 12. Mechanizmy ograniczające działanie eksploitów Klasyfikacja Podpisywanie kodu Utwardzanie sterty Zabezpieczenia przed przepełnieniem zmiennej typu integer Zapobieganie wykonaniu danych Randomizacja przestrzeni adresowej Zabezpieczanie stosu Zabezpieczenia formatujących ciągów znaków Read-Only Relocations Izolowanie środowiska Zabezpieczanie kodu źródłowego Mechanizmy kontroli dostępu Zabezpieczanie jądra Ograniczenia wskaźników i logów Ochrona strony zerowej Obszary pamięci tylko do odczytu Inne zabezpieczenia Podsumowanie mechanizmów ograniczających działanie eksploitów Wyłączanie ograniczeń Zmiana tożsamości Zamiana binariów Modyfikowanie jądra Pokonywanie mechanizmów ograniczających działanie eksploitów Pokonywanie zabezpieczeń stosu Pokonywanie ASLR Pokonywanie zabezpieczeń zapobiegających wykonaniu danych Pokonywanie ograniczeń jądra Spojrzenie w przyszłość Oficjalnie rozwijane projekty Utwardzanie jądra przez społeczność Odrobina spekulacji Podsumowanie 9 319 319 319 322 322 324 331 333 334 334 336 336 338 340 342 343 345 346 346 348 349 350 351 351 352 354 356 356 357 357 358 358 359 359 359 360 360 361 362 362 Kup książkęPoleć książkę 10 Spis treści Rozdział 13. Ataki sprzętowe Komunikacja ze sprzętem Interfejsy szeregowe UART Interfejsy I2C, SPI i One-Wire JTAG Odnajdywanie interfejsów do debugowania Identyfikacja komponentów Pozyskiwanie specyfikacji Trudności przy identyfikacji komponentów Przechwytywanie, monitorowanie i wstrzykiwanie danych USB Interfejsy szeregowe I2C, SPI i UART Kradzież danych i oprogramowania Uzyskiwanie dostępu w sposób dyskretny Inwazyjne metody dostępu do oprogramowania Co zrobić ze zrzutem danych? Pułapki Nietypowe interfejsy Dane binarne i zamknięte protokoły Uszkodzone interfejsy do debugowania Hasła układu Hasła programu ładującego, kombinacje klawiszy i ciche terminale Zmodyfikowane sekwencje startowe Ukryte linie adresowe Żywica zabezpieczająca Szyfrowanie obrazów, obfuskacja i utrudnianie debugowania Podsumowanie Dodatek A Narzędzia Narzędzia programistyczne Android SDK Android NDK Eclipse Wtyczka ADT Pakiet ADT Android Studio Narzędzia do pozyskiwania fabrycznego oprogramowania i modyfikowania pamięci Binwalk fastboot Samsung NVIDIA 363 364 364 368 370 381 392 392 394 395 395 399 404 405 407 410 414 414 414 415 415 415 416 416 416 417 417 419 419 419 420 420 420 420 420 421 421 421 421 422 Kup książkęPoleć książkę Spis treści LG HTC Motorola Narzędzia natywne Androida BusyBox setpropex SQLite strace Narzędzia do podpinania i modyfikowania Framework ADBI ldpreloadhook Framework XPosed Cydia Substrate Narzędzia do analizy statycznej Smali i Baksmali Androguard apktool dex2jar jad JD-GUI JEB Radare2 IDA Pro i dekompilator Hex-Rays Narzędzia do testowania aplikacji Framework Drozer (Mercury) iSEC Intent Sniffer i Intent Fuzzer Narzędzia do hakowania sprzętu Segger J-Link JTAGulator OpenOCD Saleae Bus Pirate GoodFET TotalPhase Beagle USB Facedancer21 TotalPhase Aardvark I2C Chip Quik Opalarka Xeltek SuperPro IDA 11 422 423 423 424 424 425 425 425 425 425 426 426 426 426 427 427 427 427 428 428 428 428 429 429 429 429 430 430 430 430 430 430 431 431 431 431 431 431 432 432 Kup książkęPoleć książkę 12 Spis treści Dodatek B Repozytoria otwartych kodów źródłowych Google AOSP System kontroli kodu Gerrit Producenci SoC AllWinner Intel Marvell MediaTek Nvidia Texas Instruments Qualcomm Samsung Producenci urządzeń (OEM) ASUS HTC LG Motorola Samsung Sony Mobile Źródła projektów zewnętrznych Inne źródła Zmodyfikowane oprogramowanie fabryczne Linaro Replicant Indeksy kodu Wolni strzelcy Dodatek C Źródła Skorowidz 433 433 433 434 434 435 435 435 435 436 436 436 437 437 438 438 438 439 439 439 440 440 440 441 441 441 441 443 501 Kup książkęPoleć książkę Rozdział 4 Przegląd bezpieczeństwa aplikacji Bezpieczeństwo aplikacji było bardzo istotnym zagadnieniem, zanim jeszcze Android powstał. Na początku szaleństwa z aplikacjami webowymi programiści stadnie ruszyli w kierunku szybkiego tworzenia aplikacji, pomijając podstawowe praktyki zapewniające bezpieczeństwo lub korzystając z frameworków bez odpowiedniej kontroli zabezpieczeń. Z nadejściem aplikacji mobilnych powtó- rzyło się to samo. Ten rozdział rozpoczyna się od omówienia kilku częstych problemów z bezpie- czeństwem androidowych aplikacji. Na koniec przedstawione są dwa studia przypadków pokazują- cych odkrycie i wykorzystanie luk w aplikacjach za pomocą popularnych narzędzi. Częste błędy W tradycyjnie zabezpieczonych aplikacjach można znaleźć wiele problemów, które często poja- wiają się podczas testów bezpieczeństwa i w raportach podatności. Problemy mogą być różnego rodzaju — od wycieków wrażliwych informacji do krytycznych słabości umożliwiających wykona- nie kodu lub poleceń. Androidowe aplikacje nie są odporne na tego typu błędy, choć sposoby wy- korzystania tych błędów mogą różnić się od tych stosowanych w przypadku tradycyjnych aplikacji. W tym podrozdziale omówione są niektóre problemy z bezpieczeństwem typowo odkrywane podczas testowania bezpieczeństwa aplikacji androidowych oraz jawnych badań. Nie jest to oczywi- ście wyczerpująca lista. Jest bardzo prawdopodobne, że wraz z rozpowszechnianiem się dobrych praktyk programistycznych związanych z bezpieczeństwem aplikacji oraz rozwojem API Androida pojawią się nowe luki, a może nawet nowe klasy problemów. 101 Kup książkęPoleć książkę 102 Rozdział 4 (cid:31) Przegląd bezpieczeństwa aplikacji Problemy z uprawnieniami aplikacji Przy obecnym poziomie grupowania w przyjętym modelu uprawnień Androida występują sytu- acje, gdy programiści żądają większego zakresu uprawnień dla aplikacji, niż jest to konieczne. Takie zachowanie może wynikać z niekonsekwencji w mechanizmach kontroli uprawnień i ich doku- mentacji. Choć dokumentacja udostępniona programistom omawia większość wymagań doty- czących uprawnień dla klas i metod, nie są to informacje w stu procentach kompletne ani nawet w stu procentach poprawne. Grupy badawcze usiłowały identyfikować tego typu niekonsekwencje na różne sposoby. Na przykład w 2012 roku Andrew Reiter i Zach Lanier próbowali wykonać mapę wymagań uprawnień dla API Androida dostępnego w AOSP (Android Open Source Project). Doprowadziło to do kilku interesujących wniosków dotyczących tych problemów. Podczas tej próby odkryli oni m.in. niespójności pomiędzy dokumentacją i implementacją niektórych metod w klasie WiFiManager. Przykładowo dokumentacja nie wspomina o wymaganiach uprawnień dla metody startScan. Rysunek 4.1 zawiera zrzut ekranu z dokumentacji dla pro- gramistów Androida dotyczącej tej metody. Rysunek 4.1. Dokumentacja metody startScan Różni się to od rzeczywistego kodu źródłowego tej metody (w Androidzie 4.2), który zawiera wywołanie metody enforceCallingOrSelfPermission, sprawdzającej, czy wywołujący ją posiada uprawnienie ACCESS_WIFI_STATE poprzez enforceChangePermission: public void startScan(boolean forceActive) { enforceChangePermission(); mWifiStateMachine.startScan(forceActive); noteScanStart(); } ... private void enforceChangePermission() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE, WifiService ); } Innym przykładem jest metoda getNeighboringCellInfo z klasy TelephonyManager, której doku- mentacja określa wymagane uprawnienie ACCESS_COARSE_UPDATES. Rysunek 4.2 pokazuje zrzut ekra- nu z dokumentacji dla programistów Androida dotyczącej tej metody. Rysunek 4.2. Dokumentacja getNeighboringCellInfo Kup książkęPoleć książkę Częste błędy 103 Jednak zaglądając do kodu źródłowego klasy PhoneInterfaceManager (w Androidzie 4.2), która implementuje interfejs Telephony, można zobaczyć, że metoda getNeighboringCellInfo w rzeczywi- stości sprawdza obecność uprawnień ACCESS_FINE_LOCATION lub ACCESS_COARSE_LOCATION, nie- wymienianych w dokumentacji: public List NeighboringCellInfo getNeighboringCellInfo() { try { mApp.enforceCallingOrSelfPermission( android.Manifest.permission.ACCESS_FINE_LOCATION, null); }catch (SecurityException e) { // If we have ACCESS_FINE_LOCATION permission, skip the check // for ACCESS_COARSE_LOCATION // A failure should throw the SecurityException from // ACCESS_COARSE_LOCATION since this is the weaker precondition mApp.enforceCallingOrSelfPermission( android.Manifest.permission.ACCESS_COARSE_LOCATION, null); } Tego rodzaju przeoczenia, choć mogą wyglądać niewinnie, często prowadzą u części progra- mistów do złych praktyk, takich jak przydzielanie zbyt małej liczby uprawnień (ang. undergranting) lub zbyt dużej liczby uprawnień (ang. overgranting). W pierwszym przypadku często pojawia się problem z działaniem aplikacji, objawiający się nieobsłużonym wyjątkiem SecurityException, prowadzącym do zatrzymania aplikacji. W drugim przypadku jest to bardziej problem bezpie- czeństwa, ponieważ zawierająca błąd aplikacja ze zbyt dużym zakresem uprawnień może zostać wykorzystana przez inną aplikację do rozszerzenia uprawnień. Przy analizowaniu aplikacji Androida pod kątem zbyt dużego zakresu uprawnień ważne jest, by porównać zakres wymaganych uprawnień z rzeczywistym przeznaczeniem aplikacji. Niektóre uprawnienia, jak CAMERA oraz SEND_SMS, mogą nie być potrzebne w samej aplikacji. Niezbędną funk- cjonalność można osiągnąć, przekazując sterowanie do standardowej aplikacji Aparat lub Wiadomo- ści, aby wykonały konieczną czynność (co jest bezpieczniejsze). Przykład omówiony w podrozdziale „Studium przypadku: Mobile Security App” pokazuje, jak sprawdzić, w których komponentach aplikacji dane uprawnienia są wykorzystywane. Niezabezpieczone przesyłanie wrażliwych danych Dzięki temu, że często poświęca się tej sprawie uwagę, ogólna świadomość konieczności zabezpiecza- nia kanału transmisji danych (np. SSL, TLS itp.) jest dość wysoka. Niestety, nie zawsze przekłada się to na świat aplikacji mobilnych. Prawdopodobnie z powodu braku umiejętności poprawnego zaimplementowania SSL lub TLS albo też z powodu nieuzasadnionego przekonania, że dane przesy- łane przez sieć operatora są bezpieczne, twórcy aplikacji mobilnych czasem nie zabezpieczają wrażli- wych danych podczas transmisji. Ten problem objawia się na jeden lub więcej z poniższych sposobów: (cid:31) słabe szyfrowanie lub brak szyfrowania; (cid:31) silne szyfrowanie, ale brak obsługi ostrzeżeń dotyczących zabezpieczeń bądź błędów walidacji certyfikatów; (cid:31) użycie czystego tekstu przy problemach z szyfrowaniem; Kup książkęPoleć książkę 104 Rozdział 4 (cid:31) Przegląd bezpieczeństwa aplikacji (cid:31) niespójne wykorzystanie zabezpieczeń transmisji w zależności od typu sieci (przykładowo w sieci komórkowej i przez Wi-Fi). Do wykrycia problemów z niezabezpieczoną transmisją danych może wystarczyć samo prze- chwycenie danych wysyłanych z badanego urządzenia. Szczegóły dotyczące przygotowania ataku typu man-in-the-middle wykraczają poza zakres tej książki, ale istnieje wiele narzędzi i tutoriali opisujących wykonanie takiego ataku. W najprostszym przypadku emulator Androida umożliwia zarówno przekierowanie przesyłanych danych, jak i zapisywanie ruchu do pliku w formacie PCAP. Można to osiągnąć za pomocą opcji -http-proxy i -tcpdump. Ważnym, znanym publicznie przykładem niezabezpieczonej transmisji danych była imple- mentacja przez firmę Google protokołu autoryzacji ClientLogin w Androidzie od 2.1 do 2.3.4. Ten protokół umożliwia aplikacjom żądanie autoryzacji konta użytkownika Google, a to z kolei można później wykorzystać do dalszej komunikacji z API wybranej usługi. W 2011 roku badacze z University of Ulm ustalili, że aplikacje Kalendarz i Kontakty w An- droidzie 2.1 do 2.3.3 oraz usługa Picasa Sync w Androidzie 2.3.4 przesyłały token uwierzytelniający Google ClientLogin czystym tekstem za pomocą protokołu HTTP. Po uzyskaniu takiego tokena atakujący może wykorzystać go do podszywania się pod użytkownika. Ponieważ istnieje wiele na- rzędzi i technik przeprowadzania ataków typu man-in-the-middle w sieciach Wi-Fi, przechwycenie takiego tokena jest stosunkowo łatwe i może mieć złe następstwa dla użytkowników złośliwych lub niezabezpieczonych sieci Wi-Fi. Więcej informacji na temat odkryć dotyczących implementacji ClientLogin dokonanych na University of Ulm można znaleźć pod adresem www.uni-ulm.de/en/in/mi/staff/koenings/catching- authtokens.html. Przechowywanie niezabezpieczonych danych Android oferuje wiele standardowych mechanizmów do przechowywania danych — są to współ- dzielone właściwości (ang. Shared Preferences), bazy danych SQLite oraz zwykłe pliki tekstowe. Dodatkowo każdy z tych kontenerów można utworzyć i wykorzystywać na różne sposoby — za- rządzanym kodem, natywnym kodem lub za pomocą interfejsów, takich jak dostawcy treści (ang. Content Providers). Najczęstsze błędy to: przechowywanie wrażliwych danych w plikach tekstowych, tworzenie niezabezpieczonych dostawców treści (omówione dalej) oraz niebezpieczne upraw- nienia do plików. Dobrym przykładem zawierającym zarówno przechowywanie w plikach tekstowych, jak i nie- bezpieczne uprawnienia do plików jest klient Skype dla Androida, w którym odkryto te problemy w kwietniu 2011 roku. Jak zgłosił Justin Case (jcase) na stronie http://AndroidPolice.com, aplika- cja Skype tworzyła pliki baz danych SQLite oraz pliki XML z takimi uprawnieniami, że były one udostępnione do odczytu i zapisu dla wszystkich. Ponadto ich zawartość nie była zaszyfrowana i zawierała dane konfiguracyjne oraz logi przesyłanych komunikatów tekstowych. Poniższy listing zawiera udostępniony przez jscae opis zawartości katalogu jego aplikacji Skype oraz część zawartości jednego z plików: # ls -l /data/data/com.skype.merlin_mecha/files/jcaseap -rw-rw-rw- app_152 app_152 331776 2011-04-13 00:08 main.db -rw-rw-rw- app_152 app_152 119528 2011-04-13 00:08 main.db-journal Kup książkęPoleć książkę Częste błędy 105 -rw-rw-rw- app_152 app_152 40960 2011-04-11 14:05 keyval.db -rw-rw-rw- app_152 app_152 3522 2011-04-12 23:39 config.xml drwxrwxrwx app_152 app_152 2011-04-11 14:05 voicemail -rw-rw-rw- app_152 app_152 0 2011-04-11 14:05 config.lck -rw-rw-rw- app_152 app_152 61440 2011-04-13 00:08 bistats.db drwxrwxrwx app_152 app_152 2011-04-12 21:49 chatsync -rw-rw-rw- app_152 app_152 12824 2011-04-11 14:05 keyval.db-journal -rw-rw-rw- app_152 app_152 33344 2011-04-13 00:08 bistats.db-journal # grep Default /data/data/com.skype.merlin_mecha/files/shared.xml Default jcaseap /Default Pomijając przechowywanie danych zapisanych czystym tekstem, niebezpieczne uprawnienia do plików były skutkiem wcześniejszego, słabiej nagłośnionego problemu z natywnym tworzeniem plików w Androidzie. Wszystkie bazy danych SQLite, pliki zawierające współdzielone preferencje oraz zwykłe pliki tworzone za pomocą interfejsów Java mają uprawnienia 0660. Dzięki temu uprawnienie do odczytu i zapisu plików jest ograniczone do procesów mających taki sam identy- fikator użytkownika UID lub grupy GID. Jednak gdy takie pliki są tworzone za pomocą kodu natywnego bądź zewnętrznych poleceń, proces aplikacji dziedziczy umask tworzącego go procesu, Zygote, o wartości 000, co oznacza, że pliki uzyskują uprawnienia pozwalające wszystkim na ich odczytywanie i zapisywanie. Klient Skype korzystał z kodu natywnego do wykonywania większości operacji, łącznie z tworzeniem i obsługą plików. (cid:3)(cid:3)Od Androida 4.1 warto(cid:401)(cid:273) umask dla Zygote zosta(cid:371)a zmieniona na bezpieczniejsz(cid:268) warto(cid:401)(cid:273) 077. Wi(cid:295)cej informacji na temat tej zmiany znajduje si(cid:295) w rozdziale 12. Więcej informacji na temat odkryć w Skype ujawnionych przez jcase można znaleźć na stronie www.androidpolice.com/2011/04/14/exclusive-vulnerability-in-skype-for-android-is-exposing-your- name-phone-number-chat-logs-and-a-lot-more/. Wycieki informacji przez logi Mechanizm logów Androida jest wspaniałym źródłem wyciekających informacji. Dzięki temu, że programiści często korzystają z metod tworzących logi, z reguły podczas wyszukiwania błędów, aplikacje mogą logować wiele rzeczy, od komunikatów diagnostycznych do danych logowania lub innych wrażliwych informacji. Nawet procesy systemowe, takie jak ActivityManager, logują sto- sunkowo obszerne komunikaty na temat wywołań aktywności. Aplikacje posiadające uprawnienie READ_LOGS mogą uzyskać dostęp do tych komunikatów (za pomocą polecenia logcat). Uprawnienie READ_LOGS nie jest ju(cid:463) dost(cid:295)pne dla zewn(cid:295)trznych aplikacji od An- droida 4.1. Jednak w starszych wersjach oraz w przypadku urz(cid:268)dze(cid:375) z pe(cid:371)nym dost(cid:295)pem ze- wn(cid:295)trzne aplikacje mog(cid:268) uzyska(cid:273) dost(cid:295)p do tych uprawnie(cid:375), a tak(cid:463)e do polecenia logcat. Jako przykład dużej liczby informacji umieszczanych w logach przez ActivityManager może po- służyć poniższy listing: Kup książkęPoleć książkę 106 Rozdział 4 (cid:31) Przegląd bezpieczeństwa aplikacji I/ActivityManager(13738): START {act=android.intent.action.VIEW dat=http://www.helion.pl/ cmp=com.google.android.browser/com.android.browser.BrowserActivity (has extras) u=0} from pid 11352 I/ActivityManager(13738): Start proc com.google.android.browser for activity com.google.android.browser/com.android.browser.BrowserActivity: pid=11433 uid=10017 gids={3003, 1015, 1028} Widać tutaj uruchomienie standardowej przeglądarki internetowej, prawdopodobnie po kliknię- ciu przez użytkownika na link w wiadomości e-mail lub SMS. Szczegóły przesłanej intencji są tutaj widoczne i zawierają adres odnośnika (http://helion.pl/ksiazki/andrph.htm) do strony odwiedzanej przez użytkownika. Choć ten prosty przykład może nie wyglądać na wielki problem, w tych warun- kach pokazuje on możliwość zebrania informacji na temat stron przeglądanych przez użytkownika. Bardziej przekonujący przykład nadmiernego logowania został odnaleziony w przeglądarce Firefox dla Androida. Neil Bergman zgłosił ten problem w systemie śledzenia błędów Mozilli w grudniu 2012 roku. Firefox dla Androida logował aktywności związane z przeglądaniem stron, w tym adresy odwiedzanych stron. W niektórych przypadkach zapisywane były identyfikatory sesji, co Neil wskazał w swoim zgłoszeniu błędów i dołączonym wyniku działania polecenia logcat: I/GeckoBrowserApp(17773): Favicon successfullyloaded for URL = https://mobile.walmart.com/m/pharmacy;jsessionid=83CB330691854B071CD172D41DC2C3AB I/GeckoBrowserApp(17773): Favicon is for current URL = https://mobile.walmart.com/m/pharmacy;jsessionid=83CB330691854B071CD172D41DC2C3AB E/GeckoConsole(17773): [JavaScript Warning: Error in parsingvalue for background .Declaration dropped. {file: https://mobile.walmart.com/m/pharmacy;jsessionid=83CB330691854B071CD172D41DC2C3AB?wicket:book markablePage=:com.wm.mobile.web.rx.privacy.PrivacyPractices line: 0}] W takim przypadku złośliwa aplikacja (z dostępem do logów) mogła potencjalnie pobierać takie identyfikatory sesji i przejmować sesję ofiary w zdalnej aplikacji internetowej. Więcej szczegółów na temat tego błędu można znaleźć w systemie śledzenia błędów Mozilli pod adresem https://bugzilla. mozilla.org/show_bug.cgi?id=825685. Niezabezpieczone zakończenia IPC Wspólne zakończenia komunikacji międzyprocesowej (IPC) — usługi, aktywności, odbiorcy ko- munikatów oraz dostawcy treści — często nie są rozważane jako potencjalne punkty, na które może zostać przeprowadzony atak. Ponieważ są to zarówno źródła danych, jak i odbiorcy, sposób interakcji z nimi bardzo zależy od ich implementacji, a sposób wykorzystania ich słabości zależy od ich przeznaczenia. Na najprostszym poziomie zabezpieczanie tych interfejsów jest zazwyczaj realizowane za pomocą uprawnień aplikacji (standardowych lub autorskich). Przykładowo aplikacja może zdefiniować zakończenie IPC, które może być dostępne tylko za pomocą innych komponentów tej aplikacji, lub takie, do którego muszą mieć dostęp inne aplikacje posiadające odpowiednie uprawnienia. W przypadku gdy zakończenie IPC nie zostanie odpowiednio zabezpieczone bądź złośliwa aplikacja uzyska wymagane uprawnienie, pojawiają się specyficzne problemy przy obu rodzajach zakończeń. Dostawcy treści dają dostęp do ustrukturyzowanych danych i przez to są one podatne Kup książkęPoleć książkę Częste błędy 107 na różnego rodzaju ataki, takie jak wstrzykiwanie lub przeglądanie katalogów. Aktywności, jako komponenty prezentowane użytkownikowi, mogą potencjalnie zostać wykorzystane przez złośli- wą aplikację w ataku modyfikującym interfejs użytkownika. Odbiorcy komunikatów są często wykorzystywani do obsługi niejawnych intencji lub intencji z niedoprecyzowanymi kryteriami, jak zdarzenia systemowe. Przykładowo nadejście nowej wiado- mości SMS powoduje rozesłanie przez podsystem telefonu niejawnej intencji z akcją SMS_RECEIVED. Zarejestrowani odbiorcy komunikatów z filtrem intencji dopasowanym do tej akcji odbierają ten komunikat. Jednak atrybut opisujący priorytet w filtrze intencji (nie tylko w odbiorcach komuni- katów) może określać kolejność, w jakiej niejawna intencja jest doręczana, co może potencjalnie prowadzić do przechwytywania takich komunikatów. Niejawne intencje to intencje bez okre(cid:401)lonego konkretnego adresata, podczas gdy jawne intencje s(cid:268) skierowane do konkretnej aplikacji i komponentu tej aplikacji (takiego jak com. wiley.exampleapp.SomeActivity). Jak zostało powiedziane w rozdziale 2., usługi umożliwiają aplikacji przetwarzanie danych w tle. Podobnie jak w przypadku odbiorców komunikatów i aktywności interakcja z usługami przebiega za pomocą intencji. Są w tym akcje, takie jak uruchomienie usługi, zatrzymywanie usługi lub podłączanie do usługi. Podłączona usługa może również udostępniać dodatkową warstwę specy- ficznych dla aplikacji funkcjonalności innym aplikacjom. Ponieważ są to autorskie funkcjonalności, programista może po prostu udostępnić metodę wykonującą dowolne polecenie. Dobrym przykładem potencjalnych skutków wykorzystania niezabezpieczonego interfejsu IPC jest odkrycie dokonane przez Andre „sh4ka” Moulu w aplikacji Kies Samsunga dla Galaxy S3. Zauważył on, że Kies, aplikacja systemowa o szerokich uprawnieniach (nawet mająca uprawnie- nie INSTALL_PACKAGES), miała odbiorcę komunikatów przywracającego pakiety (APK) z katalogu /sdcard/restore. Poniższy listing zawiera kod uzyskany przez sh4ka po dekompilacji kodu Kies: public void onReceive(Context paramContext, Intent paramIntent) { ... if (paramIntent.getAction().toString().equals( com.intent.action.KIES_START_RESTORE_APK )) { kies_start.m_nKiesActionEvent = 15; int i3 = Log.w( KIES_START , KIES_ACTION_EVENT_SZ_START_RESTORE_APK ); byte[] arrayOfByte11 = new byte[6]; byte[] arrayOfByte12 = paramIntent.getByteArrayExtra( head ); byte[] arrayOfByte13 = paramIntent.getByteArrayExtra( body ); byte[] arrayOfByte14 = new byte[arrayOfByte13.length]; int i4 = arrayOfByte13.length; System.arraycopy(arrayOfByte13, 0, arrayOfByte14, 0, i4); StartKiesService(paramContext, arrayOfByte12, arrayOfByte14); return; } W kodzie widać, że metoda onReceive przyjmuje intencję paramIntent. Wywołanie getAction sprawdza, czy wartość pola opisującego akcję w paramIntent to KIES_START_RESTORE_APK. Jeśli sprawdzenie da pozytywny rezultat, metoda pobiera kilka dodatkowych wartości, nagłówek i za- wartość z paramIntent, a następnie wywołuje StartKiesService. Łańcuch wywołań doprowadza do tego, że Kies sprawdza zawartość /sdcard/restore i instaluje wszystkie zapisane tam pakiety APK. Kup książkęPoleć książkę 108 Rozdział 4 (cid:31) Przegląd bezpieczeństwa aplikacji Aby umieścić swój własny APK w /sdcard/restore, nie mając do tego uprawnień, sh4ka wyko- rzystał inny błąd, który dawał uprawnienie WRITE_EXTERNAL_STORAGE. W swoim tekście zatytułowa- nym From 0 perm app to INSTALL_PACKAGES sh4ka wykorzystał ClipboardSaveService w Sam- sungu Galaxy S3. Jest to zaprezentowane w poniższym listingu: Intent intentCreateTemp= new Intent( com.android.clipboardsaveservice. CLIPBOARD_SAVE_SERVICE ); intentCreateTemp.putExtra( copyPath , /data/data/ +getPackageName()+ /files/avast.apk ); intentCreateTemp.putExtra( pastePath , /data/data/com.android.clipboardsaveservice/temp/ ); startService(intentCreateTemp); Kod ten tworzy intencję skierowaną do com.android.clipboardsaveservice.CLIPBOARD_ (cid:180)SAVE_SERVICE, a w dodatkowych danych przekazuje ścieżkę źródłową do swojego pakietu (w ka- talogu files swojego stworzonego na potrzeby ataku sklepu z aplikacjami) oraz ścieżkę docelową /sdcard/restore. W końcu wywołanie startService wysyła tę intencję, a ClipboardService w efek- cie kopiuje APK do /sdcard. Wszystko to się dzieje, mimo że demonstracyjna aplikacja nie posiada uprawnienia WRITE_EXTERNAL_STORAGE. Przysłowiowym gwoździem do trumny jest to, że przesłanie odpowiedniej intencji do Kies powoduje zainstalowanie dowolnego pakietu: Intent intentStartRestore= new Intent( com.intent.action.KIES_START_RESTORE_APK ); intentStartRestore.putExtra( head , new String( cocacola ).getBytes()); intentStartRestore.putExtra( body , new String( cocacola ).getBytes()); sendBroadcast(intentStartRestore); Więcej informacji na temat pracy sh4ka można znaleźć na jego blogu pod adresem http:// sh4ka.fr/android/galaxys3/from_0perm_to_INSTALL_PACKAGES_on_galaxy_S3.html. Studium przypadku: Mobile Security App W tym podrozdziale zostanie przeprowadzona ocena mobilnej aplikacji Android zabezpieczającej przed kradzieżą. Wprowadzone zostaną narzędzia i techniki do statycznej oraz dynamicznej analizy oraz sposoby wykonywania podstawowych operacji inżynierii wstecznej. Celem jest to, byś lepiej zrozumiał, jak atakować poszczególne komponenty tej aplikacji, i żebyś odkrył, jakie interesujące błędy mogą pomagać w tego typu staraniach. Profilowanie W fazie profilowania zbierasz ogólne informacje na temat aplikacji i uzyskujesz obraz tego, z czym przyjdzie Ci się zmierzyć. Zakładając, że masz niewiele informacji na temat aplikacji lub nie masz żadnych informacji na jej temat na początku (nazywane jest to zerową wiedzą albo czarną skrzynką), ważne jest, by dowiedzieć się czegoś o twórcy aplikacji, jej zależnościach i innych godnych uwagi Kup książkęPoleć książkę Studium przypadku: Mobile Security App 109 właściwościach, które ona posiada. Pomoże to ustalić, jakie techniki należy wykorzystać w kolejnych fazach, a nawet samo w sobie może doprowadzić do ujawnienia błędów w przypadku odkrycia, że używana jest biblioteka lub usługa internetowa ze znaną podatnością. Najpierw ustal zastosowania aplikacji, jej twórcę oraz historię rozwoju bądź wersji. Wystarczy powiedzieć, że słabo zabezpieczone aplikacje udostępniane przez tego samego dewelopera mogą mieć podobne błędy. Rysunek 4.3 pokazuje podstawowe informacje na temat przykładowej aplikacji do odzyskiwania i ochrony przed kradzieżą na stronie internetowej Google Play. Rysunek 4.3. Opis aplikacji w Google Play Dokładniejszy przegląd tego wpisu pozwala ustalić, że wymaga ona wielu uprawnień. Po zain- stalowaniu aplikacja ta będzie miała dużo uprawnień jak na dodatkowo instalowaną aplikację. Po kliknięciu zakładki z uprawnieniami na stronie internetowej Play można zobaczyć, jakich uprawnień ona wymaga, co pokazane jest na rysunku 4.4. Korzystając z opisu i niektórych przedstawionych uprawnień, można wyciągnąć kilka wnio- sków. Na przykład opis wspomina o zdalnym blokowaniu, czyszczeniu oraz alarmach dźwięko- wych, a to po połączeniu z żądaniem uprawnienia READ_SMS może doprowadzić do wniosku, że SMS jest wykorzystywany do przesyłania niewidocznych komunikatów, co jest dość powszechne w mobilnych aplikacjach antywirusowych. Warto zapamiętać to na później, ponieważ oznacza to, że może być konieczne przeanalizowanie kodu odbierającego SMS-a. Kup książkęPoleć książkę 110 Rozdział 4 (cid:31) Przegląd bezpieczeństwa aplikacji Rysunek 4.4. Niektóre z uprawnień wymaganych przez analizowaną aplikację Analiza statyczna Faza analizy statycznej (ang. static analysis) obejmuje analizę kodu i danych w aplikacji (oraz wspierających ją komponentach) bez uruchamiania aplikacji. Na początku obejmuje to identyfi- kację interesujących ciągów znaków, takich jak znajdujące się w kodzie URI, dane identyfikacyjne lub klucze. Następnie przeprowadzasz dodatkową analizę, by skonstruować diagramy wywołań, ustalić logikę aplikacji, przepływy i ustalić potencjalne problemy z bezpieczeństwem. Choć Android SDK zawiera użyteczne narzędzia, takie jak dexdump, pozwalające zdekompilować classes.dex, użyteczne informacje można znaleźć też w innych plikach w APK. Większość tych plików ma nietypowe formaty, takie jak binarny XML, i może być trudno odczytać je za pomocą popularnych narzędzi, takich jak grep. Za pomocą narzędzia apktool, które można znaleźć pod adresem https://code.google.com/p/android-apktool/, można przekonwertować te zasoby na czysty tekst, a także zdekompilować kod wykonywalny maszyny Dalvik na format pośredni nazywany smali (tym formatem dokładniej zajmiemy się później). Kup książkęPoleć książkę Studium przypadku: Mobile Security App 111 Uruchom apktoold z nazwą pliku APK jako parametrem, aby zdekodować zawartość APK i umieścić jego zawartość w katalogu o takiej samej nazwie: ~$ apktool d ygib-1.apk I: Baksmaling... I: Loadingresource table... ... I: Decodingvalues */* XMLs... I: Done. I: Copyingassets and libs... Następnie za pomocą narzędzia grep można wyszukać interesujące ciągi znaków, takie jak ad- resy zasobów (URL) znajdujące się w aplikacji, co może pomóc w zrozumieniu komunikacji mię- dzy tą aplikacją a serwisem internetowym. Można też wykorzystać grep, aby usunąć wszystkie odwołania do schemas.android.com, ciągu znaków opisującego popularną przestrzeń nazw XML: ~$ grep -Eir https?:// ygib-1 |grep -v schemas.android.com ygib-1/smali/com/yougetitback/androidapplication/settings/xml/ XmlOperator.smali: const-string v2, http://cs1.ucc.ie/~yx2/upload/upload.php ygib-1/res/layout/main.xml: xmlns:ygib= http://www.ywlx.net/apk/res/ com.yougetitback.androidapplication.cpw.mobile ygib-1/res/values/strings.xml: string name= mustenteremail Please enter a previous email address if you already have an account on https://virgin.yougetitback.com or a new email address if you wish to have a new account to control this device. /string ygib-1/res/values/strings.xml: string name= serverUrl https://virgin.yougetitback.com /string ygib-1/res/values/strings.xml:Please create an account on https://virgin.yougetitback.com before activating this device /string ygib-1/res/values/strings.xml: string name= showsalocation http://virgin.yougetitback.com/showSALocation?cellid= /string ygib-1/res/values/strings.xml: string name= termsofuse https://virgin.yougetitback.com/terms_of_use /string ygib-1/res/values/strings.xml: string name= eula https://virgin.yougetitback.com/eula /string ygib-1/res/values/strings.xml: stringname= privacy https://virgin.yougetitback.com/privacy_policy /string ygib-1/res/values/strings.xml: string name= registration_succeed_text Account Registration Successful, you can now use the email address and password entered to login to your personal vault on http://virgin.yougetitback.com /string ygib-1/res/values/strings.xml: stringname= registrationerror5 ERROR:creatinguser account. Please go to http://virgin.yougetitback.com/forgot_password where you can reset your password, alternativelyenter a new email and password on this screen and we will create a new account for you. Thank You. /string ygib-1/res/values/strings.xml: string name= registrationsuccessful Congratulations you have sucessfully registered. You can now use this email and password provided to login to your personalised vault on http://virgin.yougetitback.com /string ygib-1/res/values/strings.xml: string name= link_accessvault Kup książkęPoleć książkę 112 Rozdział 4 (cid:31) Przegląd bezpieczeństwa aplikacji https://virgin.yougetitback.com/vault /string ygib-1/res/values/strings.xml: string name= text_help Access your online vault, or change your password at lt;a https://virgin.yougetitback.com/forgot_password lt;/a /string Choć apktool i popularne narzędzia systemu Unix są bardzo pomocne, potrzebujesz też cze- goś odrobinę mocniejszego. W tym przypadku skorzystamy z napisanego w Pythonie frameworka do inżynierii wstecznej i analiz o nazwie Androguard. Choć Androguard zawiera narzędzia dopaso- wane do konkretnych zadań, w tym rozdziale skupimy się na narzędziu androlyze działającym w trybie interaktywnym udostępnianym przez wiersz poleceń IPython. Na początek za pomocą metody AnalyzeAPK stwórz odpowiednie obiekty reprezentujące APK i jego zasoby, sam kod Dex, dodaj też opcję, by skorzystać z dekompilatora dad pozwalającego przekonwertować kod binarny do pseudokodu Java: ~$androlyze.py –s In [1]: a,d,dx = AnalyzeAPK( /home/ahh/ygib-1.apk ,decompiler= dad ) Następnie zbierz trochę dodatkowych ogólnych informacji na temat aplikacji, aby potwierdzić ustalenia z etapu profilowania. Obejmuje to takie elementy, jak: uprawnienia wykorzystywane przez aplikację, aktywności, z których użytkownik będzie najprawdopodobniej korzystał, usługi uruchamiane przez aplikację oraz innych odbiorców intencji. Najpierw sprawdź uprawnienia, wy- wołując permissions: In [23]: a.permissions Out[23]: [ android.permission.CAMERA , android.permission.CALL_PHONE , android.permission.PROCESS_OUTGOING_CALLS , ... android.permission.RECEIVE_SMS , android.permission.ACCESS_GPS , android.permission.SEND_SMS , android.permission.READ_SMS , android.permission.WRITE_SMS , ... Jest to zestaw uprawnień zgodny z tym, co zobaczyłeś w Google Play. Można pójść jeszcze krok dalej i za pomocą Androguard ustalić, jakie klasy i metody aplikacji korzystają z tych uprawnień, co może pomóc zawęzić analizę do interesujących nas komponentów: In [28]: show_Permissions(dx) ACCESS_NETWORK_STATE : 1 Lcom/yougetitback/androidapplication/PingService;- deviceOnline()Z (0x22) --- Landroid/net/ConnectivityManager;- getAllNetworkInfo()[Landroid/net/NetworkInfo; 1 Lcom/yougetitback/androidapplication/PingService;- wifiAvailable()Z (0x12) --- Landroid/net/ConnectivityManager;- getActiveNetworkInfo()Landroid/net/NetworkInfo; ... SEND_SMS : 1 Lcom/yougetitback/androidapplication/ActivateScreen;- sendActivationRequestMessage(Landroid/content/Context; Ljava/lang/String;)V (0x2) --- Landroid/telephony/SmsManager;- Kup książkęPoleć książkę Studium przypadku: Mobile Security App 113 getDefault()Landroid/telephony/SmsManager; 1 Lcom/yougetitback/androidapplication/ActivateScreen; - sendActivationRequestMessage(Landroid/content/Context; ... INTERNET : 1 Lcom/yougetitback/androidapplication/ActivationAcknowledgeService;- doPost(Ljava/lang/String; Ljava/lang/String;)Z (0xe) --- Ljava/net/URL;- openConnection()Ljava/net/URLConnection; 1 Lcom/yougetitback/androidapplication/ConfirmPinScreen;- doPost( Ljava/lang/String; Ljava/lang/String;)Z (0xe) --- Ljava/net/URL;- openConnection()Ljava/net/URLConnection; ... Choć wynik działania tego polecenia był bardzo długi, ten skrócony listing pokazuje kilka in- teresujących metod, takich jak doPost w klasie ConfirmPinScreen, która otwiera w pewnym mo- mencie gniazdo, ponieważ sprawdza posiadanie uprawnienia android.permission.INTERNET. Aby uzyskać obraz tego, co się dzieje, można teraz zdekomponować tę metodę poprzez wywołanie na niej show w androlyze: In [38]: d.CLASS_Lcom_yougetitback_androidapplication_ConfirmPinScreen. METHOD_doPost.show() ########## Method Information Lcom/yougetitback/androidapplication/ConfirmPinScreen;- doPost(Ljava/lang/String; Ljava/lang/String;)Z [access_flags=private] ##########Params -local registers: v0...v10 -v11:java.lang.String -v12:java.lang.String -return:boolean #################### ************************************************************************ doPost-BB@0x0 : 0 (00000000) const/4 v6, 0 1 (00000002) const/4 v5, 1 [ doPost-BB@0x4 ] doPost-BB@0x4 : 2 (00000004) new-instance v3, Ljava/net/URL; 3 (00000008) invoke-direct v3, v11, Ljava/net/URL;- init (Ljava/lang/String;)V 4 (0000000e) invoke-virtual v3, Ljava/net/URL;- openConnection() Ljava/net/URLConnection; 5 (00000014) move-result-object v4 6 (00000016) check-cast v4, Ljava/net/HttpURLConnection; 7 (0000001a) iput-object v4, v10, Lcom/yougetitback/androidapplication/ConfirmPinScreen;- con Ljava/net/HttpURLConnection; 8 (0000001e) iget-object v4, v10, Lcom/yougetitback/androidapplication/ConfirmPinScreen;- con Ljava/net/HttpURLConnection; 9 (00000022) const-string v7, POST 10 (00000026) invoke-virtual v4, v7, Ljava/net/HttpURLConnection; - setRequestMethod(Ljava/lang/String;)V 11 (0000002c) iget-object v4, v10, Lcom/yougetitback/androidapplication/ ConfirmPinScreen;- con Ljava/net/HttpURLConnection; 12 (00000030) const-string v7, Content-type 13 (00000034) const-string v8, application/x-www-form-urlencoded 14 (00000038) invoke-virtual v4, v7, v8, Ljava/net/HttpURLConnection;- setRequestProperty(Ljava/lang/String; Ljava/lang/String;) V Kup książkęPoleć książkę 114 Rozdział 4 (cid:31) Przegląd bezpieczeństwa aplikacji 15 (0000003e) iget-object v4, v10, Lcom/yougetitback/androidapplication/ConfirmPinScreen;- con Ljava/net/HttpURLConnection; ... 31 (00000084) const-string v7, User-Agent 32 (00000088) const-string v8, Android Client ... 49 (000000d4) iget-object v4, v10, Lcom/yougetitback/androidapplication/ConfirmPinScreen;- con Ljava/net/HttpURLConnection; 50 (000000d8) const/4 v7, 1 51 (000000da) invoke-virtual v4, v7, Ljava/net/HttpURLConnection; - setDoInput(Z)V 52 (000000e0) iget-object v4, v10, Lcom/yougetitback/androidapplication/ConfirmPinScreen;- con Ljava/net/HttpURLConnection; 53 (000000e4) invoke-virtual v4, Ljava/net/HttpURLConnection; - connect()V Na początku widzimy kilka podstawowych informacji na temat tego, jak Dalvik VM powinien zaalokować obiekty tej metody razem z kilkoma identyfikatorami samych metod. W znajdujących się poniżej wynikach dekompozycji tworzenie obiektów takich jak java.net.HttpURLConnection oraz wywołanie metody connect tego obiektu potwierdza użycie uprawnienia INTERNET. Można uzyskać bardziej czytelną wersję tej metody poprzez jej dekompilację, co daje wynik przypominający źródło Java, wywołując source na tej samej metodzie: In [39]: d.CLASS_Lcom_yougetitback_androidapplication_ConfirmPinScreen. METHOD_doPost.source() private boolean doPost(String p11, String p12) { this.con = new java.net.URL(p11).openConnection(); this.con.setRequestMethod( POST ); this.con.setRequestProperty( Content-type , application/x-www-form-urlencoded ); this.con.setRequestProperty( Content-Length , new StringBuilder().append(p12.length()).toString()); this.con.setRequestProperty( Connection , keep-alive ); this.con.setRequestProperty( User-Agent , Android Client ); this.con.setRequestProperty( accept , */* ); this.con.setRequestProperty( Http-version , HTTP/1.1 ); this.con.setRequestProperty( Content-languages , en-EN ); this.con.setDoOutput(1); this.con.setDoInput(1); this.con.connect(); v2 = this.con.getOutputStream(); v2.write(p12.getBytes( UTF8 )); v2.flush(); android.util.Log.d( YGIB Test , new StringBuilder( con.getResponseCode()— ). append(this.con.getResponseCode()).toString()); android.util.Log.d( YGIB Test , new StringBuilder( urlString-- ).append(p11).toString()); android.util.Log.d( YGIB Test , new StringBuilder( content-- ).append(p12).toString()); ... Warto zauwa(cid:463)y(cid:273), (cid:463)e dekompilacja nie jest idealna, cz(cid:295)(cid:401)ciowo z powodu ró(cid:463)nic mi(cid:295)dzy Dalvik Virtual Machine a Java Virtual Machine. Reprezentacja sterowania i przep(cid:371)ywu danych w ka(cid:463)dej z tych maszyn wp(cid:371)ywa na konwersj(cid:295) z kodu po(cid:401)redniego Dalvika do pseu- dokodu Javy. Kup książkęPoleć książkę Studium przypadku: Mobile Security App 115 Widać wywołania do metody android.util.Log.d, która zapisuje komunikat do logów z prio- rytetem debug. W takim przypadku aplikacja loguje szczegóły żądania HTTP, które mogą być in- teresującym wyciekiem informacji. Szczegółom logów przyjrzysz się trochę później. Na razie zo- baczmy, jakie zakończenia IPC mogą istnieć w tej aplikacji. Zaczniemy od aktywności. Aby to zrobić, wywołaj get_activities: In [87]: a.get_activities() Out[87]: [ com.yougetitback.androidapplication.ReportSplashScreen , com.yougetitback.androidapplication.SecurityQuestionScreen , com.yougetitback.androidapplication.SplashScreen , com.yougetitback.androidapplication.MenuScreen , ... com.yougetitback.androidapplication.settings.setting.Setting , com.yougetitback.androidapplication.ModifyPinScreen , com.yougetitback.androidapplication.ConfirmPinScreen , com.yougetitback.androidapplication.EnterRegistrationCodeScreen , ... In [88]: a.get_main_activity() Out[88]: u com.yougetitback.androidapplication.ActivateSplashScreen Nie dziwi fakt, że ta aplikacja ma wiele aktywności, w tym ConfirmPinScreen, które analizo- waliśmy. Teraz sprawdź usługi, wywołując get_services: In [113]: a.get_services() Out[113]: [ com.yougetitback.androidapplication.DeleteSmsService , com.yougetitback.androidapplication.FindLocationService , com.yougetitback.androidapplication.PostLocationService , ... com.yougetitback.androidapplication.LockAcknowledgeService , com.yougetitback.androidapplication.ContactBackupService , com.yougetitback.androidapplication.ContactRestoreService , com.yougetitback.androidapplication.UnlockService , com.yougetitback.androidapplication.PingService , com.yougetitback.androidapplication.UnlockAcknowledgeService , ... com.yougetitback.androidapplication.wipe.MyService , ... Opierając się na nazewnictwie niektórych z tych usług (np. UnlockService czy wipe), można powiedzieć, że najprawdopodobniej odbierają one i przetwarzają polecenia z komponentów in- nych aplikacji, gdy wywoływane są pewne zdarzenia. Teraz przyjrzyj się odbiorcom komunikatów w aplikacji za pomocą get_receivers: In [115]: a.get_receivers() Out[115]: [ com.yougetitback.androidapplication.settings.main.Entrance$MyAdmin , com.yougetitback.androidapplication.MyStartupIntentReceiver , com.yougetitback.androidapplication.SmsIntentReceiver , com.yougetitback.androidapplication.IdleTimeout , com.yougetitback.androidapplication.PingTimeout , com.yougetitback.androidapplication.RestTimeout , com.yougetitback.androidapplication.SplashTimeout , Kup książkęPoleć książkę 116 Rozdział 4 (cid:31) Przegląd bezpieczeństwa aplikacji com.yougetitback.androidapplication.EmergencyTimeout , com.yougetitback.androidapplication.OutgoingCallReceiver , com.yougetitback.androidapplication.IncomingCallReceiver , com.yougetitback.androidapplication.IncomingCallReceiver , com.yougetitback.androidapplication.NetworkStateChangedReceiver , com.yougetitback.androidapplication.C2DMReceiver ] Można założyć, że mamy tutaj odbiorcę komunikatów, który jest związany z przetwarzaniem wiadomości SMS prawdopodobnie do komunikacji niewidocznej dla użytkownika, takiej jak przesyłanie poleceń zablokowania i czyszczenia urządzenia. Ponieważ aplikacja wymaga upraw- nienia READ_SMS i widać tutaj ciekawie nazwanego odbiorcę komunikatów SmsIntentReceiver, są duże szanse, że manifest aplikacji zawiera filtr intencji dla komunikatów SMS_RECEIVED. Można przejrzeć zawartość AndroidManifest.xml w androlyze za pomocą kilku linii w Pythonie: In [77]: for e in x.getElementsByTagName( receiver ): print e.toxml() ....: ... receiver android:enabled= true android:exported= true android:name= com.yougetitback.androidapplication.SmsIntentReceiver intent-filter android:priority= 999 action android:name= android.provider.Telephony.SMS_RECEIVED /action /intent-filter /receiver ... Mo(cid:463)na te(cid:463) uzyska(cid:273) zawarto(cid:401)(cid:273) AndroidManifest.xml za pomoc(cid:268) jednego polecenia, u(cid:463)ywaj(cid:268)c androaxml.py z Androguard. Między innymi jest tu też element XML receiver dla klasy com.yougetitback.androidapplication. SmsIntentReceiver. Ta konkretna definicja odbiorcy zawiera element XML intent-filter z jaw- nie zapisanym elementem android:priority zawierającym wartość 999, odnoszący się do akcji SMS_RECEIVED z klasy android.provider.Telephony. Ustawiając dużą wartość tego atrybutu, apli- kacja zapewnia sobie otrzymanie komunikatu SMS_RECEIVED w pierwszej kolejności i dzięki temu dostęp do wiadomości SMS przed domyślnymi aplikacjami do przesyłania wiadomości. Zwróć uwagę na metody dostępne w SmsIntentReceiver poprzez wywołanie get_methods na tej klasie. Można skorzystać z prostej pętli for w Pythonie, by przejść przez wszystkie zwrócone metody, wywołując dla każdej show_info: In [178]: for meth in d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver.get_methods(): meth.show_info() .....: ##########Method Information Lcom/yougetitback/androidapplication/SmsIntentReceiver;- init ()V [access_flags=public constructor] ##########Method Information Lcom/yougetitback/androidapplication/SmsIntentReceiver;- foregroundUI(Landroid/content/Context;)V [access_flags=private] ##########Method Information Kup książkęPoleć książkę Studium przypadku: Mobile Security App 117 Lcom/yougetitback/androidapplication/SmsIntentReceiver;- getAction(Ljava/lang/String;)Ljava/lang/String; [access_flags=private] ##########Method Information Lcom/yougetitback/androidapplication/SmsIntentReceiver;- getMessagesFromIntent(Landroid/content/Intent;) [Landroid/telephony/SmsMessage; [access_flags=private] Lcom/yougetitback/androidapplication/SmsIntentReceiver;- processBackupMsg(Landroid/content/Context; Ljava/util/Vector;)V [access_flags=private] ########## Method Information Lcom/yougetitback/androidapplication/SmsIntentReceiver;- onReceive(Landroid/content/Context; Landroid/content/Intent;)V [access_flags=public] ... Dla odbiorców komunikatów metoda onReceive służy jako punkt wejściowy, więc można po- patrzeć na odwołania (ang. cross-references, xrefs) z tej metody, by uzyskać obraz przepływu ste- rowania. Najpierw utwórz odwołania za pomocą d.create_xref, a następnie wywołaj show_xref na obiekcie reprezentującym metodę onReceive: In [206]: d.create_xref() In [207]: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver. METHOD_onReceive.show_xref() ##########XREF T: Lcom/yougetitback/androidapplication/SmsIntentReceiver; isValidMessage (Ljava/lang/String; Landroid/content/Context;)Z 6c T: Lcom/yougetitback/androidapplication/SmsIntentReceiver; processContent (Landroid/content/Context; Ljava/lang/String;)V 78 T: Lcom/yougetitback/androidapplication/SmsIntentReceiver; triggerAppLaunch (Landroid/content/Context; Landroid/telephony/SmsMessage;) V 9a T: Lcom/yougetitback/androidapplication/SmsIntentReceiver; getMessagesFromIntent (Landroid/content/Intent;) [Landroid/telephony/SmsMessage; 2a T: Lcom/yougetitback/androidapplication/SmsIntentReceiver; isPinLock (Ljava/lang/String; Landroid/content/Context;)Z 8a #################### Widać tutaj, że onReceive wywołuje kilka innych metod, w tym te sprawdzające wiadomości SMS i przetwarzające ich treść. Zdekompiluj i dokładniej zbadaj kilka z nich, zaczynając od getMessageFromIntent: In [213]: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver. METHOD_getMessagesFromIntent.source() private android.telephony.SmsMessage[] getMessagesFromIntent(android.content.Intent p9) { v6 = 0; v0 = p9.getExtras(); if (v0 != 0) { v4 = v0.get( pdus ); v5 = new android.telephony.SmsMessage[v4.length]; v3 = 0; while (v3 v4.length) { v5[v3] = android.telephony.SmsMessage.createFromPdu(v4[v3]); v3++; Kup książkęPoleć książkę 118 Rozdział 4 (cid:31) Przegląd bezpieczeństwa aplikacji } v6= v5; } return v6; } Jest to dość typowy kod wybierający z intencji SMS PDU (Protocol Data Unit). Widać, że pa- rametr p9 do tej metody zawiera obiekt intencji. Zmienna v0 jest wypełniona wartością zwróconą z metody p9.getExtras, która zawiera wszystkie dodatkowe obiekty intencji. Następnie wywołana jest metoda v0.get( pdus ), by wybrać tylko tablicę bajtów PDU, która następnie zostaje zapisana w zmiennej v4. Później metoda tworzy obiekt SmsMessage z v4, przypisując go do v5, a potem w pętli wypełnia v5 danymi. W końcu, co może wyglądać dziwnie (prawdopodobnie w wyniku procesu dekompilacji), zmienna v6 jest również przypisana do obiektu SmsMessage jak v5, a następnie zwrócona do wywołującego. Dekompilacja metody onReceive pokazuje, że przed wywołaniem getMessagesFromIntent łado- wany jest plik współdzielonych właściwości SuperheroPrefsFile. W takim wypadku obiekt p8 reprezentujący kontekst lub stan aplikacji wywołał getSharedPreferences. Następnie wywoływanych jest kilka dodatkowych metod, by się upewnić, że wiadomość SMS jest poprawna (isValidMessage), a w końcu przetwarzana jest zawartość komunikatu (processContent) i wszystkie one otrzymują obiekt p8 jako parametr. Prawdopodobnie plik SuperheroPrefsFile zawiera jakiś element istotny dla kolejnej operacji, taki jak klucz lub PIN: In [3]: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver. METHOD_onReceive.source() public void onReceive(android.content.Context p8, android.content.Intent p9) { p8.getSharedPreferences( SuperheroPrefsFile , 0); if (p9.getAction().equals( android.provider.Telephony.SMS_RECEIVED ) != 0) { this.getMessagesFromIntent(p9); if (this != 0) { v1= 0; while (v1 this.length) { if (this[v1] != 0) { v2 = this[v1].getDisplayMessageBody(); if ((v2 != 0) (v2.length() 0)) { android.util.Log.i( MessageListener: , v2); this.isValidMessage(v2, p8); if (this == 0) { this.isPinLock(v2, p8); if (this != 0) { this.triggerAppLaunch(p8, this[v1]); this.abortBroadcast(); } }else { this.processContent(p8, v2); this.abortBroadcast(); ... Zakładając, że chcesz stworzyć poprawną wiadomość SMS do przetworzenia przez tę aplikację, prawdopodobnie zechcesz zerknąć na metodę isValidMessage, która jak widzimy na powyższym listingu, pobiera ciąg znaków wyciągnięty z wiadomości SMS za pomocą getDisplayMessageBody Kup książkęPoleć książkę Studium przypadku: Mobile Security App 119 razem z kontekstem aplikacji. Dekompilacja metody isValidMessage daje więcej informacji na ten temat: private boolean isValidMessage(String p12, android.content.Context p13) { v5 = p13.getString(1.82104701918e+38); v0 = p13.getString(1.821047222e+38); v4 = p13.getString(1.82104742483e+38); v3 = p13.getString(1.82104762765e+38); v7 = p13.getString(1.82104783048e+38); v1 = p13.getString(1.8210480333e+38); v2 = p13.getString(1.82104823612e+38); v6 = p13.getString(1.82104864177e+38); v8 = p13.getString(1.82104843895e+38); this.getAction(p12); if ((this.equals(v5) == 0) ((this.equals(v4) == 0) ((this.equals(v3) == 0) ((this.equals(v0) == 0) ((this.equals(v7) == 0) ((this.equals(v6) == 0) ((this.equals(v2) == 0) ((this.equals(v8) == 0) (this.equals(v1) == 0))))))))) { v10 = 0; } else { v10 = 1; } return v10; } Widać tutaj wiele wywołań metody getString, która działając w kontekście bieżącej aplikacji, pobiera wartości tekstowe dla podanych identyfikatorów zasobów z tabeli ciągów znaków aplika- cji, takie jak te znajdujące się w values/strings.xml. Warto jednak zauważyć, że identyfikatory za- sobów przekazywane do getString wyglądają trochę dziwnie. Jest to efekt jakiegoś błędu z propaga- cją typów w dekompilatorze, z którym szybko można sobie poradzić. Wcześniej opisana metoda pobiera te ciągi znaków z tablicy ciągów znaków, porównując je z ciągami znaków w p12. Ta metoda zwraca 1, jeśli uda się dopasować p12, lub 0, jeśli się nie uda. W metodzie onReceive ten wynik określa, czy wywołać isPinLock, czy processContent. Przyjrzyj się metodzie isPinLock: In [173]: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver. METHOD_isPinLock.source() private boolean isPinLock(String p6, android.content.Context p7) { v2 = 0; v0 = p7.getSharedPreferences( SuperheroPrefsFile , 0).getString( pin , ); if ((v0.compareTo( ) != 0) (p6.compareTo(v0) == 0)) { v2 = 1; } return v2; } Mamy to! Znowu pojawia się plik ze współdzielonymi właściwościami. Ta mała metoda wy- wołuje getString do pobrania wartości wpisu pin w SuperheroPrefsFile, a następnie porównuje to z p6 i zwraca informację, czy wynik porównania by
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:


Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: