Android Applications Basics
Last updated
Last updated
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Daar is twee lae:
Die OS, wat geïnstalleerde toepassings van mekaar isoleer.
Die toepassing self, wat ontwikkelaars toelaat om sekere funksies bloot te stel en toepassingsvermoëns te konfigureer.
Elke toepassing word aan 'n spesifieke gebruikers-ID toegeken. Dit gebeur tydens die installasie van die app sodat die app slegs met lêers wat aan sy gebruikers-ID behoort of gedeelde lêers kan kommunikeer. Daarom kan slegs die app self, sekere komponente van die OS en die wortelgebruiker toegang tot die toepassingsdata hê.
Twee toepassings kan gekonfigureer word om dieselfde UID te gebruik. Dit kan nuttig wees om inligting te deel, maar as een daarvan gecompromitteer word, sal die data van beide toepassings gecompromitteer wees. Dit is waarom hierdie gedrag afgeraadpleeg word.
Om dieselfde UID te deel, moet toepassings dieselfde android:sharedUserId
waarde in hul manifes definieer.
Die Android Toepassing Sandbox laat toe om elke toepassing as 'n afsonderlike proses onder 'n afsonderlike gebruikers-ID te laat loop. Elke proses het sy eie virtuele masjien, sodat 'n app se kode in isolasie van ander apps loop. Vanaf Android 5.0(L) SELinux word afgedwing. Basies het SELinux alle prosesinteraksies ontken en toe beleide geskep om slegs die verwagte interaksies tussen hulle toe te laat.
Wanneer jy 'n app installeer en dit vra vir toestemmings, vra die app vir die toestemmings wat in die uses-permission
elemente in die AndroidManifest.xml lêer geconfigureer is. Die uses-permission element dui die naam van die aangevraagde toestemming binne die naam attribuut aan. Dit het ook die maxSdkVersion attribuut wat stop om vir toestemmings te vra op weergawes hoër as die een wat gespesifiseer is.
Let daarop dat android toepassings nie al die toestemmings aan die begin hoef te vra nie, hulle kan ook dynamies om toestemmings vra maar al die toestemmings moet verklaar word in die manifest.
Wanneer 'n app funksionaliteit blootstel, kan dit die toegang beperk tot slegs apps wat 'n gespesifiseerde toestemming het. 'n Toestemmingselement het drie attribiete:
Die naam van die toestemming
Die permission-group attribuut, wat toelaat om verwante toestemmings te groepeer.
Die protection-level wat aandui hoe die toestemmings toegeken word. Daar is vier tipes:
Normaal: Gebruik wanneer daar geen bekende bedreigings vir die app is nie. Die gebruiker is nie verplig om dit goed te keur nie.
Gevaarlik: Dui aan dat die toestemming die aansoekende toepassing 'n paar verhoogde toegang gee. Gebruikers word gevra om dit goed te keur.
Handtekening: Slegs apps wat deur dieselfde sertifikaat as die een wat die komponent uitvoer, kan toestemming ontvang. Dit is die sterkste tipe beskerming.
HandtekeningOfStelsel: Slegs apps wat deur dieselfde sertifikaat as die een wat die komponent uitvoer of apps wat met stelselniveau toegang loop kan toestemming ontvang.
Hierdie apps word gewoonlik in die /system/app
of /system/priv-app
gidsen gevind en sommige van hulle is geoptimaliseer (jy mag nie eens die classes.dex
lêer vind nie). Hierdie toepassings is die moeite werd om na te kyk omdat hulle soms met te veel toestemmings loop (as wortel).
Diegene wat saam met die AOSP (Android OpenSource Project) ROM verskaf word
Bygevoeg deur die toestel fabrikant
Bygevoeg deur die sel foonverskaffer (as dit van hulle gekoop is)
Om worteltoegang tot 'n fisiese android toestel te verkry, moet jy gewoonlik 1 of 2 kwesbaarhede ontgin wat gewoonlik spesifiek vir die toestel en weergawe is.
Sodra die ontginning gewerk het, word gewoonlik die Linux su
binêre na 'n plek gekopieer wat in die gebruiker se PATH omgewing veranderlike soos /system/xbin
gespesifiseer is.
Sodra die su binêre geconfigureer is, word 'n ander Android app gebruik om met die su
binêre te kommunikeer en versoeke vir worteltoegang te verwerk soos Superuser en SuperSU (beskikbaar in die Google Play winkel).
Let daarop dat die rooting proses baie gevaarlik is en die toestel ernstig kan beskadig
Dit is moontlik om die OS te vervang deur 'n pasgemaakte firmware te installeer. Deur dit te doen, is dit moontlik om die nuttigheid van 'n ou toestel uit te brei, sagtewarebeperkings te omseil of toegang tot die nuutste Android kode te verkry. OmniROM en LineageOS is twee van die gewildste firmwares om te gebruik.
Let daarop dat dit nie altyd nodig is om die toestel te root nie om 'n pasgemaakte firmware te installeer. Sommige vervaardigers laat die ontsluiting van hul bootloaders op 'n goed gedokumenteerde en veilige manier toe.
Sodra 'n toestel ge-root is, kan enige app toegang as wortel vra. As 'n kwaadwillige toepassing dit kry, kan dit toegang tot byna alles hê en dit sal in staat wees om die foon te beskadig.
Die formaat van Android toepassings word verwys na as APK lêerformaat. Dit is essensieel 'n ZIP lêer (deur die lêernaamsextensie na .zip te hernoem, kan die inhoud onttrek en besigtig word).
APK Inhoud (Nie uitputtend nie)
AndroidManifest.xml
resources.arsc/strings.xml
resources.arsc: bevat vooraf gecompileerde hulpbronne, soos binêre XML.
res/xml/files_paths.xml
META-INF/
Dit is waar die Sertifikaat geleë is!
classes.dex
Bevat Dalvik bytecode, wat die gecompileerde Java (of Kotlin) kode verteenwoordig wat die toepassing standaard uitvoer.
lib/
Huisves inheemse biblioteke, gesegregeer volgens CPU argitektuur in subgidse.
armeabi
: kode vir ARM-gebaseerde verwerkers
armeabi-v7a
: kode vir ARMv7 en hoër gebaseerde verwerkers
x86
: kode vir X86 verwerkers
mips
: kode vir slegs MIPS verwerkers
assets/
Berg miscellaneous lêers wat deur die app benodig word, moontlik insluitend addisionele inheemse biblioteke of DEX lêers, soms deur kwaadwillige skrywers gebruik om addisionele kode te verberg.
res/
Bevat hulpbronne wat nie in resources.arsc gecompileer is nie.
In Android ontwikkeling, Java of Kotlin word gebruik om apps te skep. In plaas daarvan om die JVM soos in lessenaarapps te gebruik, compileer Android hierdie kode in Dalvik Executable (DEX) bytecode. Eerder het die Dalvik virtuele masjien hierdie bytecode hanteer, maar nou neem die Android Runtime (ART) oor in nuwer Android weergawes.
Vir omgekeerde ingenieurswese, word Smali noodsaaklik. Dit is die menslike leesbare weergawe van DEX bytecode, wat soos assemblytaal optree deur bronkode in bytecode instruksies te vertaal. Smali en baksmali verwys na die samestelling en ontbinding gereedskap in hierdie konteks.
Intents is die primêre middel waardeur Android apps tussen hul komponente of met ander apps kommunikeer. Hierdie boodskapobjekte kan ook data tussen apps of komponente dra, soortgelyk aan hoe GET/POST versoeke in HTTP kommunikasies gebruik word.
So 'n Intent is basies 'n boodskap wat tussen komponente oorgedra word. Intents kan gerig word na spesifieke komponente of apps, of kan sonder 'n spesifieke ontvanger gestuur word. Om dit eenvoudig te stel, kan Intent gebruik word:
Om 'n Aktiwiteit te begin, wat tipies 'n gebruikerskoppelvlak vir 'n app oopmaak
As uitsendings om die stelsel en apps van veranderinge in kennis te stel
Om 'n agtergronddiens te begin, stop, en kommunikeer
Om toegang tot data via ContentProviders te verkry
As terugroep om gebeurtenisse te hanteer
As kwesbaar, kan Intents gebruik word om 'n verskeidenheid aanvalle uit te voer.
Intent Filters definieer hoe 'n aktiwiteit, diens, of Uitsendingsontvanger met verskillende tipes Intents kan kommunikeer. Essensieel beskryf hulle die vermoëns van hierdie komponente, soos watter aksies hulle kan uitvoer of die tipes uitsendings wat hulle kan verwerk. Die primêre plek om hierdie filters te verklaar is binne die AndroidManifest.xml lêer, hoewel dit ook 'n opsie is om dit vir Uitsendingsontvangers te kodeer.
Intent Filters bestaan uit kategorieë, aksies, en data filters, met die moontlikheid om addisionele metadata in te sluit. Hierdie opstelling laat komponente toe om spesifieke Intents te hanteer wat by die verklaarde kriteria pas.
'n Kritieke aspek van Android komponente (aktiwiteite/dienste/inhoudverskaffers/uitsendingsontvangers) is hul sigbaarheid of publieke status. 'n Komponent word as publiek beskou en kan met ander apps kommunikeer as dit exported
is met 'n waarde van true
of as 'n Intent Filter vir dit in die manifest verklaar is. Daar is egter 'n manier vir ontwikkelaars om hierdie komponente eksplisiet privaat te hou, wat verseker dat hulle nie onbedoeld met ander apps kommunikeer nie. Dit word bereik deur die exported
attribuut op false
in hul manifest definisies in te stel.
Boonop het ontwikkelaars die opsie om toegang tot hierdie komponente verder te beveilig deur spesifieke toestemmings te vereis. Die permission
attribuut kan gestel word om af te dwing dat slegs apps met die aangewese toestemming toegang tot die komponent kan verkry, wat 'n ekstra laag van sekuriteit en beheer oor wie daarmee kan kommunikeer, toevoeg.
Intents word programmaties geskep met 'n Intent-konstruktors:
Die Aksie van die voorheen verklaarde intent is ACTION_SEND en die Ekstra is 'n mailto Uri (die Ekstra is die ekstra inligting wat die intent verwag).
Hierdie intent moet binne die manifest verklaar word soos in die volgende voorbeeld:
'n Intent-filter moet die aksie, data en kategorie ooreenstem om 'n boodskap te ontvang.
Die "Intent resolusie" proses bepaal watter app elke boodskap moet ontvang. Hierdie proses oorweeg die prioriteit eienskap, wat in die intent-filter verklaring gestel kan word, en die een met die hoër prioriteit sal gekies word. Hierdie prioriteit kan tussen -1000 en 1000 gestel word en toepassings kan die SYSTEM_HIGH_PRIORITY
waarde gebruik. As 'n konflik ontstaan, verskyn 'n "choser" venster sodat die gebruiker kan besluit.
'n Expliciete intent spesifiseer die klasnaam wat dit teiken:
In ander toepassings om toegang te verkry tot die voorheen verklaarde intent kan jy gebruik maak van:
Hierdie laat ander toepassings toe om aksies namens jou toepassing te neem, met jou app se identiteit en toestemmings. Om 'n Pending Intent te konstrueer, moet daar 'n intent en die aksie wat uitgevoer moet word, gespesifiseer word. As die verklaarde intent nie Eksplisiet is nie (nie verklaar watter intent dit kan oproep nie), kan 'n kwaadwillige toepassing die verklaarde aksie namens die slagoffer-app uitvoer. Boonop, as 'n aksie nie gespesifiseer is nie, sal die kwaadwillige app in staat wees om enige aksie namens die slagoffer te doen.
Anders as die vorige intents, wat slegs deur een app ontvang word, kan broadcast intents deur verskeie apps ontvang word. Vanaf API weergawe 14 is dit egter moontlik om die app wat die boodskap moet ontvang, te spesifiseer met behulp van Intent.setPackage.
Alternatiewelik is dit ook moontlik om 'n toestemming te spesifiseer wanneer die broadcast gestuur word. Die ontvangende app sal daardie toestemming moet hê.
Daar is twee tipes Uitsendings: Normaal (asynchrone) en Geordende (synchroniese). Die volgorde is gebaseer op die geconfigureerde prioriteit binne die ontvanger element. Elke app kan die Broadcast verwerk, oordra of laat val.
Dit is moontlik om 'n broadcast te stuur met die funksie sendBroadcast(intent, receiverPermission)
van die Context
klas.
Jy kan ook die funksie sendBroadcast
van die LocalBroadCastManager
gebruik wat verseker dat die boodskap nooit die app verlaat nie. Deur dit te gebruik, sal jy selfs nie 'n ontvanger komponent hoef te eksporteer nie.
Hierdie tipe Uitsendings kan lank nadat hulle gestuur is, toeganklik wees. Hierdie is in API vlak 21 verouderd en dit word aanbeveel om nie hulle te gebruik nie. Hulle laat enige toepassing toe om die data te snuffel, maar ook om dit te wysig.
As jy funksies vind wat die woord "sticky" bevat, soos sendStickyBroadcast
of sendStickyBroadcastAsUser
, kontroleer die impak en probeer om hulle te verwyder.
In Android toepassings, deep links word gebruik om 'n aksie (Intent) direk deur 'n URL te begin. Dit word gedoen deur 'n spesifieke URL skema binne 'n aktiwiteit te verklaar. Wanneer 'n Android toestel probeer om 'n URL met hierdie skema te benader, word die gespesifiseerde aktiwiteit binne die toepassing gelaai.
Die skema moet in die AndroidManifest.xml
lêer verklaar word:
Die skema van die vorige voorbeeld is examplescheme://
(let ook op die category BROWSABLE
)
Dan kan jy in die data veld die host en path spesifiseer:
Om dit vanaf 'n web te benader, is dit moontlik om 'n skakel soos:
Om die kode wat in die App uitgevoer sal word te vind, gaan na die aktiwiteit wat deur die deeplink aangeroep word en soek die funksie onNewIntent
.
Leer hoe om deeplinks te bel sonder om HTML-bladsye te gebruik.
Die Android Interface Definition Language (AIDL) is ontwerp om kommunikasie tussen kliënt en diens in Android-toepassings te fasiliteer deur middel van interprocess communication (IPC). Aangesien dit nie toegelaat word om 'n ander proses se geheue direk op Android te benader nie, vereenvoudig AIDL die proses deur voorwerpe in 'n formaat te marshall wat deur die bedryfstelsel verstaan word, wat kommunikasie oor verskillende prosesse vergemaklik.
Gekoppelde Dienste: Hierdie dienste gebruik AIDL vir IPC, wat aktiwiteite of komponente in staat stel om aan 'n diens te bind, versoeke te maak en antwoorde te ontvang. Die onBind
metode in die diens se klas is krities vir die inisiering van interaksie, wat dit 'n belangrike area maak vir sekuriteitsherziening in die soeke na kwesbaarhede.
Messenger: As 'n gekoppelde diens, fasiliteer Messenger IPC met 'n fokus op die verwerking van data deur die onBind
metode. Dit is noodsaaklik om hierdie metode noukeurig te ondersoek vir enige onveilige datahantering of uitvoering van sensitiewe funksies.
Binder: Alhoewel direkte gebruik van die Binder-klas minder algemeen is weens AIDL se abstraksie, is dit voordelig om te verstaan dat Binder as 'n kernvlak bestuurder optree wat datatransfer tussen die geheue ruimtes van verskillende prosesse fasiliteer. Vir verdere begrip is 'n hulpbron beskikbaar by https://www.youtube.com/watch?v=O-UHvFjxwZ8.
Hierdie sluit in: Aktiwiteite, Dienste, Uitsendingsontvangers en Verskaffers.
In Android-toepassings is aktiwiteite soos skerms, wat verskillende dele van die app se gebruikerskoppelvlak vertoon. 'n App kan baie aktiwiteite hê, elkeen wat 'n unieke skerm aan die gebruiker aanbied.
Die laaieraktiwiteit is die hooftoegangspunt tot 'n app, wat gelaai word wanneer jy op die app se ikoon tik. Dit is gedefinieer in die app se manifeslêer met spesifieke MAIN en LAUNCHER intents:
Nie alle toepassings benodig 'n lanseeraktiwiteit nie, veral dié sonder 'n gebruikerskoppelvlak, soos agtergronddienste.
Aktiwiteite kan beskikbaar gestel word aan ander toepassings of prosesse deur dit as "geëksporteer" in die manifes te merk. Hierdie instelling laat ander toepassings toe om hierdie aktiwiteit te begin:
However, toegang tot 'n aktiwiteit van 'n ander app is nie altyd 'n sekuriteitsrisiko nie. Die bekommernis ontstaan as sensitiewe data onregmatig gedeel word, wat kan lei tot inligtingslekke.
'n Aktiwiteit se lewensiklus begin met die onCreate-metode, wat die UI opstel en die aktiwiteit voorberei vir interaksie met die gebruiker.
In Android-ontwikkeling het 'n app die opsie om 'n subklas van die Application klas te skep, alhoewel dit nie verpligtend is nie. Wanneer so 'n subklas gedefinieer word, word dit die eerste klas wat binne die app geïnstantieer word. Die attachBaseContext
metode, indien geïmplementeer in hierdie subklas, word uitgevoer voordat die onCreate
metode. Hierdie opstelling stel vroeë inisialisering in staat voordat die res van die aansoek begin.
Dienste is agtergrond operasies wat in staat is om take uit te voer sonder 'n gebruikerskoppelvlak. Hierdie take kan voortgaan om te loop selfs wanneer gebruikers na verskillende toepassings oorskakel, wat dienste noodsaaklik maak vir langdurige operasies.
Dienste is veelsydig; hulle kan op verskillende maniere geaktiveer word, met Intents as die primêre metode om hulle as 'n toepassing se toegangspunt te begin. Sodra 'n diens begin is met die startService
metode, begin sy onStart
metode en hou aan om te loop totdat die stopService
metode eksplisiet aangeroep word. Alternatiewelik, as 'n diens se rol afhanklik is van 'n aktiewe kliëntverbinding, word die bindService
metode gebruik om die kliënt aan die diens te bind, wat die onBind
metode aktiveer vir dataversending.
'n Interessante toepassing van dienste sluit agtergrondmusiekafspeel of netwerkdata-opeising in sonder om die gebruiker se interaksie met 'n toepassing te hindern. Boonop kan dienste beskikbaar gemaak word vir ander prosesse op dieselfde toestel deur uitvoer. Dit is nie die standaardgedrag nie en vereis eksplisiete konfigurasie in die Android Manifest-lêer:
Broadcast receivers dien as luisteraars in 'n boodskapstelsel, wat verskeie toepassings toelaat om op dieselfde boodskappe van die stelsel te reageer. 'n App kan 'n ontvanger registreer op twee primêre maniere: deur die app se Manifest of dynamies binne die app se kode via die registerReceiver
API. In die Manifest word uitsendings gefiltreer met toestemmings, terwyl dinamies geregistreerde ontvangers ook toestemmings kan spesifiseer tydens registrasie.
Intent filters is van kardinale belang in beide registrasiewyse, wat bepaal watter uitsendings die ontvanger aktiveer. Sodra 'n ooreenstemmende uitsending gestuur word, word die ontvanger se onReceive
metode aangeroep, wat die app in staat stel om ooreenkomstig te reageer, soos om gedrag aan te pas in reaksie op 'n lae battery waarskuwing.
Uitsendings kan asynchrone wees, wat alle ontvangers sonder volgorde bereik, of synchronies, waar ontvangers die uitsending ontvang op grond van gestelde prioriteite. Dit is egter belangrik om die potensiële sekuriteitsrisiko te noem, aangesien enige app homself kan prioriteer om 'n uitsending te onderskep.
Om 'n ontvanger se funksionaliteit te verstaan, soek na die onReceive
metode binne sy klas. Hierdie metode se kode kan die ontvangde Intent manipuleer, wat die behoefte aan datavalidatie deur ontvangers beklemtoon, veral in Ordered Broadcasts, wat die Intent kan wysig of laat val.
Content Providers is noodsaaklik vir die deel van gestruktureerde data tussen toepassings, wat die belangrikheid van die implementering van toestemmings beklemtoon om datasekuriteit te verseker. Hulle laat toepassings toe om toegang te verkry tot data van verskeie bronne, insluitend databasisse, lêerstelsels, of die web. Spesifieke toestemmings, soos readPermission
en writePermission
, is van kardinale belang om toegang te beheer. Boonop kan tydelike toegang verleen word deur grantUriPermission
instellings in die app se manifest, wat eienskappe soos path
, pathPrefix
, en pathPattern
benut vir gedetailleerde toegangbeheer.
Invoervalidasie is van kardinale belang om kwesbaarhede, soos SQL-inspuiting, te voorkom. Content Providers ondersteun basiese operasies: insert()
, update()
, delete()
, en query()
, wat datamanipulasie en -deling tussen toepassings fasiliteer.
FileProvider, 'n gespesialiseerde Content Provider, fokus op die veilige deel van lêers. Dit word in die app se manifest gedefinieer met spesifieke eienskappe om toegang tot vouers te beheer, aangedui deur android:exported
en android:resource
wat na vouer konfigurasies verwys. Versigtigheid word aanbeveel wanneer daar vouers gedeel word om te voorkom dat sensitiewe data per ongeluk blootgestel word.
Voorbeeld manifest verklaring vir FileProvider:
En 'n voorbeeld van die spesifisering van gedeelde vouers in filepaths.xml
:
For further information check:
WebViews is soos mini webblaaiers binne Android-apps, wat inhoud trek of van die web of van plaaslike lêers. Hulle ondervind soortgelyke risiko's as gewone blaaiers, maar daar is maniere om hierdie risiko's te verlaag deur spesifieke instellings.
Android bied twee hoof WebView-tipes:
WebViewClient is uitstekend vir basiese HTML, maar ondersteun nie die JavaScript waarskuwing funksie nie, wat die toetsing van XSS-aanvalle beïnvloed.
WebChromeClient funksioneer meer soos die volle Chrome-blaaierervaring.
'n Sleutelpunt is dat WebView-blaaiers nie koekies met die toestel se hoofblaaier deel nie.
Vir die laai van inhoud is metodes soos loadUrl
, loadData
, en loadDataWithBaseURL
beskikbaar. Dit is van kardinale belang om te verseker dat hierdie URL's of lêers veilig is om te gebruik. Sekuriteitsinstellings kan bestuur word via die WebSettings
klas. Byvoorbeeld, om JavaScript te deaktiveer met setJavaScriptEnabled(false)
kan XSS-aanvalle voorkom.
Die JavaScript "Bridge" laat Java-objekte toe om met JavaScript te kommunikeer, wat vereis dat metodes gemerk moet word met @JavascriptInterface
vir sekuriteit vanaf Android 4.2.
Om toegang tot inhoud toe te laat (setAllowContentAccess(true)
) laat WebViews toe om toegang te verkry tot Content Providers, wat 'n risiko kan wees tensy die inhoud URL's as veilig geverifieer word.
Om lêer toegang te beheer:
Deaktiveer lêer toegang (setAllowFileAccess(false)
) beperk toegang tot die lêerstelsel, met uitsonderings vir sekere bates, wat verseker dat hulle slegs vir nie-sensitiewe inhoud gebruik word.
Digitale ondertekening is 'n moet vir Android-apps, wat verseker dat hulle egte geskryf is voor installasie. Hierdie proses gebruik 'n sertifikaat vir app-identifikasie en moet deur die toestel se pakketbestuurder geverifieer word tydens installasie. Apps kan self-onderteken of gesertifiseer deur 'n eksterne CA wees, wat beskerming bied teen ongemagtigde toegang en verseker dat die app ongeskonde bly tydens sy aflewering aan die toestel.
Begin vanaf Android 4.2, 'n funksie genaamd Verify Apps laat gebruikers toe om apps vir veiligheid te laat nagaan voor installasie. Hierdie verifikasieproses kan gebruikers waarsku teen potensieel skadelike apps, of selfs die installasie van veral kwaadwillige apps voorkom, wat gebruikers se sekuriteit verbeter.
MDM-oplossings bied toesig en sekuriteit vir mobiele toestelle deur middel van Device Administration API. Hulle vereis die installasie van 'n Android-app om mobiele toestelle effektief te bestuur en te beveilig. Sleutelfunksies sluit in afdwinging van wagwoordbeleide, verpligte stoor-enkripsie, en toestemming vir afstandsdata-wipe, wat omvattende beheer en sekuriteit oor mobiele toestelle verseker.
Leer & oefen AWS Hacking:HackTricks Opleiding AWS Red Team Expert (ARTE) Leer & oefen GCP Hacking: HackTricks Opleiding GCP Red Team Expert (GRTE)