Contact Stealer
Contact Stealer è un’app sviluppata per il corso di Mobile Systems Security all’università Adam Mickiewicz di Poznań, nata per mostrare in modo pratico come un canale di comunicazione covert (nascosto) possa aggirare i meccanismi di sicurezza tradizionali, sfruttando una comunicazione acustica ultrasonica tra due app apparentemente innocue.
Struttura generale del progetto
Il sistema è composto da due applicazioni distinte, ciascuna con un insieme di permessi limitato e “non sospetto”:
- App1 (Transmitter): richiede l’autorizzazione a leggere i contatti (READ_CONTACTS) e li trasmette tramite segnali BFSK ultrasonici.
- App2 (Receiver): chiede solo l’uso del microfono (RECORD_AUDIO), decodifica i segnali ricevuti e invia i contatti decodificati su Google Sheets.
In questo modo, nessuna delle due app ha simultaneamente accesso sia ai dati sensibili sia alla rete Internet. La trasmissione dei contatti avviene esclusivamente via ultrasuoni, un canale praticamente invisibile all’utente.
Per mandare i dati da App1 –> App2, il progetto utilizza la modulazione BFSK (Binary Frequency-Shift Keying), che codifica i bit usando due frequenze diverse. Nello specifico caso:
- 0 → 20000 Hz
- 1 → 20500 Hz
Entrambe le frequenze sono ultrasoniche, quindi non udibili, e ogni bit è rappresentato da un tono sinusoidale della durata di circa 100 ms.
Per aumentare l’affidabilità ogni bit viene ripetuto 3 volte (ridondanza). Sul lato ricevente viene applicato un meccanismo di majority voting, vengono aggiunti fade-in/out di 5 ms per ridurre artefatti sonori e sono impiegati filtri passa-banda per isolare le frequenze BFSK. Inoltre, tra la trasmissione di un contatto e il successivo è previsto un pausa di 1 secondo per evitare interferenze.
App1 — Transmitter
Permessi richiesti: READ_CONTACTS
L’app legge l’intera rubrica del dispositivo e trasmette i contatti uno alla volta usando la modulazione BFSK in gamma ultrasonica.
Le componenti “operative” principali sono due:
- ContactReader: una classe helper che incapsula la logica di lettura della rubrica, sfruttando l’API ContactsContract del sistema Android. Il suo compito è estrarre i contatti e restituirli in un formato uniforme del tipo “Nome:Numero”;
- BFSKTransmitter: è la parte responsabile della modulazione e dell’emissione sonora. In pratica genera i toni corrispondenti agli 0 e 1, applica un lieve filtraggio di uscita per evitare clic o transitori bruschi, confeziona ogni messaggio in un frame strutturato (preamble, lunghezza, payload, suffix) e infine invia il segnale.
Una semplice MainActivity orchestra le operazioni e fornisce un’interfaccia utente basilare.
App2 — Receiver
Permessi richiesti: RECORD_AUDIO
L’app ascolta continuamente attraverso il microfono del dispositivo, decodifica i segnali BFSK ultrasonici e, una volta ricostruiti i contatti, li invia a un foglio Google utilizzando le credenziali OAuth di un account di servizio.
In questo caso, le componenti principali sono:
- BFSKReceiver (1): è la classe si occupa della gestione dell’audio in ingresso. Essa apre e configura un AudioRecord, legge i buffer audio e li passa al decoder.
- BFSKDecoder: implementa la logica di estrazione dei bit dal segnale: applica due filtri passa-banda centrati su 20 kHz e 20.5 kHz per isolare le componenti associate a 0 e 1, valuta l’energia relativa delle due bande e determina la sequenza binaria in arrivo, includendo i meccanismi di ridondanza e majority voting necessari per mitigare il rumore ambientale.
- BFSKReceiver (2): ricevuti i bit dal decoder, BFSKReceiver si occupa del riconoscimento dei frame strutturati (preamble: 10101010, suffix: 11110000), dell’assemblaggio delle sequenze di bit in byte e della ricostruzione della stringa finale “Nome:Numero”, che poi consegna al SheetsHelper per la persistenza.
- SheetsHelper: si occupa dell’autenticazione verso Google Sheets e dell’inserimento dei dati: per ogni contatto decodificato aggiunge una riga nel foglio “Foglio1” contenente nome, numero e timestamp, permettendo così la raccolta strutturata e la successiva analisi dei dati ricevuti.
Una semplice MainActivity orchestra le operazioni e fornisce un’interfaccia utente basilare.
Puoi trovare maggiori informazioni riguardo al progetto su GitHub.