Testarea Fuzzing a Intent Urilor Android

Cuprins

1.Introducere 5

2.1 Drozer 6

2.2 Intent Fuzzer 7

3. Metode de comunicare între componentele sistemului Android – Intents 9

4.Metode de testare negativă a intent-urilor – Fuzzing 13

5.Arhitectura BIFUZ 15

5.1.Implementare BIFUZ 16

5.2.Execuția proiectului BIFUZ de pe platforma Linux 18

5.3. Execuția proiectului BIFUZ din aplicația Android 20

6. SQL Injection 23

6.1.Exemplificarea SQL injection pe aplicația Android Sieve 26

6.2.Sql Injection de pe platforma Linux 27

6.3.SQL Injection de pe platforma Android 29

7. Rezultate obținute 31

8.Concluzii și dezvoltări ulterioare 34

8.1.Concluzii 34

8.2.Dezvoltări ulterioare 34

9.BIBLIOGRAFIE 35

Tabel cu figuri

Figura 2.1.1 Rularea aplicației Drozer 6

Figura 2.2.1 Rularea aplicației Intent Fuzzer 7

Figura 3.1.Arhitecutura Android 9

Figura 3.2 Execuția unui Intent implicit 11

Figura 4.1.Testarea fuzzing 13

Figura 4.2 Principiile testării fuzzing 14

Figura 5.1. Arhitectura proiectului BIFUZ 15

Figura 5.2.1.Execuția BIFUZ de pe Linux 19

Figura 5.3.1.Execuția Bifuz de pe platforma Android 22

Figura 6.1.Exemplu de Content Provider 23

Figura 6.2.Interacțiunea cu un Content Provider 25

Figura 6.1.1. Rularea aplicației Sieve 26

Figura 6.2.1.Rularea SQL injection din platforma Linux 27

Figura 6.2.2. SQL java.lang.SecurityException 28

Figura 6.3.1 SQL injections din BIFUZ 30

Figura 7.1.Exemplu excepție java.lang.NullPointerExcepțion la rularea unui intent 31

Figura 7.2 Numărul de excepții rezultate în urma testării a mai multor intent-uri 32

Figura 7.3 Timpul de execuție la rularea mai multor sesiuni de intent-uri 33

Figura 7.4. Rezultatele obținute în urma rulării mai multor sesiuni de intent-uri 33

Abstract

Popularitatea sistemului de operare Android a luat amploare în ultimii ani. Prin urmare, numărul dezvoltatorilor de aplicații a crescut semnificativ, conducând astfel la apariția de noi tipuri de vulnerabilități. Având în vedere faptul că, pe piața Android nu există încă un instrument complet de testare a securității unei aplicații, foarte multe din acestea nu sunt testate suficient înainte de lansare. Această lucrare are ca scop principal prezentarea unei soluții menite să vină în ajutorul oricărui dezvoltator de aplicații Android, prin asigurarea testării vulnerabilităților unei aplicații. Din moment ce intent-urile reprezintă conexiunea cea mai strânsă prin care aplicațiile unui sistem interacționează, putem afirma faptul că, funcționarea corespunzătoare a mecanismului de comunicare între procese (Inter Process Communication) este esențială pentru asigurarea securității. Aplicația creată în cadrul proiectului va genera și va trimite intent-uri negative către un dispozitiv și va monitoriza comportamentul acestuia, oferind astfel posibilitatea de a testa orice aplicație Android instalată pe un dispozitiv.

1.Introducere

Creșterea continuă a popularității dispozitivelor ce utilizează sistemul de operare Android a dus la o creștere semnificativă a numărului de dezvoltatori de aplicații.

Prin urmare, au apărut pe piața Android tot mai multe aplicații și implicit acest lucru a condus la apariția de noi tipuri de vulnerabilități de securitate.

În primul rând, pentru a putea menține securitatea unei aplicații, trebuie să analizăm modul de funcționare și comportamentul acesteia atunci când comunică cu alte aplicații din sistem prin intermediul intent-urilor. Putem spune că intent-urile reprezintă legătura cea mai importantă dintre aplicațiile Android, funcționarea corespunzătoare a mecanismului de comunicare între procese (IPC) fiind esențială pentru asigurarea securității.

Intent-ul este o instanță a clasei android.content.Intent. Această instanță este transmisă mai departe unor metode de tipul startActivity() sau startService(). Prin intermediul acestora, se pot invoca anumite componente de tipul activități, servicii și se pot emite broadcast-uri. Aceste intent-uri primesc mai multe tipuri de parametrii. Unii dintre ei trebuie să conțină doar date valide, însă alții pot conține date malformate, acestea din urmă reprezentând un interes deosebit pentru atacatori. Pentru a testa comportamentul acestora în sistemele Android, am generat o serie de intent-uri cu parametrii diferiți către mai multe aplicații din sistem prin intermediul testării fuzzing.

Testarea fuzzing reprezintă o tehnică de testare negativă ce are la bază introducerea de date aleatorii sau false la intrarea într-un program. Aplicând această tehnică pe intent-uri, putem observa modul în care o aplicație reacționează la invocarea unei componente cu parametrii falși, testându-se astfel vulnerabilitatea ei.

Securitatea unei aplicații este dată și de conținutul fișierelor de tipul AndroidManifest.xml. În aceste fișiere sunt setate toate permisiunile acordate unei aplicații. Așa cum am putut observa din analiza acestora, multe aplicații Android permit accesul din exterior la componentele și la datele lor. Astfel, orice aplicație poate să lanseze execuția uneia din componente cu anumiți parametrii prin intermediul intent-urilor.

În această lucrare sunt exploatate toate aceste vulnerabilități. Aplicația creată în acest scop, Broadcast Intent Fuzzing Framework for Android, are la bază următoarele funcționalități: generarea de intent-uri cu parametrii random pentru a testa negativ și pentru a monitoriza modul în care aplicațiile de pe un dispozitiv reacționează în funcție de securitatea lor, precum și generarea de query-uri sql prin care se încearcă preluarea și manipularea bazelor de date dintr-o aplicație.

