Projects STRLCPY quote_db Commits f41b4440
🤬
  • ■ ■ ■ ■ ■ ■
    README.md
     1 +# QuoteDB (Vulnerable TCP Server)
     2 + 
     3 +under construction
  • ■ ■ ■ ■ ■ ■
    main.c
     1 +// (Vulnerable) quote_db
     2 +// Created in preparation for OSED
     3 +// William Moody, 06.06.2021
     4 + 
     5 +// Compile and run:
     6 +// gcc main.c -o main.exe -l ws2_32; .\main.exe
     7 + 
     8 +#include <stdio.h>
     9 +#include <stdlib.h>
     10 +#include <unistd.h>
     11 +#include <winsock2.h>
     12 +#include <windows.h>
     13 +#include <time.h>
     14 + 
     15 +#pragma comment(lib, "ws2_32.lib")
     16 + 
     17 +#define VERSION 10
     18 +#define DEFAULT_PORT 3700
     19 +#define MAX_CONNECTIONS 1
     20 +#define BUF_SIZE 8192
     21 +#define QUOTE_SIZE 2048
     22 +#define MAX_NUM_QUOTES 100
     23 + 
     24 +/**
     25 + * Packet structure which is used for all communication
     26 + * from the client to the server:
     27 + *
     28 + * unsigned int opcode;
     29 + * char data[8192];
     30 + *
     31 + * ----------------------------------------------------
     32 + *
     33 + * ... server to the client:
     34 + *
     35 + * char data[8192];
     36 + */
     37 + 
     38 +// Array to hold quotes
     39 +char quotes[MAX_NUM_QUOTES][QUOTE_SIZE];
     40 +int num_quotes;
     41 + 
     42 +/**
     43 + * Displays a server banner in the console
     44 + */
     45 +void banner()
     46 +{
     47 + printf("+===========================+\n");
     48 + printf("| quote_db v%*.*f |\n", 2, 2, VERSION / 10.f);
     49 + printf("| William Moody, 06.06.2021 |\n");
     50 + printf("+===========================+\n\n");
     51 +}
     52 + 
     53 +/**
     54 + * Displays a help message and exits the program
     55 + *
     56 + * @param prog_name Name of the program (argv[0])
     57 + */
     58 +void usage(char *prog_name)
     59 +{
     60 + printf("Usage: %s [-p PORT] [-h]\n", prog_name);
     61 + exit(1);
     62 +}
     63 + 
     64 +/**
     65 + * Adds a quote
     66 + *
     67 + * @param quote The quote to add to the db
     68 + * @returns index of the quote which was added
     69 + */
     70 +int add_quote(char* quote)
     71 +{
     72 + printf("[?] Adding quote to db...");
     73 + memset(quotes[num_quotes], 0, QUOTE_SIZE);
     74 + printf("#%d.\n", num_quotes);
     75 + int copy_size = strlen(quote);
     76 + copy_size = (copy_size > QUOTE_SIZE) ? QUOTE_SIZE : copy_size;
     77 + memcpy(quotes[num_quotes], quote, copy_size);
     78 + return num_quotes++;
     79 +}
     80 + 
     81 +/**
     82 + * Gets a quote by index
     83 + *
     84 + * @param index Index of the quote to give
     85 + * @param quote Buffer to move to quote into
     86 + * @returns a quote
     87 + */
     88 +int get_quote(int index, char **quote)
     89 +{
     90 + printf("[?] Getting quote #%d from db...\n", index);
     91 + int size = strlen(quotes[index]);
     92 + *quote = malloc(size);
     93 + snprintf(*quote, QUOTE_SIZE, quotes[index]);
     94 + return size;
     95 +}
     96 + 
     97 +/**
     98 + * Updates a quote by index
     99 + *
     100 + * @param index Index of the quote to update
     101 + * @param quote New quote to replace the old one with
     102 + */
     103 +void update_quote(int index, char *quote)
     104 +{
     105 + printf("[?] Updating quote with index #%d...\n", index);
     106 + memset(quotes[index], 0, QUOTE_SIZE);
     107 + memcpy(quotes[index], quote, strlen(quote));
     108 + return;
     109 +}
     110 + 
     111 +/**
     112 + * Deletes a quote by index
     113 + *
     114 + * @param index Index of the quote to remove
     115 + */
     116 +void delete_quote(int index)
     117 +{
     118 + printf("[?] Deleting quote with index #%d...\n", index);
     119 + for (int i = index; i < MAX_NUM_QUOTES - 1; i++)
     120 + {
     121 + memset(quotes[i + 1], 0, QUOTE_SIZE);
     122 + memcpy(quotes[i + 1], quotes[i], strlen(quotes[i]));
     123 + }
     124 + num_quotes--;
     125 + return;
     126 +}
     127 + 
     128 +/**
     129 + * Thread - Handles a client connection
     130 + *
     131 + * @param sock The client socket
     132 + */
     133 +void handle_connection(void *sock)
     134 +{
     135 + // Create a buffer to store the incoming packet
     136 + // and init with 0's
     137 + char buf[BUF_SIZE];
     138 + memset(buf, 0, BUF_SIZE);
     139 + 
     140 + // Receive the packet
     141 + int recvlen;
     142 + if ((recvlen = recv((SOCKET)sock, buf, BUF_SIZE, 0)) < 4)
     143 + {
     144 + printf("....[%d] recv failed.\n", GetCurrentThreadId());
     145 + closesocket((SOCKET)sock);
     146 + return;
     147 + }
     148 + 
     149 + printf("....[%d] received %d bytes.\n", GetCurrentThreadId(), recvlen);
     150 + 
     151 + // Check what opcode the client is calling
     152 + unsigned int opcode;
     153 + memcpy(&opcode, (void *)buf, sizeof(unsigned int));
     154 + 
     155 + printf("....[%d] opcode=%d\n", GetCurrentThreadId(), opcode);
     156 + 
     157 + // Create a bufer to hold response
     158 + char response[BUF_SIZE];
     159 + memset(response, 0, BUF_SIZE);
     160 + unsigned response_size = 0;
     161 + 
     162 + // Some definitions for variables used
     163 + // in the switch statement
     164 + char* quote;
     165 + unsigned int quote_index;
     166 + char new_quote[QUOTE_SIZE];
     167 + char *index_out_of_bounds_msg = "INDEX_OUT_OF_BOUNDS";
     168 + char *bad_request_msg = "BAD_REQUEST";
     169 + char *max_quotes_reached_msg = "MAX_NUM_QUOTES_REACHED";
     170 + 
     171 + switch (opcode)
     172 + {
     173 + case 900: ;
     174 + // Ask for a random quote
     175 + time_t t;
     176 + srand((unsigned) time(&t));
     177 + response_size = get_quote(rand() % num_quotes, &quote);
     178 + memcpy(response, quote, response_size);
     179 + break;
     180 + case 901: ;
     181 + // Ask for a specific quote
     182 + memcpy(&quote_index, (void *)(buf + 4), sizeof(unsigned int));
     183 + 
     184 + if (quote_index >= num_quotes)
     185 + {
     186 + response_size = strlen(index_out_of_bounds_msg);
     187 + memcpy(response, index_out_of_bounds_msg, response_size);
     188 + }
     189 + else
     190 + {
     191 + response_size = get_quote(quote_index, &quote);
     192 + memcpy(response, quote, response_size);
     193 + }
     194 + break;
     195 + case 902: ;
     196 + // Add a new quote
     197 + if (num_quotes < MAX_NUM_QUOTES)
     198 + {
     199 + memcpy(new_quote, buf + 4, QUOTE_SIZE);
     200 + quote_index = add_quote(new_quote);
     201 + response_size = sizeof(unsigned int);
     202 + memcpy((void *)response, &quote_index, response_size);
     203 + }
     204 + else
     205 + {
     206 + response_size = strlen(max_quotes_reached_msg);
     207 + memcpy(response, max_quotes_reached_msg, response_size);
     208 + }
     209 + break;
     210 + case 903: ;
     211 + // Update a specific quote
     212 + memcpy(&quote_index, (void *)(buf + 4), sizeof(unsigned int));
     213 + 
     214 + if (quote_index >= num_quotes)
     215 + {
     216 + response_size = strlen(index_out_of_bounds_msg);
     217 + memcpy(response, index_out_of_bounds_msg, response_size);
     218 + }
     219 + else
     220 + {
     221 + update_quote(quote_index, buf + 8);
     222 + }
     223 + break;
     224 + case 904: ;
     225 + // Delete a specific quote
     226 + memcpy(&quote_index, (void *)(buf + 4), sizeof(unsigned int));
     227 + 
     228 + if (quote_index >= num_quotes)
     229 + {
     230 + response_size = strlen(index_out_of_bounds_msg);
     231 + memcpy(response, index_out_of_bounds_msg, response_size);
     232 + }
     233 + else
     234 + {
     235 + delete_quote(quote_index);
     236 + }
     237 + break;
     238 + default: ;
     239 + // Default case (invalid opcode).
     240 + response_size = strlen(bad_request_msg);
     241 + memcpy(response, bad_request_msg, strlen(bad_request_msg));
     242 + break;
     243 + }
     244 + 
     245 + // Send a response if we need to
     246 + if (response_size > 0)
     247 + {
     248 + int sent_bytes;
     249 + if ((sent_bytes = send((SOCKET)sock, response, response_size, 0)) == SOCKET_ERROR)
     250 + {
     251 + printf("....[%d] failed while sending response.\n", GetCurrentThreadId());
     252 + closesocket((SOCKET)sock);
     253 + return;
     254 + }
     255 + printf("....[%d] sent response (%d bytes).\n", GetCurrentThreadId(), sent_bytes);
     256 + }
     257 + 
     258 + // Close the client connection and return
     259 + closesocket((SOCKET)sock);
     260 + printf("....[%d] ended connection.\n", GetCurrentThreadId());
     261 + 
     262 + return;
     263 +}
     264 + 
     265 +/**
     266 + * Starts the server on a given port
     267 + *
     268 + * @param port Port to start the server on
     269 + * @returns -1 if the server failed to start on the given port
     270 + */
     271 +int start_server(int port)
     272 +{
     273 + // Display welcome banner
     274 + banner();
     275 + 
     276 + // Init quote array
     277 + memset(quotes, 0, sizeof(char[QUOTE_SIZE]) * MAX_NUM_QUOTES);
     278 + num_quotes = 0;
     279 +
     280 + // Add some sample quotes
     281 + add_quote("If life were predictable it would cease to be life, and be without flavor. - Eleanor Roosevelt");
     282 + add_quote("Give a man a mask and he'll tell you the truth. - Oscar Wilde");
     283 + add_quote("Do not go where the path may lead, go instead where there is no path and leave a trail. - Ralph Waldo Emerson");
     284 + add_quote("Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead");
     285 + add_quote("If you do not change direction, you may end up where you are heading. - Lao Tzu");
     286 + add_quote("No one has ever failed until he has given up. - Anonymous");
     287 + add_quote("Believe you can you're halfway there. - Theodore Roosevelt");
     288 + add_quote("Do it today or regret it tomorrow. - Anonymous");
     289 + add_quote("Action is the foundation key to all success. - Pablo Picasso");
     290 + add_quote("The only place were success comes before work is in the dictionary. - Vidal Sassoon");
     291 + 
     292 + // Try to initialize the winsock library
     293 + WSADATA wsa;
     294 + if (WSAStartup(0x22, &wsa) != 0)
     295 + {
     296 + printf("[-] Failed to initialize WSA library\n");
     297 + return -1;
     298 + }
     299 + 
     300 + printf("[+] WSA Initialized.\n");
     301 + 
     302 + // Try to create socket
     303 + SOCKET s;
     304 + if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
     305 + {
     306 + printf("[-] Failed to created socket.\n");
     307 + closesocket(s);
     308 + return -1;
     309 + }
     310 + 
     311 + printf("[+] Socket created.\n");
     312 + 
     313 + // Bind socket to the given port
     314 + struct sockaddr_in server;
     315 + server.sin_family = AF_INET;
     316 + server.sin_addr.s_addr = INADDR_ANY;
     317 + server.sin_port = htons(port);
     318 + 
     319 + if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
     320 + {
     321 + printf("[-] Failed to bind to port %d.\n", port);
     322 + closesocket(s);
     323 + return -1;
     324 + }
     325 + 
     326 + printf("[+] Bound to port %d.\n", port);
     327 + 
     328 + // Listen for incoming connection
     329 + listen(s, MAX_CONNECTIONS);
     330 + 
     331 + printf("[+] Listening for incoming connections...\n");
     332 + 
     333 + // Accept connections and create handler threads
     334 + struct sockaddr_in client;
     335 + int c = sizeof(struct sockaddr_in);
     336 + SOCKET client_socket;
     337 + while ((client_socket = accept(s, (struct sockaddr *)&client, &c)) != INVALID_SOCKET)
     338 + {
     339 + printf("[+] Accepted a connection from %s:%d.\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
     340 + _beginthread(&handle_connection, 0, (void *)client_socket);
     341 + }
     342 + 
     343 + if (client_socket == INVALID_SOCKET)
     344 + {
     345 + printf("[-] Error while accepting socket.\n");
     346 + closesocket(s);
     347 + closesocket(client_socket);
     348 + return -1;
     349 + }
     350 + 
     351 + // Close the server socket
     352 + closesocket(s);
     353 + 
     354 + // Close server without errors
     355 + return 0;
     356 +}
     357 + 
     358 +/**
     359 + * Entry point
     360 + * Handles arguments and starts the server
     361 + */
     362 +int main(int argc, char *argv[])
     363 +{
     364 + // Init port to default value
     365 + int port = DEFAULT_PORT;
     366 + 
     367 + // Parse arguments
     368 + int opt;
     369 + while ((opt = getopt(argc, argv, "p:h")) >= 0)
     370 + {
     371 + switch (opt)
     372 + {
     373 + case 'p':
     374 + // Set the server port number
     375 + if (sscanf(optarg, "%i", &port) != 1)
     376 + usage(argv[0]);
     377 + break;
     378 + case 'h':
     379 + // Display the help message
     380 + usage(argv[0]);
     381 + break;
     382 + default:
     383 + break;
     384 + }
     385 + }
     386 + 
     387 + // Start the server
     388 + start_server(port);
     389 + 
     390 + // Cleanup winsock2 library
     391 + WSACleanup();
     392 + 
     393 + // Exit with no errors
     394 + return 0;
     395 +}
Please wait...
Page is in error, reload to recover