diff --git a/.cifuzz-build/input.txt b/.cifuzz-build/input.txt new file mode 100644 index 0000000..bccb652 --- /dev/null +++ b/.cifuzz-build/input.txt @@ -0,0 +1,2 @@ +1 +Ciao \ No newline at end of file diff --git a/.cifuzz-build/libfuzzer/address+undefined/.cmake/api/v1/query/client-vscode/query.json b/.cifuzz-build/libfuzzer/address+undefined/.cmake/api/v1/query/client-vscode/query.json new file mode 100644 index 0000000..82bb964 --- /dev/null +++ b/.cifuzz-build/libfuzzer/address+undefined/.cmake/api/v1/query/client-vscode/query.json @@ -0,0 +1 @@ +{"requests":[{"kind":"cache","version":2},{"kind":"codemodel","version":2},{"kind":"toolchains","version":1},{"kind":"cmakeFiles","version":1}]} \ No newline at end of file diff --git a/.cifuzz-build/libfuzzer/address+undefined/CMakeCache.txt b/.cifuzz-build/libfuzzer/address+undefined/CMakeCache.txt new file mode 100644 index 0000000..ce5ba0a --- /dev/null +++ b/.cifuzz-build/libfuzzer/address+undefined/CMakeCache.txt @@ -0,0 +1,97 @@ +# This is the CMakeCache file. +# For build in directory: /home/zacarias/Desktop/CodeIntelligence/TcpServer/TcpServer/.cifuzz-build/libfuzzer/address+undefined +# It was generated by CMake: /usr/bin/cmake +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +# KEY:TYPE=VALUE +# KEY is the name of a variable in the cache. +# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. +# VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + +//No help, variable specified on the command line. +CIFUZZ_ENGINE:UNINITIALIZED=libfuzzer + +//No help, variable specified on the command line. +CIFUZZ_SANITIZERS:UNINITIALIZED=address;undefined + +//No help, variable specified on the command line. +CIFUZZ_TESTING:BOOL=ON + +//No help, variable specified on the command line. +CMAKE_BUILD_RPATH_USE_ORIGIN:BOOL=ON + +//No help, variable specified on the command line. +CMAKE_BUILD_TYPE:UNINITIALIZED=RelWithDebInfo + +//Path to a program. +CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make + +//Value Computed by CMake +CMAKE_PROJECT_DESCRIPTION:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_HOMEPAGE_URL:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_NAME:STATIC=TcpServer + +//Value Computed by CMake +TcpServer_BINARY_DIR:STATIC=/home/zacarias/Desktop/CodeIntelligence/TcpServer/TcpServer/.cifuzz-build/libfuzzer/address+undefined + +//Value Computed by CMake +TcpServer_IS_TOP_LEVEL:STATIC=ON + +//Value Computed by CMake +TcpServer_SOURCE_DIR:STATIC=/home/zacarias/Desktop/CodeIntelligence/TcpServer/TcpServer + + +######################## +# INTERNAL cache entries +######################## + +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=/home/zacarias/Desktop/CodeIntelligence/TcpServer/TcpServer/.cifuzz-build/libfuzzer/address+undefined +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=22 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=3 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=/usr/bin/cmake +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest +//Path to cache edit program executable. +CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/ccmake +//Name of external makefile project generator. +CMAKE_EXTRA_GENERATOR:INTERNAL= +//Name of generator. +CMAKE_GENERATOR:INTERNAL=Unix Makefiles +//Generator instance identifier. +CMAKE_GENERATOR_INSTANCE:INTERNAL= +//Name of generator platform. +CMAKE_GENERATOR_PLATFORM:INTERNAL= +//Name of generator toolset. +CMAKE_GENERATOR_TOOLSET:INTERNAL= +//Source directory with the top level CMakeLists.txt file for this +// project +CMAKE_HOME_DIRECTORY:INTERNAL=/home/zacarias/Desktop/CodeIntelligence/TcpServer/TcpServer +//ADVANCED property for variable: CMAKE_MAKE_PROGRAM +CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 +//number of local generators +CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1 +//Platform information initialized +CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1 +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.22 +//uname command +CMAKE_UNAME:INTERNAL=/usr/bin/uname + diff --git a/.cifuzz-build/libfuzzer/address+undefined/CMakeFiles/3.22.3/CMakeSystem.cmake b/.cifuzz-build/libfuzzer/address+undefined/CMakeFiles/3.22.3/CMakeSystem.cmake new file mode 100644 index 0000000..14a03a4 --- /dev/null +++ b/.cifuzz-build/libfuzzer/address+undefined/CMakeFiles/3.22.3/CMakeSystem.cmake @@ -0,0 +1,15 @@ +set(CMAKE_HOST_SYSTEM "Linux-5.4.0-110-generic") +set(CMAKE_HOST_SYSTEM_NAME "Linux") +set(CMAKE_HOST_SYSTEM_VERSION "5.4.0-110-generic") +set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64") + + + +set(CMAKE_SYSTEM "Linux-5.4.0-110-generic") +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_SYSTEM_VERSION "5.4.0-110-generic") +set(CMAKE_SYSTEM_PROCESSOR "x86_64") + +set(CMAKE_CROSSCOMPILING "FALSE") + +set(CMAKE_SYSTEM_LOADED 1) diff --git a/.cifuzz-build/libfuzzer/address+undefined/CMakeFiles/CMakeOutput.log b/.cifuzz-build/libfuzzer/address+undefined/CMakeFiles/CMakeOutput.log new file mode 100644 index 0000000..b557a2d --- /dev/null +++ b/.cifuzz-build/libfuzzer/address+undefined/CMakeFiles/CMakeOutput.log @@ -0,0 +1 @@ +The system is: Linux - 5.4.0-110-generic - x86_64 diff --git a/.cifuzz-build/libfuzzer/address+undefined/CMakeFiles/cmake.check_cache b/.cifuzz-build/libfuzzer/address+undefined/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..3dccd73 --- /dev/null +++ b/.cifuzz-build/libfuzzer/address+undefined/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/.cifuzz-build/logs/build-my_fuzz_test.log b/.cifuzz-build/logs/build-my_fuzz_test.log new file mode 100644 index 0000000..e69de29 diff --git a/.github/workflows/Vulnerability.yml b/.github/workflows/Vulnerability.yml new file mode 100644 index 0000000..43f6526 --- /dev/null +++ b/.github/workflows/Vulnerability.yml @@ -0,0 +1,124 @@ +name: Vulnerability Assessment + +on: + workflow_dispatch: + push: + branches: + - main + pull_request: + branches: [ main ] + +env: + FUZZING_SERVER_ADDRESS: grpc.code-intelligence.com:443 + WEB_APP_ADDRESS: https://app.code-intelligence.com + CHECKOUT_DIR: TcpServer/ + CIFUZZ_DOWNLOAD_URL: "https://github.com/CodeIntelligenceTesting/cifuzz/releases/latest/download/cifuzz_installer_linux_amd64" + CIFUZZ_INSTALL_DIR: ./cifuzz + FUZZING_ARTIFACT: fuzzing-artifact.tar.gz + BUILD_TYPE: Release + +jobs: + fuzz-test: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + with: + repository: gladzeka/TcpServer + ref: main + + - name: Create Input.txt + run: | + echo "1" > input.txt + echo ",CIAO_Zac" >> input.txt + echo "2" >> input.txt + echo "FUZZ TEST RESULTS" > fuzz_results.txt + + + - name: Setup CMake + run: | + sudo apt-get install -y cmake + + - name: Download CMakeLists.txt + run: | + curl -sSL -o CMakeLists.txt https://github.com/gladzeka/TcpServer/raw/main/CMakeLists.txt + + + - name: Create Destination Directory + run: | + mkdir -p ${{ env.CHECKOUT_DIR }}/build/ + cp CMakeLists.txt ${{ env.CHECKOUT_DIR }} + ls ${{ env.CHECKOUT_DIR }} + + - name: Create Fuzz Directory + run: | + mkdir -p ${{ env.CHECKOUT_DIR }}/results/ + cp fuzz_results.txt ${{ env.CHECKOUT_DIR }} + ls ${{ env.CHECKOUT_DIR }} + + + - name: Install cifuzz + run: | + curl --fail --silent --show-error --location -o cifuzz_installer "$CIFUZZ_DOWNLOAD_URL" + chmod u+x cifuzz_installer + ./cifuzz_installer --install-dir $CIFUZZ_INSTALL_DIR + + - name: Setup Environment + run: | + sudo apt-get update + + - name: Build Server + run: | + cmake . + cmake --build . + + - name: List Directories + run: | + pwd && ls # display the working directory and List the files in the current directory + + + - name: Start Server + run: | + ./tcp_server & + + - name: Start Client + run: | + pwd && ls + cat input.txt | ./tcp_client + #echo "::set-output name=clientFinished::true" + continue-on-error: true + + - name: Fuzz commands + run: | + sh -c "$(curl -fsSL https://raw.githubusercontent.com/CodeIntelligenceTesting/cifuzz/main/install.sh)" + cifuzz init + cifuzz login + cifuzz run heap_buffer_overflow_test + + + + - name: Start Fuzz + run: | + cp test/Fuzzing/inputvalidation.py . + python inputvalidation.py & + + #cat input.txt | ./tcp_client + #echo -e "1\n Mio msg" | ./tcp_client + continue-on-error: true + + + + + - name: Save Fuzz Test Results + if: always() + run: | + # Save thee fuzzing test results to an artifact or a file for further analysis + cp fuzz_results.txt ${{ env.CHECKOUT_DIR }}/results/fuzz_results.txt + + - name: Upload Fuzz Test Results + if: always() + uses: actions/upload-artifact@v2 + with: + name: Fuzz Test Results + path: ${{ env.CHECKOUT_DIR }}/results + diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b3553ae --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "cmake.configureOnOpen": true, + "files.associations": { + "*.py": "python", + "*.txt": "plaintext", + "*.yml": "cpp", + "chrono": "cpp", + "system_error": "cpp", + "xlocale": "cpp", + "typeinfo": "cpp" + }, + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..05054c5 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: g++ build active file", + "command": "/usr/bin/g++", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/CMakeLists - backup.txt b/CMakeLists - backup.txt new file mode 100644 index 0000000..6795e26 --- /dev/null +++ b/CMakeLists - backup.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.8.1) +project(tcp_client_server) + +find_package (Threads) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-std=c++11") + +add_library(${PROJECT_NAME} + src/tcp_client.cpp + src/tcp_server.cpp + src/client.cpp + src/pipe_ret_t.cpp + src/common.cpp) + +option(SERVER_EXAMPLE "Build SERVER" ON) + +if(SERVER_EXAMPLE) + + add_definitions( + -DSERVER_EXAMPLE + ) + + add_executable(tcp_server examples/server_example.cpp) + + target_link_libraries (tcp_server ${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT}) + +endif() + +option(CLIENT_EXAMPLE "Build CLIENT" ON) + +if(CLIENT_EXAMPLE) + + add_definitions( + -DCLIENT_EXAMPLE + ) + + add_executable(tcp_client examples/client_example.cpp) + + target_link_libraries (tcp_client ${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT}) + +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 6795e26..ccfee5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 3.8.1) -project(tcp_client_server) + cmake_minimum_required(VERSION 3.8.1) +project(TcpServer) find_package (Threads) diff --git a/CMakeUserPresets.json b/CMakeUserPresets.json new file mode 100644 index 0000000..e507671 --- /dev/null +++ b/CMakeUserPresets.json @@ -0,0 +1,100 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 20, + "patch": 0 + }, + "configurePresets": [ + { + "name": "cifuzz (Coverage)", + "displayName": "cifuzz (Coverage)", + "binaryDir": "${sourceDir}/.cifuzz-build/replayer/gcov", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CIFUZZ_ENGINE": "replayer", + "CIFUZZ_SANITIZERS": "gcov", + "CIFUZZ_TESTING": { + "type": "BOOL", + "value": "ON" + }, + "CMAKE_BUILD_RPATH_USE_ORIGIN": { + "type": "BOOL", + "value": "ON" + } + } + }, + { + "name": "cifuzz (Fuzzing)", + "displayName": "cifuzz (Fuzzing)", + "binaryDir": "${sourceDir}/.cifuzz-build/libfuzzer/address+undefined", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CIFUZZ_ENGINE": "libfuzzer", + "CIFUZZ_SANITIZERS": "address;undefined", + "CIFUZZ_TESTING": { + "type": "BOOL", + "value": "ON" + }, + "CMAKE_BUILD_RPATH_USE_ORIGIN": { + "type": "BOOL", + "value": "ON" + } + }, + "environment": { + "CC": "clang", + "CXX": "clang++" + } + }, + { + "name": "cifuzz (Regression Test)", + "displayName": "cifuzz (Regression Test)", + "binaryDir": "${sourceDir}/.cifuzz-build/replayer/address+undefined", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CIFUZZ_ENGINE": "replayer", + "CIFUZZ_SANITIZERS": "address;undefined", + "CIFUZZ_TESTING": { + "type": "BOOL", + "value": "ON" + }, + "CMAKE_BUILD_RPATH_USE_ORIGIN": { + "type": "BOOL", + "value": "ON" + } + } + } + ], + "buildPresets": [ + { + "name": "cifuzz (Coverage)", + "displayName": "cifuzz (Coverage)", + "configurePreset": "cifuzz (Coverage)", + "configuration": "RelWithDebInfo" + }, + { + "name": "cifuzz (Fuzzing)", + "displayName": "cifuzz (Fuzzing)", + "configurePreset": "cifuzz (Fuzzing)", + "configuration": "RelWithDebInfo" + }, + { + "name": "cifuzz (Regression Test)", + "displayName": "cifuzz (Regression Test)", + "configurePreset": "cifuzz (Regression Test)", + "configuration": "RelWithDebInfo" + } + ], + "testPresets": [ + { + "name": "cifuzz (Regression Test)", + "displayName": "cifuzz (Regression Test)", + "configurePreset": "cifuzz (Regression Test)", + "filter": { + "include": { + "label": "^cifuzz_regression_test$" + } + } + } + ] +} diff --git a/build.sh b/build.sh old mode 100755 new mode 100644 diff --git a/cifuzz.yaml b/cifuzz.yaml new file mode 100644 index 0000000..4464473 --- /dev/null +++ b/cifuzz.yaml @@ -0,0 +1,46 @@ +## Configuration for a CI Fuzz project +## Generated on 2023-05-31 + +## The build system used to build this project. If not set, cifuzz tries +## to detect the build system automatically. +## Valid values: "bazel", "cmake", "maven", "gradle", "other". +#build-system: cmake + +## If the build system type is "other", this command is used by +## `cifuzz run` to build the fuzz test. +#build-command: "make my_fuzz_test" + +## Directories containing sample inputs for the code under test. +## See https://llvm.org/docs/LibFuzzer.html#corpus +#seed-corpus-dirs: +# - path/to/seed-corpus + +## A file containing input language keywords or other interesting byte +## sequences. +## See https://llvm.org/docs/LibFuzzer.html#dictionaries +#dict: path/to/dictionary.dct + +## Command-line arguments to pass to libFuzzer. +## See https://llvm.org/docs/LibFuzzer.html#options +#engine-args: +# - -rss_limit_mb=4096 + +## Maximum time to run fuzz tests. The default is to run indefinitely. +#timeout: 30m + +## By default, fuzz tests are executed in a sandbox to prevent accidental +## damage to the system. Set to false to run fuzz tests unsandboxed. +## Only supported on Linux. +#use-sandbox: false + +## Set to true to print output of the `cifuzz run` command as JSON. +#print-json: true + +## Set to true to disable desktop notifications +#no-notifications: true + +## Set URL of the CI App +#server: https://app.code-intelligence.com + +## Set the project name on the CI App +#project: my-project-1a2b3c4d diff --git a/examples/myfuzztest.cpp b/examples/myfuzztest.cpp new file mode 100644 index 0000000..13fc581 --- /dev/null +++ b/examples/myfuzztest.cpp @@ -0,0 +1,155 @@ +#ifdef SERVER_EXAMPLE + +#include +#include +#include +#include + +#include "../include/tcp_server.h" + +// declare the server +TcpServer server; + +// declare a server observer which will receive incomingPacketHandler messages. +// the server supports multiple observers +server_observer_t observer; + +bool shouldSaveMsg = false; +char msgBuffer[10] = {0}; + +std::mutex mtx; +std::condition_variable server_ready; +bool canAcceptNextClient = true; + +// observer callback. will be called for every new message received by clients +// with the requested IP address +void onIncomingMsg(const std::string &clientIP, const char *msg, size_t size) { + std::string msgStr = msg; + if (msgStr == "S") { + shouldSaveMsg = true; + } else if (shouldSaveMsg) { + if (strncmp(msgStr.c_str(), "M", 1) == 0) { + memcpy(msgBuffer, msg, size); + } + shouldSaveMsg = false; + } + // print client message + std::cout << "Observer1 got client msg: " << msgStr << "\n"; +} + +// observer callback. will be called when client disconnects +void onClientDisconnected(const std::string &ip, const std::string &msg) { + std::cout << "Client: " << ip << " disconnected. Reason: " << msg << "\n"; + { + std::lock_guard lock(mtx); + canAcceptNextClient = true; + server_ready.notify_one(); + } +} + +int main() { + // start server on port 65123 + pipe_ret_t startRet = server.start(65123); + if (startRet.isSuccessful()) { + std::cout << "Server setup succeeded\n"; + } else { + std::cout << "Server setup failed: " << startRet.message() << "\n"; + return EXIT_FAILURE; + } + + // configure and register observer + observer.incomingPacketHandler = onIncomingMsg; + observer.disconnectionHandler = onClientDisconnected; + observer.wantedIP = "127.0.0.1"; + server.subscribe(observer); + + while (true) { + acceptClient(); + { + std::lock_guard lock(mtx); + canAcceptNextClient = false; + } + std::unique_lock lock(mtx); + server_ready.wait(lock, [] { return canAcceptNextClient; }); + } + + return 0; +} + +#endif +/////////////////////////////////////////////////////////// +/////////////////////CLIENT EXAMPLE//////////////////////// +/////////////////////////////////////////////////////////// + +#ifdef CLIENT_EXAMPLE + +#include +#include +#include "../include/tcp_client.h" + +TcpClient client; + +// on sig_exit, close client +void sig_exit(int s) { + std::cout << "Closing client...\n"; + pipe_ret_t finishRet = client.close(); + if (finishRet.isSuccessful()) { + std::cout << "Client closed.\n"; + } else { + std::cout << "Failed to close client.\n"; + } + exit(0); +} + +// observer callback. will be called for every new message received by the server +void onIncomingMsg(const char *msg, size_t size) { + std::cout << "Got msg from server: " << msg << "\n"; +} + +// observer callback. will be called when server disconnects +void onDisconnection(const pipe_ret_t &ret) { + std::cout << "Server disconnected: " << ret.message() << "\n"; +} + +int main() { + // register to SIGINT to close client when user press ctrl+c + signal(SIGINT, sig_exit); + + // configure and register observer + client_observer_t observer; + observer.wantedIP = "127.0.0.1"; + observer.incomingPacketHandler = onIncomingMsg; + observer.disconnectionHandler = onDisconnection; + client.subscribe(observer); + + // connect client to an open server + bool connected = false; + while (!connected) { + pipe_ret_t connectRet = client.connectTo("127.0.0.1", 65123); + connected = connectRet.isSuccessful(); + if (connected) { + std::cout << "Client connected successfully\n"; + } else { + std::cout << "Client failed to connect: " << connectRet.message() << "\n" + << "Make sure the server is open and listening\n\n"; + sleep(2); + std::cout << "Retrying to connect...\n"; + } + } + + // send messages to server + while (true) { + // Fuzzed input for sending a message to the server + std::string message = /* fuzzed message */; + pipe_ret_t sendRet = client.sendMsg(message.c_str(), message.size()); + if (!sendRet.isSuccessful()) { + std::cout << "Failed to send message: " << sendRet.message() << "\n"; + } else { + std::cout << "Message was sent successfully\n"; + } + } + + return 0; +} + +#endif diff --git a/examples/server_example.cpp b/examples/server_example.cpp index 3d9f21d..b4781b7 100644 --- a/examples/server_example.cpp +++ b/examples/server_example.cpp @@ -42,9 +42,8 @@ void acceptClient() { } -// observer callback. will be called for every new message received by clients -// with the requested IP address -void onIncomingMsg(const std::string &clientIP, const char * msg, size_t size) { + + void onIncomingMsg(const std::string &clientIP, const char * msg, size_t size) { std::string msgStr = msg; if (msgStr == "S") { shouldSaveMsg = true; @@ -54,8 +53,17 @@ void onIncomingMsg(const std::string &clientIP, const char * msg, size_t size) { } shouldSaveMsg = false; } - // print client message + // Print client message std::cout << "Observer1 got client msg: " << msgStr << "\n"; + + // Check for the X-Injected-Header value + std::string injectedHeaderValue = "MaliciousContentChironda"; + if (msgStr == injectedHeaderValue) { + std::cout << "Zacarias has injected a file heree: " << msgStr << "\n"; + // Example: server.handleInjectedHeader(injectedHeaderValue); + } + + } // observer callback. will be called when client disconnects diff --git a/start.txt b/start.txt new file mode 100644 index 0000000..91b9f0b --- /dev/null +++ b/start.txt @@ -0,0 +1,2 @@ +1 +Ciao diff --git a/test/Fuzzing/DoS.py b/test/Fuzzing/DoS.py new file mode 100644 index 0000000..d0d65bd --- /dev/null +++ b/test/Fuzzing/DoS.py @@ -0,0 +1,20 @@ +import socket + +# Connect to the server +server_address = ('localhost', 65123) +client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +client_socket.connect(server_address) + +# Define the payload to be sent repeatedly +payload = "A" * 1000 # Adjust the payload length as needed + +try: + # Send the payload repeatedly + while True: + client_socket.sendall(payload.encode()) +except KeyboardInterrupt: + # Interrupt the loop on keyboard interrupt + pass + +# Close the connection +client_socket.close() diff --git a/test/Fuzzing/crash.py b/test/Fuzzing/crash.py new file mode 100644 index 0000000..d7f97d5 --- /dev/null +++ b/test/Fuzzing/crash.py @@ -0,0 +1,27 @@ +import random + +# Function to fuzz-test +def process_input(input_string): + if input_string == "crash": + # Simulate a crash or error condition + raise Exception("Crash detected!") + else: + # Process the input normally + print("Processing input:", input_string) + +# Fuzz test the process_input function +def fuzz_test(): + while True: + # Generate a random input + input_length = random.randint(1, 10) + input_chars = [chr(random.randint(32, 126)) for _ in range(input_length)] + input_string = "".join(input_chars) + + # Call the process_input function with the generated input + try: + process_input(input_string) + except Exception as e: + print("Exception:", str(e)) + +# Run the fuzz test +fuzz_test() diff --git a/test/Fuzzing/input_dir/accesscontrol.py b/test/Fuzzing/input_dir/accesscontrol.py new file mode 100644 index 0000000..80694e1 --- /dev/null +++ b/test/Fuzzing/input_dir/accesscontrol.py @@ -0,0 +1,16 @@ + # Define the vulnerable function +def vulnerable_function(user_input): + if user_input == "admin": + print("Access granted!") + else: + print("Access denied!") + +# Fuzzing with AFL +import subprocess + +# Define the AFL command +afl_command = ["afl-fuzz", "-i", "input_dir", "-o", "output_dir", "--", "python", "-c", + "from main import vulnerable_function; import sys; vulnerable_function(sys.stdin.readline().strip())"] + +# Start the fuzzing process +subprocess.run(afl_command) diff --git a/test/Fuzzing/input_dir/output_dir/cmdline b/test/Fuzzing/input_dir/output_dir/cmdline new file mode 100644 index 0000000..9379a34 --- /dev/null +++ b/test/Fuzzing/input_dir/output_dir/cmdline @@ -0,0 +1,2 @@ +python +fuzzer.py diff --git a/test/Fuzzing/input_dir/output_dir/plot_data b/test/Fuzzing/input_dir/output_dir/plot_data new file mode 100644 index 0000000..4461bb2 --- /dev/null +++ b/test/Fuzzing/input_dir/output_dir/plot_data @@ -0,0 +1 @@ +# unix_time, cycles_done, cur_path, paths_total, pending_total, pending_favs, map_size, unique_crashes, unique_hangs, max_depth, execs_per_sec diff --git a/test/Fuzzing/input_dir/testcase1.py b/test/Fuzzing/input_dir/testcase1.py new file mode 100644 index 0000000..97ca304 --- /dev/null +++ b/test/Fuzzing/input_dir/testcase1.py @@ -0,0 +1,32 @@ +import socket + +# Connect to the server +server_address = ('localhost', 65123) +client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +client_socket.connect(server_address) + +# Craft a test case for input validation +# Modify the client IP and message to simulate different scenarios +# Example 1: Valid input +client_ip = '127.0.0.1' +message = 'Hello, server!' +# Example 2: Invalid input (containing a semicolon) +# client_ip = '127.0.0.1;' +# message = 'Malicious payload' +# Example 3: Invalid input (empty client IP) +# client_ip = '' +# message = 'Hello, server!' + +# Craft the payload by combining client IP and message +payload = f'{client_ip}\n{message}' + +# Send the payload to the server +client_socket.sendall(payload.encode()) + +# Receive and print the server's response +response = client_socket.recv(1024).decode() +print(response) + +# Close the connection +client_socket.close() + diff --git a/test/Fuzzing/input_dir/testcase2 b/test/Fuzzing/input_dir/testcase2 new file mode 100644 index 0000000..140c703 --- /dev/null +++ b/test/Fuzzing/input_dir/testcase2 @@ -0,0 +1 @@ +name="DoS.py" diff --git a/test/Fuzzing/inputvalidation.py b/test/Fuzzing/inputvalidation.py new file mode 100644 index 0000000..d299d0e --- /dev/null +++ b/test/Fuzzing/inputvalidation.py @@ -0,0 +1,36 @@ +""" +By executing this Python code, I want to emulating a client that sends the malicious payload to the server +attempting to exploit the input validation vulnerability +""" + +import socket +# Connect to the server +server_address = ('localhost', 65123) +client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +client_socket.connect(server_address) + +# Craft a malicious client IP and message +# Modifying the inputs to "127.0.0.1; rm -rf /" +# Establishing a connection with the server using a socket. +# Then, I craft a payload by combining the malicious client IP (127.0.0.1; rm -rf /) and message (S; rm -rf /). +# I send the payload to the server and receive the server's response. +# +client_ip = '127.0.0.1; rm -rf /' +message = 'S; rm -rf /' +message2 = '127.0.0.1' + + +# Craft the payload by combining client IP and message +payload = f'{client_ip}\n{message}\n{message2}' + +# Send the payload to the server +client_socket.sendall(payload.encode()) + +# Receive and print the server's response +response = client_socket.recv(1024).decode() +print(response) + +# Close the connection +client_socket.close() + + diff --git a/test/Fuzzing/output_dir/.cur_input b/test/Fuzzing/output_dir/.cur_input new file mode 100644 index 0000000..e69de29 diff --git a/test/Fuzzing/output_dir/cmdline b/test/Fuzzing/output_dir/cmdline new file mode 100644 index 0000000..bf2fc12 --- /dev/null +++ b/test/Fuzzing/output_dir/cmdline @@ -0,0 +1 @@ +tcp_server diff --git a/test/Fuzzing/output_dir/plot_data b/test/Fuzzing/output_dir/plot_data new file mode 100644 index 0000000..4461bb2 --- /dev/null +++ b/test/Fuzzing/output_dir/plot_data @@ -0,0 +1 @@ +# unix_time, cycles_done, cur_path, paths_total, pending_total, pending_favs, map_size, unique_crashes, unique_hangs, max_depth, execs_per_sec diff --git a/test/Fuzzing/output_dir/queue/id:000000,time:0,orig:accesscontrol.py b/test/Fuzzing/output_dir/queue/id:000000,time:0,orig:accesscontrol.py new file mode 100644 index 0000000..80694e1 --- /dev/null +++ b/test/Fuzzing/output_dir/queue/id:000000,time:0,orig:accesscontrol.py @@ -0,0 +1,16 @@ + # Define the vulnerable function +def vulnerable_function(user_input): + if user_input == "admin": + print("Access granted!") + else: + print("Access denied!") + +# Fuzzing with AFL +import subprocess + +# Define the AFL command +afl_command = ["afl-fuzz", "-i", "input_dir", "-o", "output_dir", "--", "python", "-c", + "from main import vulnerable_function; import sys; vulnerable_function(sys.stdin.readline().strip())"] + +# Start the fuzzing process +subprocess.run(afl_command) diff --git a/test/Fuzzing/output_dir/queue/id:000001,time:0,orig:crash.py b/test/Fuzzing/output_dir/queue/id:000001,time:0,orig:crash.py new file mode 100644 index 0000000..d7f97d5 --- /dev/null +++ b/test/Fuzzing/output_dir/queue/id:000001,time:0,orig:crash.py @@ -0,0 +1,27 @@ +import random + +# Function to fuzz-test +def process_input(input_string): + if input_string == "crash": + # Simulate a crash or error condition + raise Exception("Crash detected!") + else: + # Process the input normally + print("Processing input:", input_string) + +# Fuzz test the process_input function +def fuzz_test(): + while True: + # Generate a random input + input_length = random.randint(1, 10) + input_chars = [chr(random.randint(32, 126)) for _ in range(input_length)] + input_string = "".join(input_chars) + + # Call the process_input function with the generated input + try: + process_input(input_string) + except Exception as e: + print("Exception:", str(e)) + +# Run the fuzz test +fuzz_test() diff --git a/test/Fuzzing/output_dir/queue/id:000002,time:0,orig:testcase1.py b/test/Fuzzing/output_dir/queue/id:000002,time:0,orig:testcase1.py new file mode 100644 index 0000000..97ca304 --- /dev/null +++ b/test/Fuzzing/output_dir/queue/id:000002,time:0,orig:testcase1.py @@ -0,0 +1,32 @@ +import socket + +# Connect to the server +server_address = ('localhost', 65123) +client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +client_socket.connect(server_address) + +# Craft a test case for input validation +# Modify the client IP and message to simulate different scenarios +# Example 1: Valid input +client_ip = '127.0.0.1' +message = 'Hello, server!' +# Example 2: Invalid input (containing a semicolon) +# client_ip = '127.0.0.1;' +# message = 'Malicious payload' +# Example 3: Invalid input (empty client IP) +# client_ip = '' +# message = 'Hello, server!' + +# Craft the payload by combining client IP and message +payload = f'{client_ip}\n{message}' + +# Send the payload to the server +client_socket.sendall(payload.encode()) + +# Receive and print the server's response +response = client_socket.recv(1024).decode() +print(response) + +# Close the connection +client_socket.close() + diff --git a/test/Fuzzing/output_dir/queue/id:000003,time:0,orig:testcase2 b/test/Fuzzing/output_dir/queue/id:000003,time:0,orig:testcase2 new file mode 100644 index 0000000..140c703 --- /dev/null +++ b/test/Fuzzing/output_dir/queue/id:000003,time:0,orig:testcase2 @@ -0,0 +1 @@ +name="DoS.py" diff --git a/test/my_fuzz_test.cpp b/test/my_fuzz_test.cpp new file mode 100644 index 0000000..13fc581 --- /dev/null +++ b/test/my_fuzz_test.cpp @@ -0,0 +1,155 @@ +#ifdef SERVER_EXAMPLE + +#include +#include +#include +#include + +#include "../include/tcp_server.h" + +// declare the server +TcpServer server; + +// declare a server observer which will receive incomingPacketHandler messages. +// the server supports multiple observers +server_observer_t observer; + +bool shouldSaveMsg = false; +char msgBuffer[10] = {0}; + +std::mutex mtx; +std::condition_variable server_ready; +bool canAcceptNextClient = true; + +// observer callback. will be called for every new message received by clients +// with the requested IP address +void onIncomingMsg(const std::string &clientIP, const char *msg, size_t size) { + std::string msgStr = msg; + if (msgStr == "S") { + shouldSaveMsg = true; + } else if (shouldSaveMsg) { + if (strncmp(msgStr.c_str(), "M", 1) == 0) { + memcpy(msgBuffer, msg, size); + } + shouldSaveMsg = false; + } + // print client message + std::cout << "Observer1 got client msg: " << msgStr << "\n"; +} + +// observer callback. will be called when client disconnects +void onClientDisconnected(const std::string &ip, const std::string &msg) { + std::cout << "Client: " << ip << " disconnected. Reason: " << msg << "\n"; + { + std::lock_guard lock(mtx); + canAcceptNextClient = true; + server_ready.notify_one(); + } +} + +int main() { + // start server on port 65123 + pipe_ret_t startRet = server.start(65123); + if (startRet.isSuccessful()) { + std::cout << "Server setup succeeded\n"; + } else { + std::cout << "Server setup failed: " << startRet.message() << "\n"; + return EXIT_FAILURE; + } + + // configure and register observer + observer.incomingPacketHandler = onIncomingMsg; + observer.disconnectionHandler = onClientDisconnected; + observer.wantedIP = "127.0.0.1"; + server.subscribe(observer); + + while (true) { + acceptClient(); + { + std::lock_guard lock(mtx); + canAcceptNextClient = false; + } + std::unique_lock lock(mtx); + server_ready.wait(lock, [] { return canAcceptNextClient; }); + } + + return 0; +} + +#endif +/////////////////////////////////////////////////////////// +/////////////////////CLIENT EXAMPLE//////////////////////// +/////////////////////////////////////////////////////////// + +#ifdef CLIENT_EXAMPLE + +#include +#include +#include "../include/tcp_client.h" + +TcpClient client; + +// on sig_exit, close client +void sig_exit(int s) { + std::cout << "Closing client...\n"; + pipe_ret_t finishRet = client.close(); + if (finishRet.isSuccessful()) { + std::cout << "Client closed.\n"; + } else { + std::cout << "Failed to close client.\n"; + } + exit(0); +} + +// observer callback. will be called for every new message received by the server +void onIncomingMsg(const char *msg, size_t size) { + std::cout << "Got msg from server: " << msg << "\n"; +} + +// observer callback. will be called when server disconnects +void onDisconnection(const pipe_ret_t &ret) { + std::cout << "Server disconnected: " << ret.message() << "\n"; +} + +int main() { + // register to SIGINT to close client when user press ctrl+c + signal(SIGINT, sig_exit); + + // configure and register observer + client_observer_t observer; + observer.wantedIP = "127.0.0.1"; + observer.incomingPacketHandler = onIncomingMsg; + observer.disconnectionHandler = onDisconnection; + client.subscribe(observer); + + // connect client to an open server + bool connected = false; + while (!connected) { + pipe_ret_t connectRet = client.connectTo("127.0.0.1", 65123); + connected = connectRet.isSuccessful(); + if (connected) { + std::cout << "Client connected successfully\n"; + } else { + std::cout << "Client failed to connect: " << connectRet.message() << "\n" + << "Make sure the server is open and listening\n\n"; + sleep(2); + std::cout << "Retrying to connect...\n"; + } + } + + // send messages to server + while (true) { + // Fuzzed input for sending a message to the server + std::string message = /* fuzzed message */; + pipe_ret_t sendRet = client.sendMsg(message.c_str(), message.size()); + if (!sendRet.isSuccessful()) { + std::cout << "Failed to send message: " << sendRet.message() << "\n"; + } else { + std::cout << "Message was sent successfully\n"; + } + } + + return 0; +} + +#endif