what happens if a program receives as an argv[1] argument a string with a null terminator in the middle? for example:

./program test'\0'example

what is the value of argv[1]? is it test? is it test\0example? I have these lines of code

max = sizeof(filename);
len = strlen(argv[1]);
if (len > max) goto error;
strcpy(filename, argv[1]);

I need to build an exploit for this program and what I wanted to do, is making argv[1] worth test'\0'example so strlen(argv[1])=strlen("test")=4 and strcpy(filename, argv[1])=strcpy(filename, "test") so I can use the rest of the string (the example part) to put my exploit. is it possible? thank you very much?

有帮助吗?

解决方案

argv[1] is a pointer object of type char*. Its value is an address, not a string. Specifically, its value is the address of a char object whose value is 't'.

The C standard (in section 7.1.1) has the following definitions:

A string is a contiguous sequence of characters terminated by and including the first null character.
[...]
A pointer to a string is a pointer to its initial (lowest addressed) character. The length of a string is the number of bytes preceding the null character and the value of a string is the sequence of the values of the contained characters, in order.

Since argv[1] points to the first of a contiguous sequence of characters, one of which is a null character, it's a pointer to a string. The value of that string is "test" (which includes the terminating '\0'), and the length of the string is 4.

It's common to say, as a kind of verbal shorthand, that the value of argv[1] is "test", but that's imprecise -- especially in a case like this where the distinction between the value of a string and the value of the array containing that string is significant.

argv[1] also points to the first character of an array of characters. The first 5 bytes of that array contain the string "test". The entire array contains the character values:

{ 't', 'e', 's', 't',
  '\0',
  'e', 'x', 'a', 'm', 'p', 'l', 'e',
  '\0' }

If you pass the value of argv[1] to a string function, that function will only see "test", and will not access anything past the terminating '\0'. The rest of the contents of the array are still perfectly valid, and can be accessed using functions (like memcpy) that don't just operate on strings.

Whether it's possible to invoke your main program in such a way that argv[1] will point to the first element of an array with those particular contents is another matter, one that depends on your operating system.

其他提示

The value of argv[1] will be "test", assuming you actually manage to get a real NULL character on the terminal and not just the literal characters \ and 0.

As RedAlert's comment mentioned, strlen and strcpy both stop on a null character, so getting a null character will not help for most exploits.

You most likely need to find a way to do the exploit without using the character \0.

Your idea works when main() is called from within main()

#include <stdio.h>

int main(int argc, char **argv) {
  if (argc == 1) {
    char *data[] = {"", "5one\0two", "7three\0four", "6five\0six"};
    main(4, data); // call main again, with exploitable data
  } else {
    if (!argv[0][0]) { // test for empty argv[0]
      for (int i = 1; i < 4; i++) {
        printf("%s ==> %s\n", argv[i] + 1, argv[i] + argv[i][0] - '0');
      }
    }
  }
  return 0;
}

I'm not sure if it will work when main() is called from the C library initialization code ... or even if you can make your shell accept a NUL character as part of an argument.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top