mardi 10 novembre 2009

le worm de l'iphone

Fatalement, fallait bien que ça arrive, un (nouveau) worm sur un téléphone mobile; et pas n'importe lequel: l'iPhone d'Apple. Alors que Mme Michu se rassure, seuls les iPhones dits "jailbreakés" sont concernés (il s'agit des iPhones dont l'utilisateur a fait tomber la protection contre l'exécution des exécutables par signature numérique, en gros [j'ai grossièrement résumé]).
Le code était public jusqu'à récemment, mais il semblerait que ça ne soit plus le cas; Mais par chance, il est encore disponible à de nombreux endroits.
Alors dans les médias, on nous présente toujours les développeurs de virus et autres worms comme étant des petits génies de la programmation; ce n'est clairement pas ce que je pense en lisant le code source de ce worm.
syslog(LOG_DEBUG, "Lannnnn");
scanner(lanRanges);
syslog(LOG_DEBUG, "VODAPHONE");
scanner(vodRanges1);
scanner(vodRanges2);
scanner(vodRanges3);
syslog(LOG_DEBUG, "OPTUSSSS");
scanner(optRanges1);
scanner(optRanges2);
scanner(optRanges3);
scanner(optRanges4);
scanner(optRanges5);
scanner(optRanges6);
syslog(LOG_DEBUG, "Telstra");
scanner(telRanges);
Vous en conviendrez aisément, ce code fait mal aux yeux. Et ensuite, sa série de variables "optRangesX", "vodRangesX", il les a définies plus haut:
char *locRanges = getAddrRange();
char *lanRanges = "192.168.0.0-192.168.255.255"; // #172.16.0.0-172.31.255.255 Ehh who uses it
char *vodRanges1 = "202.81.64.0-202.81.79.255";
char *vodRanges2 = "23.98.128.0-123.98.143.255";
char *vodRanges3 = "120.16.0.0-120.23.255.255";
char *optRanges1 = "114.72.0.0-114.75.255.255";
char *optRanges2 = "203.2.75.0-203.2.75.255";
char *optRanges3 = "210.49.0.0-210.49.255.255";
char *optRanges4 = "203.17.140.0-203.17.140.255";
char *optRanges5 = "203.17.138.0-203.17.138.255";
char *optRanges6 = "211.28.0.0-211.31.255.255";
char *telRanges = "58.160.0.0-58.175.255.25";
//char *attRanges = "32.0.0.0-32.255.255.255"; // TOO BIG
Alors vous aurez noté des trucs sympa, comme le 192.168.255.255, qui est utilisé comme borne haute dans la rangée d'adresses IP à scanner sur un LAN, ce qui n'est pas une obligation - en 192.168, c'est du /24 par défaut - ce qui fait que son programme a une chance non négligeable de tenter un nombre incroyable de connexions vers des IP ne faisant pas partie du même réseau que l'iPhone. Je ne sais pas ce que ça donne en terme de consommation CPU, mais ça doit pas être très optimal tout ça. On passera sur les adresses de broadcast aussi. Sa remarque sur le fait que personne n'utilise les IP privées en 172.16.x.y aussi. Puis il oublie les IP en 10.x.y.z (on passera sur les autres, qui sont encore plus rarement utilisées comme les 4-5.x.y.z, utilisées par exemple par hamachi :-)
Il aurait pu utiliser un ioctl() pour récupérer ces paramètres, afin de rendre son code fonctionnel dans les configurations réseau "moins répandues", et surtout optimiser la métode de propagation.
Revenons-en à nos moutons: la série d'appels à la fonction "scanner", qui aurait quand même pu être méchament simplifiée, par exemple en définissant une structure (en C) avec un entier comme "index", et une chaine de caractères qui contienne sa rangée d'adresses IP; ensuite, il n'avait plus qu'à itérer en incrémentant son index, et il se retrouvait avec un code sensiblement plus extensible (supposons qu'il veuille rajouter une rangée d'adresses IP pour un opérateur: il se retrouve à devoir ajouter un nouveau "optRangesX" correspondant à cet opérateur, ainsi qu'un ou plusieurs appels à "scanner()" en fonction du nombre de rangées d'adresses IP de l'opérateur; pour un code de quelques lignes comme celui -ci ça passe encore: pour un projet de grande envergure, je ne ferais pas appel à ce type).
J'ai aussi une petite pensée pour ses fonctions "runCommand" et "prunCommand", qui sont quasiment identiques, la différence étant que la première renvoie 0 si l'iPhone est vulnérable (comprendre: si l'utilisateur de l'iPhone n'a pas changé le mot de passe root).
En fait ça me fait plus penser à du code qu'un développeur PHP de 15 ans aurait pu pondre, et ça, même le commentaire en header du fichier ne me fera pas penser le contraire:
// This code is CLOSED source.
// And very hacky, i just needed it to work.
Je ne vais pas m'étendre plus sur le code source de ce truc. Sur Zataz, la question est posée sur "comment il sélectionne ses victimes", il y a plusieurs réponses, dont deux données au dessus:
- les ranges d'IP de quelques opérateurs;
- les IP du réseau local de l'iPhone, si une connexion wifi est active;
- des IP générées aléatoirement.
Dans tous les cas, le ver essaie de se connecter via ssh à chacune de ces adresses IP en essayant le mot de passe par défaut d'un iPhone, et en tentant l'exécution d'une commande ("echo 99"). Si cette commande reussit, la fonction "infectHost" est appelée, le fond d'écran de l'utilisateur est supprimé, et remplacé par un autre, puis le worm s'installe dans les scripts de démarrage, afin d'être lancé à chaque reboot de l'iPhone.
En plus d'avoir jailbreaké son iPhone et laissé le mot de passe root par défaut (même si 90% des stats sont inventées, je pense que 99% des utilisateurs d'iPhone jailbreakés [qui doivent être une minorité] ont laissé le pass root sans le changer), il faut que le port ssh de l'iPhone soit accessible depuis le reste d'internet; je ne sais pas ce que ça donne en france par contre à ce niveau là.
Il est maintenant temps de retourner à l'écoute en boucle du clip du moment.

1 commentaire:

Vincent a dit…

Sur Orange, pour en avoir discuté il y a quelques temps, il semblerait qu'ils aient senti venir la blague en avance et filtré le problème.
Et c'était il y a quelques mois déjà.

- Sweet limonade.