Aplicația va genera și va trimite intent-uri malformate către alte aplicații și va monitoriza comportamentul acestora. După aceea se va analiza output-ul sistemului și se vor genera fișiere seed-files, ce conțin lista cu toate intent-urile rulate până în momentul execuției eșuate a unui intent. Aceste fișiere sunt foarte utile pentru recrearea contextului în care am găsit o eroare a unei aplicații. Prin urmare, se vor putea retesta listele de intent-uri ce au dus la generarea unei erori a unui pachet.

În cea de-a doua parte a lucrării sunt analizate vulnerabilitățile content provider-ilor, ce reprezintă modalitatea prin care se poate partaja și controla transferul de date între aplicații și oferă soluția de stocare persistentă a unor date. Astfel se va testa manipularea bazelor de date ale aplicațiilor Android prin crearea de query-uri sql (Standard Query Language) de tip projection sau injection.

2. State of the art

Pentru a testa securitatea dispozitivelor ce utilizează sistemul de operare Android, au fost create mai multe aplicații ce au ca scop găsirea vulnerabilităților care duc la oprirea unei aplicații sau a sistemului. Cele mai importante dintre acestea sunt reprezentate de Drozer și Intent Fuzzer.

2.1 Drozer

Drozer este în topul aplicațiilor de securitate pentru platformele Android și a făcut mult mai facilă testarea vulnerabilităților aplicațiilor Android. Acesta poate să interacționeze cu alte aplicații instalate pe un dispozitiv Android și poate îndeplini oricare din funcțiile pe care acestea le au. Utilizând mecanismul de comunicare între procese al aplicațiilor, IPC(Inter-Process Communication), este posibilă interacționarea cu orice parte a sistemului de operare.

Drozer are un rol semnificativ în exploatarea vulnerabilităților, prin crearea de fișiere malițioase destinate unor atacuri asupra dispozitivelor Android. În funcție de permisiunile pe care o aplicație le oferă, Drozer poate să lanseze un atac la această aplicație prin injectarea de cod SQL.

Pentru a utiliza Drozer, este nevoie de un laptop/calculator și de un dispozitiv sau un emulator Android. Se instalează agentul Drozer (apk-ul aplicației) pe dispozitiv și platforma Drozer pe laptop și se deschide o sesiune nouă.

Comunicarea se face prin consola Drozer în linia de comandă, asemenea unor terminale Linux. Din consolă se pot porni activități ale aplicațiilor Android de pe dispozitiv/emulator, se pot prelua informații ale pachetelor instalate, se pot citi informații din bazele de date ale aplicației (content-providers), se poate rula injecție de cod SQL. Un exemplu cu modul de funcționare al aplicației Drozer se află în figura 2.1.1. În partea dreaptă se află un emulator Android cu agentul Drozer instalat, iar în partea stângă se află rularea efectivă din consolă.

2.2 Intent Fuzzer

Intent Fuzzer este un utilitar care poate fi utilizat pe orice dispozitiv care folosește sistemul de operare Android. Așa cum se poate observa din titlu, aplicația este un instrument de fuzzing, de testare negativă, ce are ca scop găsirea vulnerabilităților care duc la oprirea unei aplicații sau a sistemului.

Intent fuzzer poate testa o singură componentă a unei aplicații sau poate testa toate componentele deodată. Aplicația creează intent-uri și broadcast-uri către toate celelalte aplicații din sistem. Preia mai întâi toate pachetele instalate pe dispozitiv și afișează într-un spinner Android toate componentele. După aceea, utilizatorul poate alege ce aplicație vrea să testeze, selectând una din componentele disponibile. După ce a fost selectată o aplicație, se vor lista toate activitățile, broadcast-urile, serviciile disponibile pentru acea aplicație și se poate porni testarea lor prin selectarea uneia din opțiuni: Null Fuzz Single sau Null Fuzz All.

Am exemplificat funcționarea aplicației Intent Fuzzer în figura 2.2.1. alegând o aplicație si testând trimiterea unui intent la ea. Intent-ul a fost trimis cu succes:

”Sent:Intent{cmp=com.tedrasoft.revealpicture1/.MainActivity}”

2Figura 2.2.1 Rularea aplicației Intent Fuzzer

Aplicația BIFUZ îndeplinește aproape toate funcțiile aplicației Drozer, dar aduce și îmbunătățiri semnificative. La Drozer, totul se rulează din linia de comandă. La BIFUZ nu este nevoie decât de un dispozitiv Android și astfel se va facilita testarea vulnerabilităților sistemului de către orice dezvoltator de aplicații. Astfel, oricine poate utiliza aplicația fără a necesita cunoștințe de shell.

Asemenea aplicației Intent Fuzzer, BIFUZ testează componentele tuturor aplicațiilor din sistem, preluând toate pachetele instalate pe un dispozitiv. În plus, BIFUZ nu testează doar vulnerabilitățile mecanismului de intercomunicare între procese, ci le testează și pe cele ale bazelor de date din aplicații, ale content provider-ilor, prin sql injection.

Spre deosebire de Drozer și Intent Fuzzer, BIFUZ oferă opțiunea de a recrea contextul în care o aplicație a generat o eroare prin salvarea listei tuturor intent-urilor generate până la apariția unei excepții.

3. Metode de comunicare între componentele sistemului Android – Intents

Pentru a înțelege procesul de inter-comunicare între componentele sistemului, este important să cunoaștem mai întâi arhitectura sistemului de operare Android

3Figura 3.1.Arhitecutura Android

Așa cum putem observa din figura 3.1, la baza arhitecturii Android se află kernelul Linux care reprezintă nivelul de abstractizare între componenta hardware și cea software. Kernelul Linux furnizează funcționalitățile de bază ale sistemului, cum ar fi: managementul memoriei, al proceselor și al tuturor driverelor.

