This article explains how to create a network socket fuzz test
To be able to test your software with a socket fuzz test you need to be able to compile the software into a dynamic library. CI Fuzz will do this automatically if you set the flag for position independent code compilation in the project.yaml file:
compiler_extra_args:
- "-fPIC"
After this you can create a network socket fuzz test (e.g. using the VS Code plugin). The following code example shows a networks socket fuzzing test:
#include <flibc.h>
#include <fstream>
#include <signal.h>
#include <iostream>
#include <stdio.h>
int start_server(int argc, char** argv) {
//Put your code to start the target server here:
return 0;
}
//Used for timeout for select()
struct timeval tv;
fd_set fdread;
//Used to store server responses
uint8_t buf[1024];
//This function is called in a loop. The data and size are the fuzzing data
//The first argument of this function is a method that will be called once when
//the fuzz test is started, so it should be used to start the server application
FUZZ_TCP_SERVER(start_server, 8080, int client_fd, const uint8_t* data, size_t size) {
//Optional:
//Use this if you want to ignore broken pipe signals
signal(SIGPIPE, SIG_IGN);
//Optional:
//Receive any server banners or messages that are sent when a connection is made
recv(client_fd, buf, 512, 0);
std::cout << buf << "\n";
//Send our fuzzing data to the server
int written = write(client_fd, data, size);
//Optional:
//The following is used to receive potential server answers in a non blocking way.
//Since recv is blocking we need to use select to check if the server is actually sending a response
int selectStatus = 1;
while (selectStatus > 0) {
tv.tv_sec = 0;
tv.tv_usec = 1600;
FD_ZERO(&fdread);
FD_SET( client_fd, &fdread );
selectStatus = select(client_fd+1, &fdread, NULL, NULL, &tv);
//selectStatus bigger than 0 means we can receive something
if (selectStatus > 0) {
int received_bytes = recv(client_fd, buf, 1024, 0);
std::cout << "Received " << received_bytes << " bytes\n" << buf << "\n";
if (received_bytes == 0) break;
//Here you can process the received bytes, e.g. send a specific second request
}
}
}