From 6f44676e9ef71b80d12a856a8ff8c3ffedeb3948 Mon Sep 17 00:00:00 2001 From: Christian Templen Grave Date: Wed, 10 Jul 2024 13:11:27 +0200 Subject: [PATCH] fix neutralising %n by doubling %, as it is no longer an intended exploit --- service/src/cli.c | 14 +++++----- service/src/server.c | 61 ++++++++++++++++++++++++++++++++++++++++++-- service/src/server.h | 4 ++- 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/service/src/cli.c b/service/src/cli.c index e85645a..cb3fc28 100644 --- a/service/src/cli.c +++ b/service/src/cli.c @@ -81,12 +81,12 @@ int interact_cli(session_t *session) strncpy(file_path, argument1 + 1, argument2 - argument1 - 1); file_path[argument2 - argument1 - 1] = '\0'; strcpy(custom_ID, argument2 + 1); - trim_whitespace(file_path); + trim_whitespace(file_path, sizeof(file_path)); } else { strcpy(file_path, argument1 + 1); - trim_whitespace(file_path); + trim_whitespace(file_path, sizeof(file_path)); generate_custom_id(custom_ID, 16); } } @@ -144,7 +144,7 @@ int interact_cli(session_t *session) read_size = recv(session->sock, parrot_input, 256, 0); // Null-terminate and remove newline parrot_input[read_size] = '\0'; - trim_whitespace(parrot_input); + trim_whitespace(parrot_input, sizeof(parrot_input)); fflush(stdout); // If parrot input is empty, ask to save with identity @@ -158,7 +158,7 @@ int interact_cli(session_t *session) read_size = recv(session->sock, identity_input, 256, 0); // Null-terminate and remove newline identity_input[read_size - 1] = '\0'; - trim_whitespace(identity_input); + trim_whitespace(identity_input, sizeof(identity_input)); fflush(stdout); if (strncmp(identity_input, "y", 255) == 0) @@ -212,6 +212,8 @@ int interact_cli(session_t *session) sprintf(scam_filename, "%s_%s_scam_%s_%s", lower_case_pirate_adjective, lower_case_pirate_noun, date, time_str); } + printf("Filepath: %s\n", file_path); + // Save as a treasure file with a password if (strncmp(parrot_input, "", 255) != 0) { @@ -451,7 +453,7 @@ void cat_file(char *filename, session_t *session) read_size = recv(session->sock, password_input, 256, 0); // Null-terminate and remove newline password_input[read_size] = '\0'; - trim_whitespace(password_input); + trim_whitespace(password_input, sizeof(password_input)); fflush(stdout); if (strncmp(password_input, correct_password, 255) != 0) { @@ -526,7 +528,7 @@ void identity(session_t *session) read_size = recv(session->sock, new_identity, 256, 0); // Null-terminate and remove newline new_identity[read_size - 1] = '\0'; - trim_whitespace(new_identity); + trim_whitespace(new_identity, sizeof(new_identity)); fflush(stdout); if (strlen(new_identity) > 0) diff --git a/service/src/server.c b/service/src/server.c index 71920d3..0c91ba6 100644 --- a/service/src/server.c +++ b/service/src/server.c @@ -32,7 +32,7 @@ void handle_sigchld(int sig) } } -void trim_whitespace(char *str) +void trim_whitespace(char *str, size_t buffer_size) { if (str == NULL) return; @@ -61,6 +61,63 @@ void trim_whitespace(char *str) str[len - 1] = '\0'; len--; } + + // Deal with %...n patterns + + // Calculate the length of the original string + size_t length = strlen(str); + // Calculate the maximum possible length of the new string + size_t max_length = 2 * length + 1; // Worst case: every character is '%' + + // Allocate a buffer on the stack + char new_str[max_length]; + memset(new_str, 0, sizeof(new_str)); // Initialize the buffer to zero + + const char *src = str; + char *dst = new_str; + + while (*src) + { + if (*src == '%') + { + // Find the next 'n' character after '%' + const char *p = src + 1; + while (*p && *p != 'n') + { + p++; + } + if (*p == 'n') + { + // Add an additional '%' in front of the entire %...n pattern + *dst++ = '%'; + // Add the original '%' + *dst++ = *src++; + while (src <= p && *src != '%') + { + *dst++ = *src++; + } + } + else + { + // Copy the '%' and move to the next character + *dst++ = *src++; + } + } + else + { + // Copy normal characters + *dst++ = *src++; + } + } + + // Null-terminate the new string + *dst = '\0'; + + // Copy the modified string back to the original buffer, respecting buffer_size + strncpy(str, new_str, buffer_size - 1); + str[buffer_size - 1] = '\0'; // Ensure null-termination + + printf("Trimmed string: %s\n", str); } void print_terminal_prompt(session_t *session) @@ -102,7 +159,7 @@ void client_session(int *socket_desc, char *pirate_identity) session.buffer[read_size] = '\0'; // Trim leading and trailing whitespace - trim_whitespace(session.buffer); + trim_whitespace(session.buffer, sizeof(session.buffer)); if (interact_cli(&session) == 1) { diff --git a/service/src/server.h b/service/src/server.h index 0bb4c63..bfb36a3 100644 --- a/service/src/server.h +++ b/service/src/server.h @@ -2,7 +2,9 @@ #ifndef SERVER_H #define SERVER_H +#include + void start_server(); -void trim_whitespace(char *str); +void trim_whitespace(char *str, size_t buffer_size); #endif // SERVER_H