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.
Modello di Sicurezza Android
Ci sono due livelli:
- Il OS, che mantiene le applicazioni installate isolate lâuna dallâaltra.
- Lâapplicazione stessa, che consente agli sviluppatori di esporre determinate funzionalitĂ e configura le capacitĂ dellâapplicazione.
Separazione UID
Ogni applicazione è assegnata a un ID Utente specifico. Questo avviene durante lâinstallazione dellâapp in modo che lâapp possa interagire solo con i file di proprietĂ del suo ID Utente o con file condivisi. Pertanto, solo lâapp stessa, alcuni componenti del OS e lâutente root possono accedere ai dati delle app.
Condivisione UID
Due applicazioni possono essere configurate per utilizzare lo stesso UID. Questo può essere utile per condividere informazioni, ma se una di esse viene compromessa, i dati di entrambe le applicazioni saranno compromessi. Questo è il motivo per cui questo comportamento è sconsigliato.
Per condividere lo stesso UID, le applicazioni devono definire lo stesso valore android:sharedUserId nei loro manifest.
Sandboxing
Il Sandbox delle Applicazioni Android consente di eseguire ogni applicazione come un processo separato sotto un ID Utente separato. Ogni processo ha la propria macchina virtuale, quindi il codice di unâapp viene eseguito in isolamento rispetto ad altre app.
A partire da Android 5.0(L), SELinux è applicato. Fondamentalmente, SELinux nega tutte le interazioni tra i processi e poi crea politiche per consentire solo le interazioni previste tra di essi.
Permessi
Quando installi unâapp e richiede permessi, lâapp sta chiedendo i permessi configurati negli elementi uses-permission nel file AndroidManifest.xml. Lâelemento uses-permission indica il nome del permesso richiesto allâinterno dellâattributo name. Ha anche lâattributo maxSdkVersion che smette di richiedere permessi su versioni superiori a quella specificata.
Nota che le applicazioni android non devono chiedere tutti i permessi allâinizio, possono anche richiedere permessi dinamicamente, ma tutti i permessi devono essere dichiarati nel manifest.
Quando unâapp espone funzionalitĂ , può limitare lâaccesso solo alle app che hanno un permesso specificato.
Un elemento di permesso ha tre attributi:
- Il nome del permesso
- Lâattributo permission-group, che consente di raggruppare permessi correlati.
- Il protection-level che indica come vengono concessi i permessi. Ci sono quattro tipi:
- Normale: Usato quando non ci sono minacce note per lâapp. Lâutente non è tenuto ad approvarlo.
- Pericoloso: Indica che il permesso concede allâapplicazione richiedente un accesso elevato. Gli utenti sono invitati ad approvarli.
- Firma: Solo le app firmate dallo stesso certificato di quello che esporta il componente possono ricevere il permesso. Questo è il tipo di protezione piÚ forte.
- SignatureOrSystem: Solo le app firmate dallo stesso certificato di quello che esporta il componente o app che girano con accesso a livello di sistema possono ricevere permessi.
Applicazioni Preinstallate
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 meritano di essere controllate perchĂŠ a volte girano con troppi permessi (come root).
- Quelle fornite con il AOSP (Android OpenSource Project) ROM
- Aggiunte dal produttore del dispositivo
- Aggiunte dal fornitore di telefonia mobile (se acquistate da loro)
Rooting
Per ottenere accesso root su un dispositivo android fisico, generalmente è necessario sfruttare 1 o 2 vulnerabilità che di solito sono specifiche per il dispositivo 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 configurato il binario su, unâaltra app Android viene utilizzata per interfacciarsi con il binario su e elaborare le richieste di accesso root come Superuser e SuperSU (disponibile nel Google Play store).
Caution
Nota che il processo di rooting è molto pericoloso e può danneggiare gravemente il dispositivo.
ROMs
Ă possibile sostituire il sistema operativo installando un firmware personalizzato. Facendo ciò, è possibile estendere lâutilitĂ di un vecchio dispositivo, bypassare le restrizioni software o accedere allâultima versione del codice Android.
OmniROM e LineageOS sono due dei firmware piĂš popolari da utilizzare.
Nota che non è sempre necessario rootare il dispositivo per installare un firmware personalizzato. Alcuni produttori consentono lo sblocco dei loro bootloader in modo ben documentato e sicuro.
Implicazioni
Una volta che un dispositivo è rootato, qualsiasi app potrebbe richiedere accesso come root. Se unâapplicazione malevola ottiene questo accesso, avrĂ accesso a quasi tutto e sarĂ in grado di danneggiare il telefono.
Fondamenti delle Applicazioni Android
- Il formato delle applicazioni Android è noto come APK file format. Ă essenzialmente un file ZIP (rinominando lâestensione del file in .zip, i contenuti possono essere estratti e visualizzati).
- Contenuti 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 Certificato!
- classes.dex
- Contiene bytecode Dalvik, che rappresenta il codice Java (o Kotlin) compilato che lâapplicazione esegue per impostazione predefinita.
- lib/
- Contiene librerie native, segregate per architettura CPU in sottodirectory.
armeabi: codice per processori basati su ARMarmeabi-v7a: codice per processori ARMv7 e superiorix86: codice per processori X86mips: codice solo per processori MIPS- assets/
- Memorizza file vari necessari allâapp, potenzialmente inclusi librerie native aggiuntive o file DEX, a volte utilizzati dagli autori di malware per nascondere codice aggiuntivo.
- res/
- Contiene risorse che non sono compilate in resources.arsc.
Dalvik & Smali
Nello sviluppo Android, Java o Kotlin viene utilizzato per creare app. Invece di utilizzare la JVM come nelle app desktop, Android compila questo codice in Dalvik Executable (DEX) bytecode. In passato, la macchina virtuale Dalvik gestiva questo bytecode, ma ora, lâAndroid Runtime (ART) prende il sopravvento nelle versioni piĂš recenti di Android.
Per il reverse engineering, Smali diventa cruciale. Ă la versione leggibile dallâuomo del bytecode DEX, agendo come un linguaggio assembly traducendo il codice sorgente in istruzioni bytecode. Smali e baksmali si riferiscono agli strumenti di assemblaggio e disassemblaggio in questo contesto.
Intents
Gli Intents sono il principale mezzo attraverso il quale le app Android comunicano tra i loro componenti o con altre app. Questi oggetti messaggio possono anche trasportare dati tra app o componenti, simile a come vengono utilizzate le richieste GET/POST nelle comunicazioni HTTP.
Quindi un Intent è fondamentalmente un messaggio che viene passato tra i componenti. Gli Intents possono essere diretti a componenti o app specifiche, o possono essere inviati senza un destinatario specifico.
Per essere semplici, gli Intent possono essere utilizzati:
- Per avviare unâActivity, tipicamente aprendo unâinterfaccia utente per unâapp
- Come trasmissioni per informare il sistema e le app di cambiamenti
- Per avviare, fermare e comunicare con un servizio in background
- Per accedere ai dati tramite ContentProviders
- Come callback per gestire eventi
Se vulnerabili, gli Intents possono essere utilizzati per eseguire una varietĂ di attacchi.
Intent-Filter
Intent Filters definiscono come unâattivitĂ , un servizio o un Broadcast Receiver possono interagire con diversi tipi di Intents. Fondamentalmente, descrivono le capacitĂ di questi componenti, come quali azioni possono eseguire o i tipi di trasmissioni che possono elaborare. Il luogo principale per dichiarare questi filtri è allâinterno del file AndroidManifest.xml, anche se per i Broadcast Receivers, codificarli è anche unâopzione.
Gli Intent Filters sono composti da categorie, azioni e filtri di dati, con la possibilitĂ di includere metadati aggiuntivi. Questa configurazione consente ai componenti di gestire specifici Intents che corrispondono ai criteri dichiarati.
Un aspetto critico dei componenti Android (attivitĂ /servizi/provider di contenuti/ricevitori di trasmissione) è la loro visibilitĂ o stato pubblico. Un componente è considerato pubblico e può interagire con altre app se è exported con un valore di true o se un Intent Filter è dichiarato per esso nel manifest. Tuttavia, câè un modo per gli sviluppatori di mantenere esplicitamente privati questi componenti, assicurandosi che non interagiscano con altre app inavvertitamente. Questo viene realizzato impostando lâattributo exported su false nelle loro definizioni di manifest.
Inoltre, gli sviluppatori hanno la possibilitĂ di garantire ulteriormente lâaccesso a questi componenti richiedendo permessi specifici. Lâattributo permission può essere impostato per imporre che solo le app con il permesso designato possano accedere al componente, aggiungendo un ulteriore livello di sicurezza e controllo su chi può interagire con esso.
<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>
Intent impliciti
Gli intent vengono creati programmaticamente utilizzando un costruttore di Intent:
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
LâAzione dellâintento precedentemente dichiarato è ACTION_SEND e lâExtra è un Uri mailto (lâExtra è le informazioni aggiuntive che lâintento si aspetta).
Questo intento dovrebbe essere dichiarato allâinterno del manifest come nel seguente esempio:
<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 allâazione, ai dati e alla categoria per ricevere un messaggio.
Il processo di ârisoluzione dellâIntentâ determina quale app dovrebbe ricevere ciascun messaggio. Questo processo considera lâattributo di prioritĂ , che può essere impostato nella dichiarazione dellâintent-filter, e quella con la prioritĂ piĂš alta sarĂ selezionata. Questa prioritĂ può essere impostata tra -1000 e 1000 e le applicazioni possono utilizzare il valore SYSTEM_HIGH_PRIORITY. Se si verifica un conflitto, appare una finestra âchoserâ in modo che lâutente possa decidere.
Intents Espliciti
Un intent esplicito specifica il nome della classe che sta mirando:
Intent downloadIntent = new (this, DownloadService.class):
In altre applicazioni, per accedere allâintento precedentemente dichiarato, puoi usare:
Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);
Pending Intents
Questi consentono ad altre applicazioni di eseguire azioni per conto della tua applicazione, utilizzando lâidentitĂ e i permessi della tua app. Costruendo un Pending Intent, dovrebbe essere specificato un intent e lâazione da eseguire. Se lâintent dichiarato non è Esplicito (non dichiara quale intent può chiamarlo), unâapplicazione malevola potrebbe eseguire lâazione dichiarata per conto dellâapp vittima. Inoltre, se unâazione non è specificata, lâapp malevola sarĂ in grado di fare qualsiasi azione per conto della vittima.
Broadcast Intents
A differenza degli intent precedenti, che sono ricevuti solo da unâapp, gli intent broadcast possono essere ricevuti da piĂš app. Tuttavia, dalla versione API 14, è possibile specificare lâapp che dovrebbe ricevere il messaggio utilizzando Intent.setPackage.
In alternativa, è anche possibile specificare un permesso quando si invia il broadcast. Lâapp ricevente avrĂ bisogno di avere quel permesso.
Ci sono due tipi di Broadcast: Normale (asincrono) e Ordinato (sincrono). Lâordine si basa sulla prioritĂ configurata allâinterno dellâelemento ricevente. Ogni app può elaborare, inoltrare o scartare il Broadcast.
Ă possibile inviare un broadcast utilizzando la funzione sendBroadcast(intent, receiverPermission) dalla classe Context.
Puoi anche utilizzare la funzione sendBroadcast dalla LocalBroadCastManager che garantisce che il messaggio non esca mai dallâapp. Utilizzando questo non avrai nemmeno bisogno di esportare un componente ricevente.
Sticky Broadcasts
Questo tipo di Broadcasts può essere accessibile a lungo dopo che sono stati inviati.
Questi sono stati deprecati a livello API 21 ed è consigliato non usarli.
Consentono a qualsiasi applicazione di intercettare i dati, ma anche di modificarli.
Se trovi funzioni contenenti la parola âstickyâ come sendStickyBroadcast o sendStickyBroadcastAsUser, controlla lâimpatto e cerca di rimuoverle.
Deep links / URL schemes
Nelle applicazioni Android, deep links vengono utilizzati per avviare unâazione (Intent) direttamente tramite un URL. Questo viene fatto dichiarando uno specifico URL scheme allâinterno di unâattivitĂ . Quando un dispositivo Android cerca di accedere a un URL con questo schema, lâattivitĂ specificata allâinterno dellâapplicazione viene avviata.
Lo schema deve essere dichiarato nel file AndroidManifest.xml:
[...]
<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 dellâesempio precedente è examplescheme:// (nota anche il category BROWSABLE)
Poi, nel campo dati, puoi specificare lâhost e il path:
<data android:scheme="examplescheme"
android:host="example"
/>
Per accedervi da un 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âattivitĂ chiamata dal deeplink e cerca la funzione onNewIntent.
Scopri come chiamare deeplink senza utilizzare pagine HTML.
AIDL - Android Interface Definition Language
Il Android Interface Definition Language (AIDL) è progettato per facilitare la comunicazione tra client e servizio nelle applicazioni Android attraverso la comunicazione interprocesso (IPC). PoichĂŠ lâaccesso diretto alla memoria di un altro processo non è consentito su Android, AIDL semplifica il processo marshalling degli oggetti in un formato comprensibile dal sistema operativo, facilitando cosĂŹ la comunicazione tra diversi processi.
Concetti Chiave
-
Servizi Legati: Questi servizi utilizzano AIDL per IPC, consentendo ad attivitĂ o componenti di collegarsi a un servizio, fare richieste e ricevere risposte. Il metodo
onBindnella classe del servizio è fondamentale per avviare lâinterazione, segnalandolo come unâarea vitale per la revisione della sicurezza alla ricerca di vulnerabilitĂ . -
Messenger: Operando come un servizio legato, il Messenger facilita lâIPC con un focus sul trattamento dei dati attraverso il metodo
onBind. Ă essenziale ispezionare questo metodo attentamente per eventuali gestioni di dati non sicure o esecuzione di funzioni sensibili. -
Binder: Sebbene lâuso diretto della classe Binder sia meno comune a causa dellâastrazione di AIDL, è utile comprendere che il Binder agisce come un driver a livello di kernel facilitando il trasferimento di dati tra gli spazi di memoria di diversi processi. Per ulteriori informazioni, è disponibile una risorsa su https://www.youtube.com/watch?v=O-UHvFjxwZ8.
Componenti
Questi includono: AttivitĂ , Servizi, Ricevitori di Broadcast e Provider.
AttivitĂ di Lancio e altre attivitĂ
Nelle app Android, le attivitĂ sono come schermi, mostrando diverse parti dellâinterfaccia utente dellâapp. Unâapp può avere molte attivitĂ , ognuna delle quali presenta uno schermo unico allâutente.
LâattivitĂ di lancio è il principale gateway a unâapp, avviata quando tocchi lâicona dellâapp. Ă definita nel file manifest dellâapp con intent specifici 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 necessitano di unâattivitĂ di avvio, specialmente quelle senza unâinterfaccia utente, come i servizi in background.
Le attivitĂ possono essere rese disponibili ad altre app o processi contrassegnandole come âexportedâ nel manifest. Questa impostazione consente ad altre app di avviare questa attivitĂ :
<service android:name=".ExampleExportedService" android:exported="true"/>
Tuttavia, accedere a unâattivitĂ da unâaltra app non è sempre un rischio per la sicurezza. La preoccupazione sorge se i dati sensibili vengono condivisi in modo improprio, il che potrebbe portare a leak di informazioni.
Il ciclo di vita di unâattivitĂ inizia con il metodo onCreate, impostando lâinterfaccia utente e preparando lâattivitĂ per lâinterazione con lâutente.
Sottoclasse dellâApplicazione
Nello sviluppo Android, unâapp ha la possibilitĂ di creare una sottoclasse della Application classe, anche se non è obbligatorio. Quando tale sottoclasse è definita, 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 consente unâinizializzazione anticipata 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
}
}
Servizi
Servizi sono operativi in background capaci di eseguire compiti senza unâinterfaccia utente. Questi compiti possono continuare a funzionare anche quando gli utenti passano ad altre applicazioni, rendendo i servizi cruciali per operazioni a lungo termine.
I servizi sono versatili; possono essere avviati in vari modi, con Intents che sono il metodo principale per lanciarli come punto di ingresso di unâapplicazione. Una volta che un servizio è avviato utilizzando il metodo startService, il suo metodo onStart entra in azione e continua a funzionare fino a quando il metodo stopService non viene chiamato esplicitamente. In alternativa, se il ruolo di un servizio dipende da una connessione client attiva, il metodo bindService viene utilizzato per legare il client al servizio, attivando il metodo onBind per il passaggio dei dati.
Unâapplicazione interessante dei servizi 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 servizi possono essere resi accessibili ad altri processi sullo stesso dispositivo attraverso lâesportazione. Questo non è il comportamento predefinito e richiede una configurazione esplicita nel file Android Manifest:
<service android:name=".ExampleExportedService" android:exported="true"/>
Broadcast Receivers
I broadcast receivers fungono da ascoltatori in un sistema di messaggistica, consentendo a piĂš applicazioni di rispondere agli stessi messaggi dal sistema. Unâapp può registrare un ricevitore in due modi principali: attraverso il Manifest dellâapp o dinamicamente nel codice dellâapp tramite lâAPI registerReceiver. Nel Manifest, le trasmissioni sono filtrate con permessi, mentre i ricevitori registrati dinamicamente possono anche specificare permessi al momento della registrazione.
I filtri di Intent sono cruciali in entrambi i metodi di registrazione, determinando quali trasmissioni attivano il ricevitore. Una volta inviata una trasmissione corrispondente, viene invocato il metodo onReceive del ricevitore, consentendo allâapp di reagire di conseguenza, ad esempio, modificando il comportamento in risposta a un avviso di batteria scarica.
Le trasmissioni possono essere asincrone, raggiungendo tutti i ricevitori senza ordine, o sincrone, dove i ricevitori ricevono la trasmissione in base a priorità impostate. Tuttavia, è importante notare il potenziale rischio per la sicurezza, poichÊ qualsiasi app può dare priorità a se stessa per intercettare una trasmissione.
Per comprendere la funzionalitĂ di un ricevitore, cerca il metodo onReceive allâinterno della sua classe. Il codice di questo metodo può manipolare lâIntent ricevuto, evidenziando la necessitĂ di convalida dei dati da parte dei ricevitori, specialmente nelle Ordered Broadcasts, che possono modificare o scartare lâIntent.
Content Provider
I Content Providers sono essenziali per condividere dati strutturati tra app, sottolineando lâimportanza di implementare permessi per garantire la sicurezza dei dati. Consentono alle app di accedere ai 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 dettagliato dellâaccesso.
La convalida dellâinput è fondamentale per prevenire vulnerabilitĂ , come lâiniezione SQL. I Content Providers supportano operazioni di base: insert(), update(), delete() e query(), facilitando la manipolazione e la condivisione dei dati tra le applicazioni.
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, indicato da android:exported e android:resource che puntano alle configurazioni delle cartelle. Si consiglia cautela quando si condividono directory per evitare di esporre involontariamente dati sensibili.
Esempio di dichiarazione del 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>
E un esempio di specificazione delle cartelle condivise in filepaths.xml:
<paths>
<files-path path="images/" name="myimages" />
</paths>
Per ulteriori informazioni controlla:
WebViews
WebViews sono come mini browser web allâinterno delle app Android, che estraggono contenuti sia dal web che da file locali. Affrontano rischi simili a quelli dei browser regolari, ma ci sono modi per ridurre questi rischi attraverso specifiche impostazioni.
Android offre due principali tipi di WebView:
- WebViewClient è ottimo per HTML di base ma non supporta la funzione di avviso JavaScript, 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 cookie con il browser principale del dispositivo.
Per caricare contenuti, sono disponibili metodi come loadUrl, loadData e loadDataWithBaseURL. à fondamentale assicurarsi che questi URL o file siano sicuri da usare. Le impostazioni di sicurezza possono essere gestite tramite la classe WebSettings. Ad esempio, disabilitare JavaScript con setJavaScriptEnabled(false) può prevenire attacchi XSS.
Il âBridgeâ JavaScript consente agli oggetti Java di interagire con JavaScript, richiedendo che i metodi siano contrassegnati con @JavascriptInterface per la sicurezza a partire da Android 4.2.
Consentire lâaccesso ai contenuti (setAllowContentAccess(true)) consente ai WebView di accedere ai Content Providers, il che potrebbe essere un rischio a meno che gli URL dei contenuti non siano verificati come sicuri.
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 utilizzati solo per contenuti non sensibili.
Altri Componenti dellâApp e Gestione dei Dispositivi Mobili
Firma Digitale delle Applicazioni
- La firma digitale è un must per le app Android, assicurando che siano autenticamente create prima dellâinstallazione. Questo processo utilizza un certificato per lâidentificazione dellâapp e deve essere verificato dal gestore pacchetti del dispositivo al momento dellâinstallazione. Le app possono essere autofirmate o certificate da un CA esterno, proteggendo contro accessi non autorizzati e garantendo che lâapp rimanga intatta durante la sua consegna al dispositivo.
Verifica dellâApp per Maggiore Sicurezza
- A partire da Android 4.2, una funzione chiamata Verifica App consente agli utenti di far controllare le app per la sicurezza prima dellâinstallazione. Questo processo di verifica può avvisare gli utenti contro app potenzialmente dannose, o addirittura prevenire lâinstallazione di quelle particolarmente dannose, migliorando la sicurezza dellâutente.
Gestione dei Dispositivi Mobili (MDM)
- Le soluzioni MDM forniscono supervisione e sicurezza per i dispositivi mobili attraverso lâAPI di Amministrazione Dispositivo. Richiedono lâinstallazione di unâapp Android per gestire e proteggere efficacemente i dispositivi mobili. Le funzioni chiave includono lâapplicazione delle politiche di password, lâobbligo di crittografia dello storage e la possibilitĂ di cancellazione remota dei dati, garantendo 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);
}
Enumerare ed Sfruttare i Servizi AIDL / Binder
Android Binder IPC espone molti servizi di sistema e forniti dal venditore. Questi servizi diventano una superficie di attacco quando vengono esportati senza un adeguato controllo dei permessi (il livello AIDL stesso 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
- Traduzione del testo in italiano mantenendo la sintassi markdown e html.
- Non tradurre codice, nomi di tecniche di hacking, parole comuni di hacking, nomi di piattaforme cloud/SaaS.
- Non tradurre link o percorsi.
- Non tradurre o modificare tag, link, riferimenti e percorsi specificati.
- Non aggiungere contenuti extra nella risposta.
145 mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics]
146 wifi : [android.net.wifi.IWifiManager]
- Lâindice (prima colonna) viene assegnato durante lâesecuzione â non fare affidamento su di esso tra i riavvii.
- Il nome del Binder (ad es.
mtkconnmetrics) è ciò che verrĂ passato aservice call. - Il valore allâinterno delle parentesi quadre è lâinterfaccia AIDL completamente qualificata da cui è stato generato lo stub.
2. Ottenere il descrittore dellâinterfaccia (PING)
Ogni stub Binder 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 una stringa UTF-16 allâinterno di un Parcel.
3. Chiamare una transazione
Sintassi: service call <name> <code> [type value ...]
Specificatori di argomento comuni:
i32 <int>â valore intero firmato a 32 biti64 <long>â valore intero firmato a 64 bits16 <string>â stringa UTF-16 (Android 13+ utilizzautf16)
Esempio â avviare il monitoraggio della rete con uid 1 su un dispositivo MediaTek:
service call mtkconnmetrics 8 i32 1
4. Forzatura di metodi sconosciuti
Quando i file di intestazione non sono disponibili, puoi iterare il codice finchĂŠ lâerrore non cambia da:
Result: Parcel(00000000 00000000) # "Not a data message"
a una normale Parcel risposta o SecurityException.
for i in $(seq 1 50); do
printf "[+] %2d -> " $i
service call mtkconnmetrics $i 2>/dev/null | head -1
done
Se il servizio è stato compilato con proguard, la mappatura deve essere indovinata â vedere il passo successivo.
5. Mappatura codici â metodi tramite onTransact()
Decompila il jar/odex che implementa lâinterfaccia (per gli stub AOSP 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 cristallini.
6. Rilevare controlli di autorizzazione mancanti
Lâimplementazione (spesso una classe Impl interna) è 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 UID privilegiati (ad es. uid == 1000 /*system*/) è un indicatore di vulnerabilitĂ .
Studio di caso â MediaTek startMonitorProcessWithUid() (transazione 8) esegue completamente un messaggio Netlink senza alcun gate di permesso, consentendo a unâapp non privilegiata di interagire con il modulo Netfilter del kernel e di riempire il registro di sistema.
7. Automazione della valutazione
Strumenti / script che accelerano il riconoscimento 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()))
Riferimenti
- Android Services 101 â Pentest Partners
- Android Developer Docs â AIDL
- Android Developer Docs â IBinder
- Understanding Binder, Talk @ Google
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.
HackTricks

