diff --git a/custom_net_fuzzer.c b/custom_net_fuzzer.c index eb29ee1..85c3a93 100644 --- a/custom_net_fuzzer.c +++ b/custom_net_fuzzer.c @@ -26,17 +26,41 @@ static u8 enable_socket_fuzzing = 0; /* Enable network fuzzing */ static u8 is_TCP = 1; /* TCP or UDP */ static u32 target_port = 0x0; /* Target port to send test cases */ static u32 socket_init_delay = SOCKET_INIT_DELAY; /* Socket init delay */ -static u8 *target_ip_address = NULL; /* Target IP to send test cases */ +static u8* target_ip_address = NULL; /* Target IP to send test cases */ static SOCKET ListenSocket = INVALID_SOCKET; static SOCKET ClientSocket = INVALID_SOCKET; -static void send_data_tcp(const char *buf, const int buf_len, int first_time) { - static struct sockaddr_in si_other; - static int slen = sizeof(si_other); - static WSADATA wsa; +int connect_to_tcp(char* ip, int port) { int s; + struct sockaddr_in si_other; + + // setup address structure + memset((char*)&si_other, 0, sizeof(si_other)); + si_other.sin_family = AF_INET; + si_other.sin_port = htons(target_port); + si_other.sin_addr.S_un.S_addr = inet_addr((char*)target_ip_address); + + /* In case of TCP we need to open a socket each time we want to establish + * connection. In theory we can keep connections always open but it might + * cause our target behave differently (probably there are a bunch of + * applications where we should apply such scheme to trigger interesting + * behavior). + */ + if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == SOCKET_ERROR) + printf("socket() failed with error code : %d", WSAGetLastError()); + + // Connect to server. + while (connect(s, (SOCKADDR*)&si_other, sizeof(si_other)) == SOCKET_ERROR) + printf("connect() failed with error code : %d", WSAGetLastError()); + + return s; +} + +static void send_data_tcp(const char* buf, const int buf_len, int first_time) { + static WSADATA wsa; + static int s = INVALID_SOCKET; if (first_time == 0x0) { /* wait while the target process open the socket */ @@ -45,39 +69,21 @@ static void send_data_tcp(const char *buf, const int buf_len, int first_time) { if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) FATAL("WSAStartup failed. Error Code : %d", WSAGetLastError()); - // setup address structure - memset((char *)&si_other, 0, sizeof(si_other)); - si_other.sin_family = AF_INET; - si_other.sin_port = htons(target_port); - si_other.sin_addr.S_un.S_addr = inet_addr((char *)target_ip_address); + s = connect_to_tcp(target_ip_address, target_port); } - /* In case of TCP we need to open a socket each time we want to establish - * connection. In theory we can keep connections always open but it might - * cause our target behave differently (probably there are a bunch of - * applications where we should apply such scheme to trigger interesting - * behavior). - */ - if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == SOCKET_ERROR) - FATAL("socket() failed with error code : %d", WSAGetLastError()); - - // Connect to server. - if (connect(s, (SOCKADDR *)& si_other, slen) == SOCKET_ERROR) - FATAL("connect() failed with error code : %d", WSAGetLastError()); - // Send our buffer - if (send(s, buf, buf_len, 0) == SOCKET_ERROR) - FATAL("send() failed with error code : %d", WSAGetLastError()); - - // shutdown the connection since no more data will be sent - if (shutdown(s, 0x1/*SD_SEND*/) == SOCKET_ERROR) - FATAL("shutdown failed with error: %d\n", WSAGetLastError()); - // close the socket to avoid consuming much resources - if (closesocket(s) == SOCKET_ERROR) - FATAL("closesocket failed with error: %d\n", WSAGetLastError()); + while (send(s, buf, buf_len, 0) <= 0) { + printf("send() failed with error code : %d", WSAGetLastError()); + // close the socket to avoid consuming much resources + if (closesocket(s) == SOCKET_ERROR) + printf("closesocket failed with error: %d\n", WSAGetLastError()); + + s = connect_to_tcp(target_ip_address, target_port); + } } -static void send_data_udp(const char *buf, const int buf_len, int first_time) { +static void send_data_udp(const char* buf, const int buf_len, int first_time) { static struct sockaddr_in si_other; static int s, slen = sizeof(si_other); static WSADATA wsa; @@ -93,20 +99,20 @@ static void send_data_udp(const char *buf, const int buf_len, int first_time) { FATAL("socket() failed with error code : %d", WSAGetLastError()); // setup address structure - memset((char *)&si_other, 0, sizeof(si_other)); + memset((char*)&si_other, 0, sizeof(si_other)); si_other.sin_family = AF_INET; si_other.sin_port = htons(target_port); - si_other.sin_addr.S_un.S_addr = inet_addr((char *)target_ip_address); + si_other.sin_addr.S_un.S_addr = inet_addr((char*)target_ip_address); } // send the data - if (sendto(s, buf, buf_len, 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR) + if (sendto(s, buf, buf_len, 0, (struct sockaddr*)&si_other, slen) == SOCKET_ERROR) FATAL("sendto() failed with error code : %d", WSAGetLastError()); } #define DEFAULT_BUFLEN 4096 -CUSTOM_SERVER_API int APIENTRY dll_run(char *data, long size, int fuzz_iterations) { +CUSTOM_SERVER_API int APIENTRY dll_run(char* data, long size, int fuzz_iterations) { if (is_TCP) send_data_tcp(data, size, fuzz_iterations); else @@ -115,10 +121,10 @@ CUSTOM_SERVER_API int APIENTRY dll_run(char *data, long size, int fuzz_iteration } static int optind; -static u8 *optarg; +static u8* optarg; -int getopt(int argc, char **argv, char *optstring) { - char *c; +int getopt(int argc, char** argv, char* optstring) { + char* c; optarg = NULL; int i = 0; @@ -153,24 +159,24 @@ int getopt(int argc, char **argv, char *optstring) { void usage() { printf("Network fuzzing options:\n\n"\ - " -a - IP address to send data in\n"\ - " -U - Use UDP (default TCP)\n"\ - " -p - Port to send data in\n"\ - " -w - Delay in milliseconds before start sending data\n"); + " -a - IP address to send data in\n"\ + " -U - Use UDP (default TCP)\n"\ + " -p - Port to send data in\n"\ + " -w - Delay in milliseconds before start sending data\n"); exit(1); } static int optind; -static u8 *optarg; +static u8* optarg; #define MAX_ARGS 28 -char **convert_to_array(char *args, int *argc) { +char** convert_to_array(char* args, int* argc) { int element_id = 0; int last_element_offset = 0; - char *c = NULL; + char* c = NULL; int length = strlen(args); - char **argv = malloc(MAX_ARGS * sizeof (char *)); + char** argv = malloc(MAX_ARGS * sizeof(char*)); while (args) { c = strchr(args, ' '); @@ -181,7 +187,7 @@ char **convert_to_array(char *args, int *argc) { if (len <= 0) break; - char *element = malloc(len); + char* element = malloc(len); memcpy(element, args, len); element[len] = '\0'; @@ -210,9 +216,9 @@ CUSTOM_SERVER_API int APIENTRY dll_init() { if (!first_time) return 1; - char *args = getenv("AFL_CUSTOM_DLL_ARGS"); + char* args = getenv("AFL_CUSTOM_DLL_ARGS"); - char **argv = convert_to_array(args, &argc); + char** argv = convert_to_array(args, &argc); if (args == NULL) usage(); @@ -249,7 +255,7 @@ CUSTOM_SERVER_API int APIENTRY dll_init() { usage(); printf("Ready to begin fuzzing. Target IP= %s, target port = %d\n", - target_ip_address, target_port); + target_ip_address, target_port); first_time = 0x0; return 1; -} +} \ No newline at end of file diff --git a/test_netmode.cpp b/test_netmode.cpp index ef436af..2aec90f 100644 --- a/test_netmode.cpp +++ b/test_netmode.cpp @@ -10,7 +10,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -21,10 +21,13 @@ */ /* cmd line to find the crash: + * For UDP * set AFL_CUSTOM_DLL_ARGS=-U -p 7714 -a 127.0.0.1 -w 1000 - * C:\Users\max\Desktop\winafl\winafl_fork\build\Debug>afl-fuzz.exe -l custom_net_fuzzer.dll - * -i in -o out -D ..\..\dr_release\bin32 -t 20000 -- -target_module test_netmode.exe -target_method - * recv_func -coverage_module test_netmode.exe -fuzz_iterations 5000 -nargs 1 -- test_netmode.exe + * For TCP + * set AFL_CUSTOM_DLL_ARGS=-T -p 7714 -a 127.0.0.1 -w 1000 + * C:\Users\max\Desktop\winafl\winafl_fork\build\Debug>afl-fuzz.exe -l custom_net_fuzzer.dll + * -i in -o out -D ..\..\dr_release\bin32 -t 20000 -- -target_module test_netmode.exe -target_method + * recv_func -coverage_module test_netmode.exe -fuzz_iterations 5000 -nargs 3 -- test_netmode.exe -T 7714 */ #define _CRT_SECURE_NO_WARNINGS @@ -38,30 +41,116 @@ #define DEFAULT_PORT 7714 #define BUFSIZE 4096 -/* TODO: test for TCP */ +void usage() +{ + printf("Options:\n\n"\ + " -U - Use UDP\n"\ + " -T - Use TCP\n"\ + " 7714 - Port\n"); +} -void error(const char *msg) { +void error(const char* msg) +{ printf("[ERROR] %s %d\n", msg, WSAGetLastError()); - exit(-1); + exit(-1); } -struct sockaddr_in serveraddr; /* server's addr */ +int make_upd_sock(int portno) +{ + int sockfd = INVALID_SOCKET; + + while (true) { + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd == INVALID_SOCKET) { + error("UDP socket creation failed"); + break; + } + + int optval = 1; + /* UDP */ + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&optval, sizeof(int))) { + error("Set socket options failed"); + closesocket(sockfd); + sockfd = INVALID_SOCKET; + break; + } + + struct sockaddr_in serveraddr; + + memset((char*)&serveraddr, 0, sizeof(serveraddr)); + serveraddr.sin_family = AF_INET; + serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); + serveraddr.sin_port = htons((unsigned short)portno); + + if (bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == SOCKET_ERROR) { + error("ERROR on binding"); + closesocket(sockfd); + sockfd = INVALID_SOCKET; + } + + break; + } + + return sockfd; +} + +int make_tcp_sock(int portno) +{ + int clientSockFd = INVALID_SOCKET; + int serverSockfd = INVALID_SOCKET; + + while (true) { + // Create server socket + serverSockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (serverSockfd == INVALID_SOCKET) { + error("TCP socket creation failed"); + } + + struct sockaddr_in serveraddr; + + // Bind socket to port + serveraddr.sin_family = AF_INET; + serveraddr.sin_addr.s_addr = INADDR_ANY; + serveraddr.sin_port = htons((unsigned short)portno); + + if (bind(serverSockfd, (sockaddr*)&serveraddr, sizeof(serveraddr)) == SOCKET_ERROR) { + error("ERROR on binding"); + } + + // Start listening + if (listen(serverSockfd, SOMAXCONN) == SOCKET_ERROR) { + error("Listen failed"); + } + + //move to make_tcp_sock + struct sockaddr_in clientAddr; + int clientAddrSize = sizeof(clientAddr); + + clientSockFd = accept(serverSockfd, (sockaddr*)&clientAddr, &clientAddrSize); + if (clientSockFd == INVALID_SOCKET) { + error("connect_tcp_client err"); + } + + break; + } + + closesocket(serverSockfd); + + return clientSockFd; +} -void recv_func(int sockfd) -{ - char *buf; - struct sockaddr_in clientaddr; /* client addr */ - int clientlen = sizeof(clientaddr); - int n = 0; +bool __declspec(noinline) recv_func(int sockfd) +{ + char buf[BUFSIZE] = { 0x00 }; - buf = (char *)malloc(BUFSIZE); + int n = recv(sockfd, buf, BUFSIZE, 0); - /* receiving over UDP */ - n = recvfrom(sockfd, buf, BUFSIZE, 0, (struct sockaddr *)&clientaddr, &clientlen); - if (n < 0) - error("ERROR in recvfrom"); + if (n <= 0) { + printf("ERROR in recvfrom %d\n", WSAGetLastError()); + return false; + } - if (buf[0] == 'P') { + if (buf[0] == 'P') { if (buf[1] == 'W') { if (buf[2] == 'N') { if (buf[3] == 'I') { @@ -74,38 +163,50 @@ void recv_func(int sockfd) } } - printf("Received %d bytes, content = %s\n", n, buf); - free(buf); + printf("Received %d bytes, content = %s\n", n, buf); + return true; } int main(int argc, char** argv) { - int sockfd; + int sockFd; int portno = DEFAULT_PORT; - int optval; static WSADATA wsaData; static int iResult; + if (argc < 3) { + usage(); + return 0; + } + + bool useTCP = true; + + if (strcmp(argv[1], "-U") == 0x0) + useTCP = false; + + portno = atoi(argv[2]); + if (!portno) { + usage(); + return 0; + } + // Initialize Winsock iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd < 0) - error("ERROR opening socket"); - - optval = 1; - /* UDP */ - setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof(int)); + if (useTCP) + sockFd = make_tcp_sock(portno); + else + sockFd = make_upd_sock(portno); - memset((char *)&serveraddr, 0, sizeof(serveraddr)); - serveraddr.sin_family = AF_INET; - serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); - serveraddr.sin_port = htons((unsigned short)portno); + if (sockFd == INVALID_SOCKET) { + error("ERROR opening socket"); + WSACleanup(); + return -1; + } - if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) - error("ERROR on binding"); while (1) { - recv_func(sockfd); + recv_func(sockFd); } - return 0; + + return 0; }