Următorul nivel al arhitecturii este reprezentat de librăriile de bază ale sistemului de operare: Surface Manager, Media Framework, SSL, SGL.

Al treilea nivel este Android RunTime, care are la bază mașina virtuală Dalvik. DVM permite rularea fiecărei aplicații într-un proces propriu și utilizează fișiere speciale .dex, ce au anumite limitări din punct de vedere al vitezei procesorului, precum și al memoriei.

Nivelul Application Framework reprezintă interacțiunea directă a aplicațiilor cu sistemul. Acest nivel gestionează funcționalitățile de bază ale unui dispozitiv, cum ar fi :

• Managementul activității (ActivityManager)-monitorizează ciclul de viață a unei activități

• Managementul pachetelor (PackageManager)

• Managementul ferestrelor (WindowManager)

• Managementul telefonului (TelephonyManager)

• Managementul Providerulului de conținut (ContentProvider)

• Gestiunea resurselor (ResouseManager)

• Sistemul de vizualizare (ViewSystem)

• Managementul locațiilor (LocationManager) și Serviciile XMPP (XMPP_Service)

• Managementul notificărilor (NotificationManager)

Ultimul nivel din arhitectura Android este cel al aplicațiilor și este reprezentat de aplicațiile de bază ce se sunt instalate pe dispozitiv în mod implicit. Cele mai reprezentative dintre acestea sunt:

aplicația Home

aplicația de apelare un contact

aplicația de trimitere a unui mesaj

aplicația calendar

aplicația e-mail

aplicația de pornire a camerei foto/video

Fiecare aplicație Android este compusă din mai multe componente care încapsulează logica aplicației. Există patru tipuri de componente: Activities, Services, Content Providers și Broadcast Receivers,iar fiecare din acestea poate fi securizată într-un mod diferit.

Activitățile sunt asociate unei ferestre, unei interfețe grafice, o aplicație Android fiind formată din una sau mai multe activități. Un exemplu este Facebook, pagina de login a unei aplicații.

Serviciile încapsulează procese mai complexe, executate în fundal, a căror rulare durează o perioadă de timp semnificativă, astfel încât să nu poată fi plasate în cadrul aceluiași fir de execuție ca interfața grafică. Serviciile sunt gestionate de o instanță a clasei Service și nu necesită interacțiunea cu interfața. Un exemplu ar putea fi o aplicație de ascultat muzică ce se execută în fundal.

Componenta Content Provider este implementată de o subclasă a clasei ContentProvider și reprezintă modalitatea prin care se poate partaja și controla transferul de date între aplicații, oferind astfel soluția de stocare persistentă a unor date. Un Content Provider poate fi văzut ca o interfață a unei baze de date creată cu standardul Android, SQLite database.

Componenta Broadcast Receivers este implementată de o subclasă a clasei BroadcastReceiver și răspunde la mesajele propagate de alte aplicații sau chiar de aplicația din care face parte.

Activitatea este una dintre cele mai importante componente ale unei aplicații Android deoarece este strâns legată de interfața cu utilizatorul. O activitate este utilizată pentru a gestiona interfața cu utilizatorul și este echivalentă cu fereastra sau formularul din aplicațiile desktop.

În tabelul 3.1 se află numărul de componente pentru câteva din aplicațiile cele mai căutate pe Google Play.

Tabelul 3.1.Numărul de componente ale aplicațiilor din topul Google PlaY

Declarația tuturor componentelor unei aplicații și a capabilităților lor se găsește în fișierul “AndroidManifest.Xml”. Acesta conține permisiunile componentelor de care alte aplicații au nevoie pentru a le putea accesa. Interacțiunea între componente se face prin intermediul intent-urilor.

Intent-ul reprezintă modalitatea de bază ce permite trimiterea de mesaje către alte aplicații sau chiar către alte componente din cadrul aceleiași aplicații. Pentru a trimite un mesaj, trebuie să fie creat un obiect de tip Intent. Prin acesta se poate specifica pornirea unei anumite componente cu anumite date.

Intent-urile pot sa fie de două feluri: explicite, care vizează o singură componentă specifică sau implicite, care se referă la o acțiune dorită (deschiderea unei pagini web de exemplu), fără a selecta componenta care să execute această operație.

De exemplu, pentru a porni din activitatea curentă o altă activitate numită secondActivity se folosește următoarea structură de creare a unui intent explicit:

Intent myIntent = new Intent(myContext,com.example.testapps.secondActivity.class);

myContext.startActivity(myIntent);

În figura 3.2 avem un exemplu cu modul de funcționare al unui intent implicit:

1.Activitatea A creează un intent, urmând ca apoi să îl trimită ca argument funcției startActivity()

2.Sistemul Android caută în tot sistemul o aplicație care să corespundă intent-ului primit, bazându-se pe parametrii acestuia.

3.Sistemul pornește activitatea găsită (activitatea B) pentru acel intent prin invocarea metodei OnCreate(), specifică activității B.

4Figura 3.2 Execuția unui Intent implicit

Există două mecanisme care controlează accesul către componentele unei aplicații din interiorul unei alte aplicații.

Primul mecanism este reprezentat de atributul exported, care se află în fișierul AndroidManifest.xml. Valoarea lui implicită este “false”, acest lucru semnificând faptul că numai componentele din interiorul aceleiași aplicații au dreptul de a accesa componenta specifică. Altfel, componenta poate fi accesată și din interiorul altor aplicații prin intent-uri.

Componentele exportate au în mod uzual și niște filtre ce specifică tipurile de intent-uri implicite pe care sunt capabile sa le primească. Prin aceste filtre, componenta este expusă automat către alte aplicații din sistem.

Cel de-al doilea mecanism care controlează expunerea unei componente este reprezentat de permisiuni. Fiecare componentă poate specifica anumite permisiuni pe care alte aplicații trebuie să le dețină pentru a o putea accesa.

4.Metode de testare negativă a intent-urilor – Fuzzing

