如果一个程序作为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(&#34 ; test")= 4和strcpy(filename,argv [1])= strcpy(filename," test")所以我可以使用字符串的其余部分(示例部分)来放置我的漏洞利用。可能吗?非常感谢你?
答案 0 :(得分:1)
argv[1]
是char*
类型的指针。它的值是一个地址,而不是一个字符串。具体而言,其值是char
对象的地址,其值为't'
。
C标准(第7.1.1节)具有以下定义:
string 是由第一个null终止并包含第一个null的连续字符序列 字符。
[...]
指向字符串的指针是指向其初始(最低寻址)字符的指针。 字符串的长度是空字符前面的字节数 字符串的值是按顺序包含的字符值的序列。
由于argv[1]
指向连续字符序列中的第一个,其中一个是空字符,因此它是指向字符串的指针。该字符串的值为" test" (包括终止'\0'
),字符串的长度为4。
作为一种口头速记,argv[1]
的值"test"
是argv[1]
,但这不精确 - * es
"test"
也指向数组字符的第一个字符。该数组的前5个字节包含字符串{ 't', 'e', 's', 't',
'\0',
'e', 'x', 'a', 'm', 'p', 'l', 'e',
'\0' }
。整个数组包含字符值:
argv[1]
如果将"test"
的值传递给字符串函数,则该函数只会看到'\0'
,并且不会访问终止memcpy
之后的任何内容。数组的其余内容仍然完全有效,并且可以使用不仅仅对字符串进行操作的函数(如argv[1]
)来访问。
作为一种口头速记,"test"
的价值是argv[1]
,但这种不精确 - 尤其在这种情况下,字符串的值与包含该字符串的数组的值之间的区别很大。
是否可以以{{1}}指向具有这些特定内容的数组的第一个元素的方式调用主程序是另一个问题,一个取决于您的操作系统。
答案 1 :(得分:0)
argv[1]
的值将为"test"
,假设您确实设法在终端上获得真正的NULL字符,而不仅仅是文字字符\
和0
。
正如RedAlert的评论所提到的,strlen
和strcpy
都停止在空字符上,因此获取空字符对大多数漏洞利用都无济于事。
您很可能需要在不使用字符\0
的情况下找到一种方法来进行利用。
答案 2 :(得分: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;
}
我不确定从C库初始化代码调用main()
时它是否可行...或者即使你可以让你的shell接受NUL字符作为参数的一部分。< / p>