0

如果程序接收到一个中间带有空终止符的字符串作为 argv[1] 参数会发生什么?例如:

./program test'\0'example

argv[1] 的值是多少?是测试吗?是测试\ 0示例吗?我有这些代码行

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

我需要为这个程序构建一个漏洞利用,我想做的是让 argv[1] 值得测试'\0'示例所以 strlen(argv[1])=strlen("test")=4 和 strcpy(filename , argv[1])=strcpy(filename, "test") 所以我可以使用字符串的其余部分(示例部分)来放置我的漏洞利用。可能吗?非常感谢您?

4

3 回答 3

1

argv[1]是一个类型的指针char*。它的值是一个地址,而不是一个字符串。具体来说,它的值是一个值为 的char对象的地址't'

C 标准(在第 7.1.1 节中)具有以下定义:

字符串是由第一个空字符终止并包括第一个空字符的连续字符序列。
[...]指向字符串
的指针是指向其初始(最低地址)字符的指针。字符串的长度是空字符之前的字节数,字符串的值是包含的字符值的顺序,按顺序排列。

由于argv[1]指向连续字符序列的第一个字符,其中一个是空字符,因此它是指向字符串的指针。该字符串的值为“test”(包括终止符'\0'),字符串的长度为 4。

作为一种口头速记,通常说 的值为argv[1]"test"但这并不精确—— *es

argv[1]也指向字符数组的第一个字符。该数组的前 5 个字节包含字符串"test"。整个数组包含字符值:

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

如果将 的值传递argv[1]给字符串函数,该函数将只能看到"test",并且不会访问 terminating 之后的任何内容'\0'。数组的其余内容仍然完全有效,并且可以使用memcpy不仅仅对字符串进行操作的函数(如 )进行访问。

作为一种口头简写,通常说 is 的值argv[1]"test"但这是不精确的——尤其是在这种情况下,字符串的值和包含该字符串的数组的值之间的区别很重要。

是否可以以指向具有这些特定内容的数组的第一个元素的方式调用主程序argv[1]是另一回事,这取决于您的操作系统。

于 2014-05-07T18:20:00.060 回答
0

main()当从内部调用时,您的想法有效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;
}

我不确定当main()从 C 库初始化代码调用时它是否会起作用......或者即使你可以让你的 shell 接受 NUL 字符作为参数的一部分。

于 2014-05-07T18:15:55.103 回答
0

的值argv[1]将是"test",假设您实际上设法在终端上获得一个真正的 NULL 字符,而不仅仅是文字字符\0.

正如 RedAlert 的评论所提到的,strlen并且strcpy两者都停在空字符上,因此获取空字符对大多数漏洞利用无济于事。

您很可能需要找到一种不使用字符的方法来执行漏洞利用\0

于 2014-05-07T17:57:20.237 回答