La sicurezza nelle applicazioni Android e ios: vulnerabilità e best practice Security Summit Milano, 17 Marzo 2016
Chi siamo Davide Danelon Senior Security Consultant @ Minded Security Android Enthusiast OWASP Testing Guide Contributor & Speaker Riferimenti: LinkedIn: https://it.linkedin.com/in/davidedanelon Blog: http://blog.mindedsecurity.com
Chi siamo Simone Bovi Security Consultant @ Minded Security ios Enthusiast AFNetworking Library Security Issue Riferimenti: LinkedIn: https://it.linkedin.com/in/simonebovi Twitter: @enormecotica Blog: http://blog.mindedsecurity.com
Agenda Feature di sicurezza in Android e ios Similitudini e differenze principali Vulnerabilità frequenti Best practice Progetti OWASP per il Mobile
Android - Feature di sicurezza Sandboxing Application signing Permessi granulari e definiti dall utente Novità introdotte in Android 6/SDK v23 Exploit mitigation Full Disk Encryption
ios - Feature di sicurezza Sandboxing Code signing Exploit mitigation Full Disk Encryption Secure Enclave (TouchID)
Similitudini tra le due piattaforme Sandboxing Controlli per l accesso al dispositivo Accesso limitato all hardware Full Disk Encryption
Differenze tra le due piattaforme Application signing Gestione dei permessi AppStore vs Android marketplace generici Notevole varietà di modelli e vendor di prodotti Android
INSUFFICIENT TRANSPORT LAYER PROTECTION
Insufficient Transport Layer Protection I dati in transito tra app e server devono essere protetti tramite l utilizzo dei protocolli SSL/TLS E necessario assicurare: Confidenzialità Integrità ios 9: Application Transport Security (ATS) Android N Preview: Network Security Configuration
Best practices Non accettare: certificati self-signed certificati scaduti certificati validi ma con hostname non corretto certificati root scaduti Utilizzare la tecnica denominata SSL Pinning!
SSL Pinning Motivi dietro al suo utilizzo: il certificato dell host a cui ci si vuole connettere potrebbe essere stato firmato da una CA compromessa (es. DigiNotar) Android KeyStore e ios Trust Store potrebbero essere stati compromessi dall installazione di un certificato malevolo
SSL Pinning Permette di associare uno specifico host con un certificato o chiave pubblica prevista Possibili implementazioni: Inclusione di un certificato all interno dell applicazione da confrontare con quello presentato dal server durante la sessione SSL Verifica dell hash relativo al campo Subject Public Key Info presente nel certificato esposto dal server
SSL Pinning AndroidPinning (https://github.com/moxie0/androidpinning) String[] pins = new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"}; URL url = new URL("https://www.google.com"); HttpsURLConnection connection = PinningHelper.getPinnedHttpsURLConnection(context, pins, url); return connection.getinputstream();
SSL Pinning TrustKit (https://github.com/datatheorem/trustkit) - (void)viewdidload { [super viewdidload]; NSDictionary *trustkitconfig; trustkitconfig = @{ @"api.paypal.com" : @{ ktskpublickeyalgorithms : @[ktskalgorithmrsa2048], ktskpublickeyhashes : @[ @"ukfooxzpctm...ft+fa6iswgsbo=", @"mwtrdoi4danhom+...myh8styexamue=" ], ktskenforcepinning : @YES } }; [TrustKit initializewithconfiguration]; }
BROKEN ACCESS CONTROL
Broken Access Control Android: Intent spoofing / Permission Re-delegation Power Control Widget ios: URL Scheme Hijacking Skype App
Intent spoofing Esempio con Broadcast Receiver: <receiver android:name=".broadcastreceivers.sendsmsnowreceiver" android:label="send SMS" > <intent-filter> <action android:name="org.owasp.goatdroid.fourgoats.social_sms" /> </intent-filter> </receiver> <receiver android:name=".broadcastreceivers.sendsmsnowreceiver" android:label="send SMS" android:exported= false <intent-filter> <action android:name="org.owasp.goatdroid.fourgoats.social_sms" /> </intent-filter> </receiver>
URL Scheme Hijacking Best Practice: Evitare l utilizzo di URL Scheme se possibile Non inviare dati privati nell URL Validare i dati ricevuti Avvertire l utente prima di eseguire qualunque azione Novità introdotte in ios 9!
INSECURE DATA STORAGE
Insecure Data Storage I dati nella sandbox diventano accessibili anche da altre app in caso di dispositivi rooted/jailbroken I dati salvati nella memoria esterna (Android) sono accessibili da qualunque applicazione E sempre necessario cifrare i dati privati salvati sul dispositivo, ricordando che: bisogna considerare quali siano i dati necessari da salvare meno dati vengono salvati, meno sarà necessario proteggerli
SharedPreferences non sicure Esempio: SharedPreferences WORLD_READABLE Qualunque app potrebbe accedere al file /data/data/app_package_name/shared_prefs/credent ials.xml SharedPreferences credentials = this.getsharedpreferences( "credentials", MODE_WORLD_READABLE); SharedPreferences.Editor editor = credentials.edit(); editor.putstring("username", username); editor.putstring("password", password); editor.putboolean("remember", true); editor.commit();
SharedPreferences non sicure Esempio - Remediation String PBE_ALGORITHM = "PBEWithSHA256And256BitAES-CBC-BC"; String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding"; int NUM_OF_ITERATIONS = 1000; int KEY_SIZE = 256; byte[] salt = embedded_salt".getbytes(); byte[] iv = "1234567890abcdef".getBytes(); String cleartext =...; // This is the value to be encrypted. byte[] encryptedtext; byte[] decryptedtext; PBEKeySpec pbekeyspec = new PBEKeySpec(password.toCharArray(), salt, NUM_OF_ITERATIONS, KEY_SIZE); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(PBE_ALGORITHM); SecretKey tempkey = keyfactory.generatesecret(pbekeyspec); SecretKey secretkey = new SecretKeySpec(tempKey.getEncoded(), "AES"); IvParameterSpec ivspec = new IvParameterSpec(iv); Cipher enccipher = Cipher.getInstance(CIPHER_ALGORITHM); enccipher.init(cipher.encrypt_mode, secretkey, ivspec); Cipher deccipher = Cipher.getInstance(CIPHER_ALGORITHM); deccipher.init(cipher.decrypt_mode, secretkey, ivspec); encryptedtext = enccipher.dofinal(cleartext.getbytes()); decryptedtext = deccipher.dofinal(encryptedtext); String sameascleartext = new String(decryptedText); la password è il PIN dal quale la chiave privata è derivata (KDF)
File di Preferences Le preferences di un app sono salvate in chiaro nella cartella Library/Preferences come property lists tramite la classe NSUserDefaults File usato per salvare oggetti serializzati NSString *valuetosave = @ password ; [[NSUserDefaults standarduserdefaults] setobject:valuetosave forkey:@ preferencename ]; [[NSUserDefaults standarduserdefaults] synchronize]; Non salvare dati privati tramite NSUserDefaults Utilizzare il Keychain!
Database SQLite I database SQLite sono ampiamente usati per il salvataggio di dati client-side Essi possono essere interrogati tramite linguaggio SQL Di default il database non è cifrato ed è rappresentato da un file.db o.sqlite all interno della sandbox
Database SQLite Il database deve essere cifrato! Questo può essere realizzato utilizzando: SQLCipher (https://www.zetetic.net/sqlcipher) Generando la chiave di cifratura a partire dall input dell utente La chiave di cifratura non deve essere hard-coded
UNINTENDED DATA LEAKAGE
Unintended Data Leakage Potrebbero verificarsi leakage di informazioni private dovute a: Problematiche dell OS, dei framework o delle librerie utilizzate per lo sviluppo E opportuno considerare: Caching dei dati (immagini, testo, richieste/risposte) Log Clipboard/Pasteboard Keystroke Logging
Log Disclosure Mostrare informazioni private all interno dei log è una pratica che dovrebbe essere evitata Tali informazioni potrebbero essere lette da altre applicazioni o da chiunque abbia accesso fisico al dispositivo ios >= 7 l Apple System Log ritorna solamente dati appartenenti all applicazione che li richiede Android >= 4.1 il permesso READ_LOGS non può più essere richiesto da applicazioni di terze parti
Log Disclosure Esempio non sicuro: Facebook Android SDK Log.d( Facebook-Authorize, Login success! access_token= + getaccesstoken()); Esempio sicuro: Tramite Proguard -assumenosideeffects class android.util.log { public static *** d(...); public static *** w(...); public static *** v(...); public static *** i(...); }
Log Disclosure DEBUG standard macro: #ifndef DEBUG #define NSLog(...) /* Sostituire le stringhe NSLog e il loro contenuto con una stringa vuota */ #endif
Clipboard/Pasteboard La Clipboard di Android e la Pasteboard di ios sono accessibili senza richiedere permessi Applicazioni malevole potrebbero monitorare passivamente il loro contenuto E importante non utilizzare la clipboard per memorizzare dati privati E opportuno disabilitare le azioni su ogni View che si prevede possa contenere dati privati
Clipboard/Pasteboard Android (singolo campo di testo): edittext.setcustomselectionactionmodelcallback(new Callback() { public boolean onprepareactionmode(actionmode mode, Menu menu) { return false; } public void ondestroyactionmode(actionmode mode) {} public boolean oncreateactionmode(actionmode mode, Menu menu) { return false; } public boolean onactionitemclicked(actionmode mode, MenuItem item) { return false; } }); ios (utilizzando la classe seguente per definire le TextView): - (BOOL)canPerformAction:(SEL)action withsender:(id)sender { if (action == @selector(copy:) action == @selector(cut:) action == @selector(paste:) action == @selector(selectall:)) { return NO; } return [super canperformaction:action withsender:sender]; }
Snapshot leakage Per implementare la funzione di background in modo sicuro, i contenuti dello schermo devono essere nascosti prima che lo screenshot venga effettuato - (void)applicationdidenterbackground:(uiapplication *)application { [UIApplication sharedapplication].keywindow.hidden = YES; } - (void)applicationdidbecomeactive:(uiapplication *)application { [UIApplication sharedapplication].keywindow.hidden = NO; }
Keystroke Logging La funzionalità di Auto Correzione offerta da ios effettua il caching delle stringhe digitate dall utente Dati privati potrebbero essere inseriti nella cache tramite tale funzionalità E opportuno disabilitare la keyboard cache per i campi che si suppone possano contenere dati privati UITextField *textfield = [ [ UITextField alloc ] initwithframe: frame ]; textfield.autocorrectiontype = UITextAutocorrectionTypeNo;
LACK OF BINARY PROTECTION
Private information hardcoded Le applicazioni Android ed ios possono essere decompilate e disassemblate Un attaccante potrebbe essere in grado di venire a conoscenza delle logiche applicative e di eventuali informazioni private contenute nel codice E necessario non considerare mai il codice di un applicazione mobile come privato
Best Practices Non inserire informazioni private all interno del codice sorgente Mantenere eventuali logiche «sensibili» lato server Es. eventuali funzionalità amministrative Offuscare il codice sorgente in modo da rendere complessa l analisi ad un eventuale attaccante Android: ProGuard ios: ios-class-guard (https://github.com/polidea/ios-classguard)
Best Practices Minded Security's Magik Quadrant for Mobile Code Protection
Progetti OWASP per il mobile OWASP Mobile Top Ten 2016 OWASP Mobile Checklist ios: imas igoat Android: GoatDroid
OWASP AppSecEU 2016 Hacking and Securing ios Applications 29/06/2016
Grazie dell attenzione! http://blog.mindedsecurity.com