Fuzzing sau testarea negativă este o tehnică software utilizată în scopuri etice pentru a descoperi vulnerabilități sau erori de cod. Această tehnică are la bază injectarea de date random, malițioase, în încercarea de a face un sistem sa eșueze. În sistemele Android ne putem folosi de tehnica fuzzing încercând să accesăm anumite componente ale unei aplicații Android prin crearea unor intent-uri cu anumiți parametri random.

Pentru fiecare aplicație Android, fluxul de lucru pentru testarea negativă este format din patru etape: extragerea componentelor, analiza statică, generarea de intent-uri și fuzzing-ul de date, așa cum se poate observa și din figura 4.1.

5Figura 4.1.Testarea fuzzing

Prin extragerea datelor se identifică toate componentele exportate și acțiunile lor, necesare pentru etapele următoare. Etapa de analiză statică constă în obținerea structurii de bază a intent-urilor specifice aplicației respective. După această etapă, urmează etapa de generare de intent-uri formate corespunzător. Fuzzing-ul de date este ultima etapă. Aici se inserează date random în intent-uri, urmând a fi puse în execuție cu acestea.

6Figura 4.2 Principiile testării fuzzing

Principiile care stau la baza testării fuzzing, așa cum sunt exemplificate in figura 4.2, se respectă și în testarea fuzzing a sistemelor Android. În cadrul proiectului BIFUZ, mai întai am identificat datele de intrare respectiv, parametrii intent-urilor. Pe baza acestora am creat datele de fuzzing prin generarea de intent-uri cu date random ce pornesc broadcast-uri sau activități. După aceea am monitorizat comportamentul aplicațiilor pornite prin intermediul logcat-ului, ce conține output-ul sistemului Android.

5.Arhitectura BIFUZ

Proiectul BIFUZ are două părți, una de Linux și alta de Android, ambele având aceeași arhitectură. El are la bază mai multe funcționalități de testare a vulnerabilităților aplicațiilor. Cele mai reprezentative sunt generarea de intent-uri cu parametrii random pentru a testa negativ și pentru a monitoriza modul în care aplicațiile de pe un dispozitiv reacționează în funcție de securitatea lor, precum și generarea de query-uri sql prin care se încearcă preluarea și manipularea bazelor de date dintr-o aplicație.

În figura 5.1 este reprezentată arhitectura proiectului BIFUZ, ce constă în mai multe etape:

Preluarea informațiilor necesare despre un pachet din dispozitivul Android; pe Linux această etapă este realizată prin intermediul utilitarului ADB, iar din aplicația Android datele sunt preluate cu ajutorul clasei Java, Package Manager(1);

Generarea parametrilor de fuzzing ai intent-urilor (2);

Generarea și lansarea intent-urilor cu parametri fuzzy (3);

Etapa de analiză a rezultatelor (4).

În urma etapei de analiză, pentru a putea găsi vulnerabilitățile unei aplicații, sunt generate mai multe fișiere de log (conțin output-ul cu log-ul sistemului Android în urma unei sesiuni de intent-uri ) și fișiere de tip seed-files. Fișierele seed-files conțin lista cu toate intent-urile rulate până în momentul în care s-a produs o eroare și s-a generat o excepție. Prin urmare, se poate retesta un pachet în același context în care a fost generată eroarea. Din proiectul BIFUZ de pe platforma Linux există și opțiunea de generare și instalare a apk-ului aplicației BIFUZ de pe platforma Android direct pe dispozitivul de test și copierea tuturor seed-file-urilor existente pentru testarea ulterioară.

7Figura 5.1. Arhitectura proiectului BIFUZ

5.1.Implementare BIFUZ

Implementarea instrumentului de fuzzing a fost făcută pe platforma Linux și pe platforma Android pentru a facilita testarea sistemelor Android de către utilizatori. Implementarea a fost făcută în limbajele de programare Python și Java, împreună cu framework-ul Kivy, utilizat pentru crearea de aplicații Android.

Am pornit de la proiectul open-source BIFUZ de pe platforma Linux, creat de Andreea Brîndușa Proca, Răzvan-Costin Ionescu, Bogdan Alexandru Ungureanu, în cadrul firmei Intel. Proiectul este scris în Python și testează vulnerabilitățile aplicațiilor din interiorul unui dispozitiv Android, dintr-o consola Linux, de pe un calculator/laptop. În aplicația BIFUZ de pe platforma Android am portat majoritatea dintre aceste funcționalități. Am lucrat în limbajul Python, utilizând framework-ul Kivy pentru crearea de aplicații Android și am utilizat și anumite clase din Java.

Implementarea constă în generarea de cât mai multe intent-uri cu parametrii diferiți și monitorizarea comportamentului activităților prin analizarea logcat-ului.

La generarea unui intent, se folosesc parametrii random pentru a face testarea fuzzing. Așa cum am specificat anterior, un obiect Intent deține informații pe care sistemul Android le folosește pentru a determina pe care componentă să o pornească. Un exemplu ar fi numele exact al componentei sau categoria acesteia, pe care ar trebui să o primească intent-ul, plus informațiile pe care aplicația destinatar le folosește în scopul de a îndeplini în mod corespunzător acțiunea respectivă.

Partea de fuzzing a fost făcută manipulând toți parametrii unui intent. Cei mai reprezentativi sunt următorii:

acțiunea (action) ce trebuie executată,indicată prin proprietatea android:name;

categoria (category);

