
Routeur ASUS — Exécution de commandes root par infosvr UDP Broadcast
Plusieurs modèles de routeurs d'ASUS incluent un service appelé infosvr qui écoute sur le port de diffusion UDP 9999 sur l'interface LAN ou WLAN. Il est utilisé par l'un des outils d'ASUS pour faciliter la configuration du routeur en localisant automatiquement les routeurs sur le sous-réseau local. Ce service s'exécute avec les privilèges root et contient une vulnérabilité d'exécution de commande sans authentification. Le code source de ce service, ainsi que celui du reste du routeur, est disponible sur le site d'assistance d'ASUS.
Le CVE attribué à ce problème est CVE-2014-9583 (hélas, pas CVE-2014-10000 finalement :-/).
Actuellement, toutes les versions de firmware connues pour les routeurs concernés (RT-AC66U, RT-N66U, etc.) sont supposées vulnérables. Les tests ont été effectués contre la version 3.0.0.4.376.2524-g0013f52.
Les routeurs/versions de firmware suivants sont confirmés vulnérables :
| Routeur | Version du firmware | Vérifié par |
|---|---|---|
| RT-N66U | 3.0.0.4.376_1071-g8696125 | Friedrich Postelstorfer |
| RT-AC87U | 3.0.0.4.378_3754 | David Longenecker |
| RT-N56U | 3.0.0.4.374_5656 | @argilo |
| RT-AC68U | 3.0.0.4.376_3626-g9a8323e | @Arie |
| DSL-N55U | 3.0.0.4.374_4422-gc83c78f | @S2- |
| DSL-AC68U | 3.0.0.4.376_2158-g340202b | @magJ, @gitFurious |
| RT-AC66R | 3.0.0.4.376_2524-g0013f52 | @asgh |
| RT-AC66R | 3.0.0.4.376_3602 | @facerolling |
| RT-AC55U | 3.0.0.4.376_6587-gaa506e9 | @pellaeon |
| RT-N12HP_B1 | 3.0.0.4.374_1327 | @vittee |
| RT-N16 | 3.0.0.4.220 | @xorrbit |
De plus, les routeurs exécutant un firmware basé sur asuswrt-merlin, soutenu par la communauté, sont vulnérables avant la version 376.49_5.
Les routeurs utilisant des révisions de firmware publiées le 12 janvier 2015 ou après ne devraient pas être affectés. Le tableau suivant recense les signalements de routeurs/firmwares non affectés.
| Routeur | Version du firmware | Vérifié par |
|---|---|---|
| RT-AC66R | 3.0.0.4.376_3754-g5ef7c1f | @asgh |
| RT-N12HP_B1 | 3.0.0.4.376_3754-g5ef7c1f | @vittee |
Considérez l'extrait suivant du projet ASUSWRT-Merlin, qui est un fork amélioré du code d'ASUS. Vous pouvez consulter le fichier dans son intégralité (recommandé pour des fous rires supplémentaires) ici.
177 char *processPacket(int sockfd, char *pdubuf)
178 {
...
202 phdr = (IBOX_COMM_PKT_HDR *)pdubuf;
...
207 if (phdr->ServiceID==NET_SERVICE_ID_IBOX_INFO &&
208 phdr->PacketType==NET_PACKET_TYPE_CMD)
209 {
...
La fonction processPacket est appelée après réception d'un paquet de INFO_PDU_LENGTH (512) octets. Le chemin de code vulnérable spécifique est main->processReq->processPacket. Le service convertit ensuite le paquet en une structure et vérifie que les champs ServiceID et PacketType correspondent aux valeurs attendues.
Le bloc suivant contient ce qui est considéré comme la cause racine de cette vulnérabilité.
222 if (phdr->OpCode!=NET_CMD_ID_GETINFO && phdr->OpCode!=NET_CMD_ID_GETINFO_MANU)
223 {
224 phdr_ex = (IBOX_COMM_PKT_HDR_EX *)pdubuf;
225
226 // Check Mac Address
227 if (memcpy(phdr_ex->MacAddress, mac, 6)==0)
228 {
229 _dprintf("Mac Error %2x%2x%2x%2x%2x%2x\n",
230 (unsigned char)phdr_ex->MacAddress[0],
231 (unsigned char)phdr_ex->MacAddress[1],
232 (unsigned char)phdr_ex->MacAddress[2],
233 (unsigned char)phdr_ex->MacAddress[3],
234 (unsigned char)phdr_ex->MacAddress[4],
235 (unsigned char)phdr_ex->MacAddress[5]
236 );
237 return NULL;
238 }
239
240 // Check Password
241 //if (strcmp(phdr_ex->Password, "admin")!=0)
242 //{
243 // phdr_res->OpCode = phdr->OpCode | NET_RES_ERR_PASSWORD;
244 // _dprintf("Password Error %s\n", phdr_ex->Password);
245 // return NULL;
246 //}
247 phdr_res->Info = phdr_ex->Info;
248 memcpy(phdr_res->MacAddress, phdr_ex->MacAddress, 6);
249 }
Le bloc commence par exclure quelques valeurs de OpCode, qui ne nécessitent probablement pas d'authentification par conception. Ensuite, il appelle memcpy et vérifie de manière suspecte la valeur de retour par rapport à zéro. Cela indique fortement que l'auteur avait l'intention d'utiliser memcmp à la place. Cela dit, même si cette vérification était implémentée correctement, connaître l'adresse MAC de l'appareil ne constitue guère une authentification suffisante.
Le bloc suivant est commenté, mais montre que l'auteur a, à un moment donné, expérimenté la vérification d'un mot de passe. Bien que, dans ce cas, le mot de passe était codé en dur comme « admin ».
Ensuite, l'instruction switch suivante répartit le traitement en fonction de la valeur OpCode fournie.
251 switch(phdr->OpCode)
252 {
...
428 case NET_CMD_ID_MANU_CMD:
429 {
430 #define MAXSYSCMD 256
431 char cmdstr[MAXSYSCMD];
432 PKT_SYSCMD *syscmd;
...
440 syscmd = (PKT_SYSCMD *)(pdubuf+sizeof(IBOX_COMM_PKT_HDR_EX));
...
443 if (syscmd->len>=MAXSYSCMD) syscmd->len=MAXSYSCMD;
444 syscmd->cmd[syscmd->len]=0;
445 syscmd->len=strlen(syscmd->cmd);
446 fprintf(stderr,"system cmd: %d %s\n", syscmd->len, syscmd->cmd);
447 #if 0
...
512 #endif
513 {
514 sprintf(cmdstr, "%s > /tmp/syscmd.out", syscmd->cmd);
515 system(cmdstr);
Si un attaquant spécifie la valeur de OpCode NET_CMD_ID_MANU_CMD, le bloc précédent traite le paquet en le convertissant en une structure PKT_SYSCMD. Ainsi, tous les membres de syscmd sont entièrement contrôlés par l'attaquant. Avant de prendre soin (clin d'œil) de terminer la chaîne de commande par un NUL, l'auteur exécute la commande à la ligne 514. Après l'exécution de la commande, la sortie est lue depuis le fichier temporaire et renvoyée à l'adresse source du paquet initiateur.
Utilisateurs finaux : Mettez à jour le firmware vers la révision 3.0.0.4.376.3754 ou plus récente. Il est important de noter que la fonctionnalité « Rechercher une mise à jour » du routeur peut ne pas fonctionner correctement. Vérifiez manuellement la version du firmware que vous exécutez et, si elle est plus ancienne, téléchargez/installez le nouveau firmware.