
Pour la demande d'extraction (pull request) de Metasploit
Ceci peut résoudre le problème #8571, qui demande des modules Phoenix Talon.
Sur la machine cible, un double-free est déclenché en raison du noyau qui conserve une copie supplémentaire de mc_list au moment de accept().
Une machine exécutant un noyau 4.10.15 et inférieur est à risque si elle exécute la routine suivante :
sockfd = socket(AF_INET, xx, IPPROTO_TCP);
setsockopt(sockfd, SOL_IP, MCAST_JOIN_GROUP, xxxx, xxxx);
bind(sockfd, xxxx, xxxx);
listen(sockfd, xxxx);
newsockfd = accept(sockfd, xxxx, xxxx);
close(newsockfd); // trigger release calls, handoff to RCU
sleep(5); // wait for rcu to free()
close(sockfd); // second free()
Le socket parent, sockfd, est créé. Il est ajouté au groupe multicast avec l'option MCAST_JOIN_GROUP. En ajoutant le socket au groupe multicast sur l'interface locale, le noyau alloue de la mémoire. À ce stade, mc_list existe dans le socket parent.
Après qu'une adresse a été assignée au socket avec bind(), listen() pour la connexion et accept(). accept() crée un nouveau socket, newsockfd, auquel tous les champs nécessaires du parent sont copiés, y compris la valeur du pointeur mc_list. À ce stade, il y a plusieurs pointeurs pointant vers le même bloc de mémoire, d'où le double free.
Lorsque la connexion est établie, le noyau crée un socket enfant qui hérite de l'objet mc_list du socket parent. Ce défaut d'héritage se trouve dans inet_csk_clone_lock à la ligne 648 du fichier net/ipv4/inet_connection_sock.c. Consultez le correctif pour voir la correction d'une ligne pour cet héritage non intentionnel.
Ensuite, fermez le socket enfant. Comme expliqué ci-dessus, cela ne libère pas l'objet mc_list. Il passe par la structure RCU (remote-copy-update) pour libérer la mémoire. sleep() pendant quelques secondes pour s'assurer que le transfert RCU a suffisamment de temps pour appeler kfree(). Enfin, fermez le socket parent, ce qui déclenchera le second free.
DoS simple. Déclenchez à distance un double-free sur une machine cible connue exécutant la routine serveur requise (expliquée ci-dessus). Cela provoque un kernel panic.