datele (data),ce reprezintă informațiile care vor fi procesate, fiind exprimate de obicei sub forma unui URI; poate fi un număr de telefon (prefixat de tel:), datele unei persoane din lista de contacte (prefixate de content://contacts/people), coordonate geografice (prefixate de geo:) sau o adresă Internet (prefixată de http://www.); pot fi specificate o serie de proprietăți (în orice combinație) pentru a indica datele suportate de componenta respectivă;

extra (extra) este un obiect de tip Bundle care conține informații suplimentare cu privire la componenta respectivă;

Acești parametrii pot fi setați manual. Un exemplu de un intent pentru crearea și trimiterea unui mesaj pe telefon cu parametrii setați manual (acțiune, date-extra și tipuri) este următorul:

Intent myIntent = new Intent();

myIntent.setAction(Intent.ACTION_SEND);

myIntent.putExtra(Intent.EXTRA_TEXT, textMessage);

myIntent.setType(HTTP.PLAIN_TEXT_TYPE);

startActivity(sendIntent);

Exemple de tipuri de acțiuni folosite în generarea intent-urilor sunt prezentate în tabelul 5.1.1:

Tabelul 5.1.1.Tipuri de acțiuni folosite în generarea intent-urilor

Am manipulat acești parametrii generând anumite date aleatorii. De exemplu, pentru categorie, am ales la crearea fiecărui intent o valoare din categoriile de bază Android.

În tabelul 5.1.2 am exemplificat listele de categorii, de date extra si de flag-uri utilizate în generarea intent-urilor.

Tabelul 5.1.2 Liste cu categorii, cheile extra si flag-urile Android

5.2.Execuția proiectului BIFUZ de pe platforma Linux

Pentru partea proiectului BIFUZ ce presupune rularea din consolă Linux, dispozitivul trebuie conectat prin USB la laptop/calculator și trebuie setat din setările acestuia modul de developer.

Meniul proiectului BIFUZ de pe platforma Linux este reprezentat în figura 5.2.1. Acesta oferă mai multe opțiuni, printre care: alegerea dispozitivului de test (opțiunea 1 din meniu), generarea de Broadcast-uri sau intent-uri fuzzy (opțiunile 2 și 3), lansarea în execuție a listelor de intent-uri din seed file-uri (opțiunea 5), testarea de query-uri de tip sql injection (opțiunea 6) sau generarea și instalarea aplicației BIFUZ direct pe dispozitiv (opțiunea 7).

Intent-urile se generează și se pornesc prin intermediul utilitarului ADB(Android Debug Bridge), ce permite comunicarea cu un dispozitiv Android. Utilitarul este un program de tipul client-server care include trei componente: un client, un server și un deamon (care rulează ca un proces background pe fiecare dispozitiv). Exemple de comenzi de rulare ADB:

“adb logcat”-returnează logcat-ul sistemului (foarte util în depanarea problemelor unei aplicații)

“adb dumpsys” –returnează informații despre sistemul Android al dispozitivului

“adb shell am broadcast -n com.android.phone/com.android.phone.SipBroadcastReceiver” – lansează în execuție un Broadcast Intent cu numele componentei dat ca parametru după „-n”

“adb shell am start -a android.settings.INPUT_METHOD_SETTINGS -c android.intent.category.LAUNCHER -n

com.instagram.android/com.instagram.android.activity.TumblrAuthActivity -f 0x00200000 -d https://7UY4QRVBG1IQ36OBFVXUEEBLKY.gov -e double android.intent.extra.CC 73” – lansează în execuție un intent cu anumiți parametrii aleși random care au fost setați manual.

În urma generării unor intent-uri cu parametrii diferiți, unele aplicații vor genera erori la pornire. Proiectul BIFUZ analizează aceste erori și pe baza lor, se construiesc anumite seed-file-uri cu toate intent-urile rulate până la momentul în care o aplicație s-a oprit. Acest lucru este posibil analizând output-ul sistemului Android, prin intermediul comenzii “adb logcat”. Pe baza acestor fișiere, se poate recrea contextul în care un intent al unei aplicații a generat o eroare, selectând din meniul BIFUZ opțiunea 5 : Run existing generated intents from file.

Alegând opțiunea 7, Generate apks for specific Intent calls, se va instala automat pe dispozitiv apk-ul aplicației BIFUZ, implementată pe platforma Android.

Opțiunea 9, Smart fuzzing – using a template, permite generarea de intent-uri după anumite șabloane, ce definesc parametrii care vor fi fuzzy. Astfel, se poate genera un intent cu toți parametrii fuzzy sau doar cu o parte dintre ei.

5.3. Execuția proiectului BIFUZ din aplicația Android

Crearea unei aplicații Android care sa găsească vulnerabilitățile sistemului, oferă unui dezvoltator de aplicații Android o modalitate mai ușoară de a își testa propriile aplicații. Având aplicația BIFUZ instalată direct pe un dispozitiv, nu mai este nevoie de un laptop sau de o consolă Linux. Testarea securității aplicațiilor din sistemul Android se poate face direct de pe dispozitiv.

Partea de generare de intent-uri funcționează în mai multe etape. Mai întâi sunt preluate toate pachetele (aplicațiile) instalate pe dispozitiv. Utilizatorul alege apoi unul din acestea pe care dorește să îl testeze. După aceea, sunt generate intent-uri pentru fiecare din activitățile disponibile în acel pachet și se pornește rularea lor. Proiectul oferă testarea a două tipuri de componente: Activități și Broadcast Receivers.

Generarea intent-urilor din aplicația BIFUZ de pe dispozitiv se face utilizând funcționalitățile următoarelor clase Java Android: PackageManager și Intent.

Rularea unui intent se face în fundalul activității principale, pentru ca execuția lui să fie independentă. Implementarea s-a realizat utilizând funcționalitățile clasei Java abstracte AsyncTask, care asigură utilizarea corectă a thread-ului principal răspunzător de interfața cu utilizatorul, UI. Această clasă permite executarea în fundal a unor operații și trimiterea rezultatului lor înapoi la terminare. Proiectul BIFUZ este implementat cu framework-ul Kivy-Android. De aceea a fost nevoie de implementarea unei librării în Java care să conțină o clasă ce extinde AsyncTask în scopul de a folosi funcționalitățile ei în proiectul BIFUZ.

Prin urmare, este generată o instanță, a clasei AsyncTask , ce primește parametrii necesari pentru execuția unui intent. Un exemplu pentru crearea unui task de execuție pentru un intent de tip Activity este următorul:

task=AsyncTask(PythonActivity.mActivity) task.execute("intent",packageName,packageClass,act,cat,flag,data,e_type,e_key,ev,command)

Clasa abstractă AsyncTask are două metode de bază: doInBackground() și onPostExecute(). Metoda doInBackground()a fost suprascrisă implementând lansarea în execuție a unui intent cu diverși parametrii.

Intent i=new Intent();

i.setComponent(new ComponentName(params[1], params[2]));

i.setAction(params[3]);

i.addCategory(params[4]);

int f=Integer.parseInt(params[5].substring(3),16);

i.addFlags(f);

i.setData(Uri.parse(params[6]));

String extra_type = params[7];

if (extra_type.equals("boolean")){ i.putExtra(params[8], Boolean.parseBoolean(params[9]));

}

else {

i.putExtra(params[8], Integer.parseInt(params[9]));

}

context.startActivity(i);

În metoda onPostExecute(), executată la finalizarea task-ului de creare a unui intent, se preia output-ul (log-ul) aplicației pentru a se vedea rezultatul testării. Preluarea output-ului însă, nu mai este la fel de ușor de făcut precum în testarea aplicației de pe platforma Linux. Din consola Linux aveam control total asupra dispozitivului. Din interiorul unei aplicații de pe un dispozitiv însă, nu se poate obține același control, din motive de securitate. Începând cu versiunea sistemului de operare Android Jelly Bean, nu mai este permis accesul dintr-o aplicație la log-ul tuturor celorlalte aplicații. Înainte se obținea accesul la logcat-ul sistemului cu ajutorul permisiunii “android.permission.READ_LOGS”. Acum nu mai este posibil acest lucru, decât în condițiile în care dispozitivul Android este rutat.

În figura 5.3.1 am exemplificat modul în care este testat Broadcast fuzzing direct pe un dispozitiv.

Mai întâi utilizatorul își alege din meniu opțiunea Broadcast BIFUZ. După aceea urmează alegerea pachetului pe care dorește să îl testeze. Astfel se vor lansa în execuție toți receiver-ii corespunzători acelui pachet și se va afișa în partea de jos a ecranului, sub forma unui mesaj de tip Android Toast, comanda utilizată. Dacă telefonul este rutat, în cazul în care lansarea unui intent va eșua, se vor genera un fișier de tip seed-file ce conține toate intent-urile rulate până în momentul respectiv. Fișierele seed-file au comenzi ADB ce conțin intent-ul și parametrii cu care a fost rulat. Fișierele seed au același format pentru implementarea BIFUZ de pe Linux, precum și pentru implementarea de pe platforma Android. Prin urmare se poate face testarea unui dispozitiv prin ambele metode fără eforturi suplimentare din partea utilizatorului.

Un exemplu de fișier seed ce a fost generat de componenta com.android.email/com.android.email.service.EmailExternalReceiver conține următoarele intrări:

adb shell am broadcast -n com.android.deskclock/com.android.deskclock.AlarmReceiver

adb shell am broadcast -n com.android.deskclock/com.android.deskclock.AlarmInitReceiver

adb shell am broadcast -n com.android.deskclock/com.android.alarmclock.AnalogAppWidgetProvider

adb shell am broadcast -n com.android.deskclock/com.android.alarmclock.AnalogAppWidgetProvider2

adb shell am broadcast -n com.android.deskclock/com.android.deskclock.PackageDataClearedReceiver

adb shell am broadcast -n com.android.email/com.android.email.service.AttachmentDownloadService$Watchdog

adb shell am broadcast -n com.android.email/com.android.email.service.EmailBroadcastReceiver

adb shell am broadcast -n com.android.email/com.android.email.SecurityPolicy$PolicyAdmin

adb shell am broadcast -n com.android.email/com.android.email.service.EmailExternalReceiver

Toate intent-urile conținute în fișier au fost executate până la ultimul, acesta generând eroare.

9Figura 5.3.1.Execuția Bifuz de pe platforma Androi

6. SQL Injection

SQL injection reprezintă vulnerabilitatea cu cel mai mare impact asupra bazelor de date. Atunci când atacatorul poate manipula query-urile SQL (clauze de tip SELECT, WHERE) pe care o aplicație le trimite mai departe unei baze de date, se produce atacul numit SQL Injection.

În cea de-a doua parte a proiectului BIFUZ am făcut o analiză asupra Content Provider-ilor unei aplicații și asupra modului în care query-urile acestora pot genera atacuri SQL injection. Aceste atacuri reprezintă modalitatea prin care se poate partaja și controla transferul de date între aplicații.

În majoritatea cazurilor, datele Content Provider-ilor sunt stocate în baze de date SQL. Acestea folosesc identificatorul _id pentru cheia primară.Utilizatorii au acces la conținutul content-urilor prin intermediul query-urilor.Datele suportate de provideri includ tipurile: integer, float, long, double și BLOB (Binary Large Object).

În figura 6.1 este exemplificat un Content Provider.Așa cum se poate observa, un obiect de tipul Content Provider poate stoca datele dintr-o bază de date, dintr-un fișier, sau dintr-un server. Toate celelalte componente ale aplicației pot accesa aceste date.

Ele pot fi accesate chiar și din alte aplicații, dacă au permisiunile necesare.

10Figura 6.1.Exemplu de Content Provider

Un Content Provider are mai multe atribute și se declară în fișierul AndroidManifest.xml în următorul mod :

<provider android:authorities="list"

android:enabled=["true" | "false"]

android:exported=["true" | "false"]

android:grantUriPermissions=["true" | "false"]

android:icon="drawable resource"

android:name="string"

android:permission="string"

android:process="string"

android:readPermission="string"

android:writePermission="string" >

</provider>

Atributul exported oferă posibilitatea provider-ului de a putea fi accesat din exteriorul aplicației, ceea ce uneori, poate fi o vulnerabilitate a aplicației Android. Atributele readPermission și writePermission definesc permisiunile necesare unui client pentru a citi, respectiv scrie, datele unui provider.

Pentru accesarea unui provider, trebuie să cunoaștem URI-ul specific, care este de forma :

content://<authority>/<path>/<id>

Atributul authority definește numele content provider-ului, iar atributul path reprezintă numele tabelei. Exemple de content-URIs :

content://com.example.app.provider/table1

content://com.example.app.provider/table2/dataset1

content://com.example.app.provider/table2/dataset2

content://com.example.app.provider/table3 Prin URI-urile de mai sus putem accesa tabelele table1,dataset1,dataset2 și table3 într-un content provider numit com.example.app.provider .

În figura 6.2 am exemplificat modul în care putem interacționa cu un Content Provider. Specificând URI-ul, se pot aplica următoarele operații asupra bazelor de date SQL: inserare, updatare, ștergere a valorilor din baza de date, iar prin query-urile SQL se pot accesa datele din interiorul Content Provider-ului, având permisiunile necesare.

6.1.Exemplificarea SQL injection pe aplicația Android Sieve

În proiectul BIFUZ am încercat preluarea și manipularea datelor prin intermediul content provider-ilor pentru a putea testa vulnerabilitatea aplicațiilor asupra atacurilor SQL.

Pentru a testa proiectul, am folosit aplicația Android, Sieve. Această aplicație a fost creată în scopul de a arata mai multe din vulnerabilitățile aplicaților Android, motiv pentru care am ales utilizarea ei. Sieve este o aplicație ce se ocupă cu managementul unor conturi și parole. Odată cu lansarea ei, utilizatorul își va seta o parolă de 16 caractere și un pin de 4 cifre pentru a-și crea un cont. După aceea, utilizatorul poate introduce mai multe intrări ce conțin conturile de utilizator de pe diverse platforme împreună cu datele importante: username, parolă, email. În figura 6.1.1. am exemplificat modul de funcționare al aplicației Sieve:

12Figura 6.1.1. Rularea aplicației Sieve

6.2.Sql Injection de pe platforma Linux

În proiectul BIFUZ de pe Linux, am realizat testarea prin comenzi ale utiliarului ADB.

În primul rând am avut nevoie de content-URI-urile aplicației. După cum am specificat anterior, pentru a ști un URI, este nevoie de cunoașterea numele content providerului, definit prin atributul authority și numele path-urilor ce definesc tabelele. Atributul authority este definit și în fișierul AndroidManifest.xml, însă numele path-urilor nu se pot afla din acest fișier.

Pentru a putea găsi numele tabelelor am utilizat aplicația Apktool ce face decompresia unui APK dintr-o consolă Linux. Astfel, am avut acces la toate fișierele din interiorul unui APK și am preluat toate content URI-urile. După această etapă, am creat mai multe query-uri SQL pentru a testa vulnerabilitatea aplicației. Am încercat preluarea datelor printr-un query de tip projection. După aceea, am testat inserarea unei valori în baza de date precum și ștergerea tuturor valorilor din baza de date.

În urma testării aplicației Sieve, toate cele trei query-uri au fost executate cu succes, așa cum se observă și din figura 6.2.1. Mai întâi am rulat un query pentru a afișa toate tabele din baza de date și se poate observa că există trei tabele cu numele android_metadata, Passwords și Key. Cel de-al doilea query rulat a fost un exemplu de sql projection prin care am afișat conținutul tabelei Passwords : doua rânduri Row0 și Row1 ce reprezintă două conturi, unul de yahoo și unul de google.

Am încercat inserarea în această tabelă a unei noi intrări printr-un query de tip insert și asa cum se poate observa din figură, s-a realizat cu succes inserarea (se observă apariția unui rând nou Row2). Ultimul query, de tipul delete, utilizat pentru ștergerea întregii tabele Passwords a fost, de asemenea, executat cu succes.

13Figura 6.2.1.Rularea SQL injection din platforma Linux

În cazul în care content-providerul unei aplicații nu este exportat, nu se va reuși preluarea informațiilor din baza de date. Am încercat testarea și pe aplicația Ebay. Testele de sql au generat o excepție Java.lang.SecurityException Permission Denial, așa cum am exemplificat și în figura 6.2.2.

14Figura 6.2.2. SQL java.lang.SecurityException

6.3.SQL Injection de pe platforma Android

În implementarea SQL injection din aplicația BIFUZ din Android, am întâmpinat mai multe dificultăți. La fel ca la Linux, pentru a ști un URI, avem nevoie să cunoaștem numele content providerului, definit prin atributul authority și numele path-urilor ce definesc tabelele. Atributul authority se poate accesa prin intermediul clasei Java, PackageManager, preluând informațiile despre toți content provider-ii.

pm = PythonActivity.mActivity.getPackageManager()

PackListProviders=pm.getPackageInfo(text,PackageManager.GET_PROVIDERS).providers

Numele path-urilor ale content provider-ilor însă, nu se pot afla din interiorul aplicației Android. Prin urmare, nu se pot forma content URI-urile necesare pentru crearea query-urilor SQL. Din platforma Linux, din lina de comandă dintr-o consolă, am folosit utilitarul Apktool, prin intermediul căruia am aflat content URI-urile necesare. Prin urmare, într-o aplicație Android, nu se pot crea URI-uri în același mod ca pe platforma Linux.

Pentru a testa însă vulnerabilitățile SQL din aplicația Android, BIFUZ, am utilizat direct numele URI-urilor pe care le-am aflat cu Apktool, la testarea de pe platforma Linux.

În figura 6.3.1 am exemplificat rezultatul executării unui query pentru afișarea datelor din tabela Passwords din aplicația Sieve. După cum am menționat anterior, aplicația Sieve face managementul unor date private cum ar fi conturi de yahoo, google. Am inserat în aplicația Sieve două conturi: unul de yahoo, unul de google. Așa cum se observă în aplicația BIFUZ, la selectarea pachetului Sieve, sunt afișate toate informațiile din baza de date, conturile mele private setate anterior.

15Figura 6.3.1 SQL injections din BIFUZ

7. Rezultate obținute

În urma testării pachetului com.google.android.gms, ce conține 140 de activități, au fost obținute următoarele rezultate din trei sesiuni de rulare.

Tabelul 7.1.Rezultatele celor 3 sesiuni de rulare de intent-uri

În sesiunea 1, parametrii utilizați pentru generarea de intent-uri au fost toți fuzzy, în sesiunea 2 doar un parametru nu a fost fuzzy, iar în sesiunea 3 toți parametrii, în afară de doi dintre ei, au fost fuzzy.

Cele mai întâlnite excepții generate au fost javaNullPointerException si javaClassNotFoundException.Un exemplu cu logcat-ul sistemului, în momentul în care lansarea unui intent eșuează, datorită unei excepții java.lang.NullPointerException, este reprezentat în figura 7.1

16Figura 7.1.Exemplu excepție java.lang.NullPointerExcepțion la rularea unui intent

În figura 7.2 avem un grafic ce reprezintă numărul de excepții generate la fiecare din cele trei sesiuni.

17Figura 7.2 Numărul de excepții rezultate în urma testării a mai multor intent-uri

Graficul din figura 7.3 reprezintă timpul de execuție necesar pentru rularea de intent-uri din fiecare sesiune. La sesiunea 3 ,unde s-au rulat un număr mult mai mare de intent-uri, timpul de execuție a crescut considerabil (a ajuns la aproximativ 3 săptămâni).

18Figura 7.3 Timpul de execuție la rularea mai multor sesiuni de intent-uri

19Figura 7.4. Rezultatele obținute în urma rulării mai multor sesiuni de intent-uri

În figura 7.4 avem un grafic cu rezultatele finale în funcție de timpul de execuție și de numărul de excepții generate. Așa cum se poate observa și din grafic, cele mai eficiente sesiuni au fost primele două.

8.Concluzii și dezvoltări ulterioare

8.1.Concluzii

În această lucrare am realizat testarea vulnerabilităților de bază ale sistemelor Android. Am verificat în primul rând funcționarea mecanismului de inter-comunicare între procese(IPC), aceasta fiind esențială în asigurarea securității sistemului. Prin urmare, am preluat toate pachetele din dispozitiv și am făcut o analiză asupra activităților și broadcast-urilor. Pe baza acestor informații și pe baza unor parametrii fuzzy am făcut generarea de broadcast-uri și de intent-uri. După lansarea acestor intent-uri către aplicațiile din sistem, am observat faptul că unele dintre acestea au generat excepții de tipul java.lang.NullPointerException sau java.lang.ClassNotFoundException. Proiectul BIFUZ analizează aceste erori și pe baza lor, se construiesc anumite seed-file-uri cu toate intent-urile rulate până la momentul excepției generate. Acest lucru este foarte util deoarece se poate recrea contextul în care s-a produs o eroare.

În cea de-a doua parte a proiectului am făcut o analiză asupra Content Provider-ilor unei aplicații și asupra modului în care query-urile acestora pot genera atacuri SQL injection. Aceste atacuri reprezintă modalitatea prin care se poate partaja și controla transferul de date între aplicații. Securitatea unui content provider poate fi protejată prin declararea unor permisiuni speciale în fișierul AndroidManifest.xml. Fără aceste permisiuni, oricine poate accesa și modifica bazele de date ale aplicației.

Pentru a putea menține securitatea unei aplicații, este necesară utilizarea mecanismului de inter-comunicare între procese într-un mod corect și sigur. Componentele exportate necesită o analiză amănunțită, deoarece ele pot reprezenta vulnerabilități pentru atacatori.

8.2.Dezvoltări ulterioare

Aplicația BIFUZ îndeplinește cu succes testarea mecanismului de inter-comunicare. Interfața a fost făcută în framework-ul Kivy Android și poate fi dezvoltată ulterior.

La partea de SQL injection se pot crea mai multe query-uri cu mai multe tipuri de SQL injection pentru a testa în profunzime vulnerabilitățile content provider-ilor.

Pe viitor, aplicația BIFUZ ar putea fi instalată ca o aplicație de sistem. Aplicațiile Android de sistem sunt instalate în folder-ul /system/app/ și au mai multe permisiuni față de cele normale, instalate în /data/app/. Astfel, ele dețin control total asupra dispozitivului și se pot utiliza anumite funcționalități speciale, cum ar fi Intent Firewall.

Intent Firewall reprezintă filtrul prin care trece orice intent creat. Acesta funcționează printr-un set de reguli, incluse în fișiere XML ce pot fi configurate în mod dinamic, ceea ce îl face un mecanism de monitorizare al intent-urilor foarte flexibil.

9.BIBLIOGRAFIE

[1] Raimondas Sasnauskas, John Regehr , „Intent Fuzzer: Crafting Intents of Death”

[2] Amiya K. Maji,Fahad A. Arshad, Saurabh Bagchi, Jan S. Rellermeyer, „An Empirical Study of the Robustness of Inter-component Communication in Android”

[3] William Enck, Damien Octeau, Patrick McDaniel, Swarat Chaudhuri, „A Study of Android Application Security ”

[4] Pragati Ogal Rai , „Android Application Security Essentials”

[5] Scott Alexander-Bown, Keith Makan ,„Android Security Cookbook”,2013

[6] Amiya K. Maji, Fahad A. Arshad, Saurabh Bagchi, Jan S. Rellermeyer, „An Empirical Study of the Robustness of Inter-component Communication in Android ”

[7] Joshua J. Drake, Pau Oliva Fora, Zach Lanier, Collin Mulliner, Stephen A. Ridley, Georg Wicherski , „Android Hacker’s Handbook”

[8] William Enck, Damien Octeau, Patrick McDaniel, Swarat Chaudhuri, „A Study of Android Application Security “

[9] Andrei Roșu-Cojocaru, Dragoș Niculescu Radu Stoenescu, “http://ocw.cs.pub.ro/courses/pdsd”

Similar Posts