elBradford elBradford - 1 month ago 16
C Question

C argument with semicolon appears truncated

I am working on an assignment that's related somewhat to the OWASP command injection Example 1. In short, I accept an argument (a filename) that is then appended to the string "cat ", so my program cats the supplied file. If I pass the user input directly to the

system()
function, the user can sneak in another command separated by a semicolon
;
. For example:

./commandinject Story.txt;whoami


will
cat Story.txt
and print the current user.

I am just asked to detect a semicolon, and if found, error and request another file - looping until valid input is given.

This is pretty straightforward with
strchr()
, at least, it should be. My issue is that when processing the string
argv[1]
, anything from the semicolon on is invisible.
I have some debug code that prints out all argv array values, and I stepped through
gdb
and the injected command is invisible, as far as I can tell.

For example, when given the input above, the code

printf ("This is the command->%s\n", argv[1]);


will print out

This is the command->Story.txt


What is really weird is that

system(argv[1]);


still executes the injected code. I am sure it is a simple c-ism that I am missing, but I would appreciate some help with this.

I should note, if I use quotes around the argument, my code works properly and catches the semicolon.

#include <stdio.h>
#include <unistd.h>

#define COMMAND_SIZE 4096

int main(int argc, char **argv) {
char cat[] = "cat ";
char *command;
char *commandRepeat;
size_t commandLength;

commandLength = strlen(cat) + strlen(argv[1]) + 1;
command = (char *) malloc(commandLength);
strncpy(command, cat, commandLength);
strncat(command, argv[1], (commandLength - strlen(cat)) );

// Search command string for ';'
while(strchr(command, ';') != NULL){
// ERROR, ask for filename again.
// Use temporary buffer for user input
commandRepeat = (char *) malloc(COMMAND_SIZE);
printf("You used an invalid character ';'\nPlease enter the filename again: ");
fgets(commandRepeat, COMMAND_SIZE, stdin);
// Trim newline that fgets includes
commandRepeat[strcspn(commandRepeat, "\n")] = '\0';

// Prepare command string
commandLength = strlen(cat) + strlen(commandRepeat) + 1;
free(command);
command = (char *) malloc(commandLength);
strncpy(command, cat, commandLength);
strncat(command, commandRepeat, (commandLength - strlen(cat)) );
free(commandRepeat);
}

printf ("This is the command->%s\n", command);
system(command);

return (0);
}

Answer

The shell is interpretting the ; and running the next command. You'll need to put it in quotes if you want it sent to your program.

If your program ends normally, you should see the bit after the ; executed.

./commandinject "Story.txt;whoami"
Comments