[英]null terminator in the middle of a string
如果程序接收到一个以argv [1]作为参数的字符串,中间有一个空终止符,会发生什么情况? 例如:
./program test'\0'example
argv [1]的值是什么? 测试吗? 是test \\ 0example吗? 我有这些代码行
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”),因此我可以使用字符串的其余部分(示例部分)来放置我的漏洞。 可能吗? 非常感谢你?
argv[1]
是char*
类型的指针。 它的值是一个地址,而不是字符串。 具体来说,其值为值为't'
的char
对象的地址。
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"
,并且不会访问终止于'\\0'
任何内容。 数组的其余内容仍然完全有效,并且可以使用不仅仅对字符串进行操作的函数(例如memcpy
)进行访问。
通常来说, argv[1]
的值是"test"
,这是一种语言上的速记,但这并不精确- 尤其是在这种情况下,字符串的值与字符串的值之间的区别包含该字符串的数组很重要。
是否可能以argv[1]
指向具有这些特定内容的数组的第一个元素的方式调用主程序是另一回事,这取决于您的操作系统。
假设您实际上设法在终端上获得一个真实的NULL字符,而不仅仅是文字字符\\
和0
,则argv[1]
的值将为"test"
。
就像RedAlert的评论中提到的那样, strlen
和strcpy
都停止在一个空字符上,因此获取空字符对大多数漏洞利用没有帮助。
您很可能需要找到一种无需使用\\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字符作为参数的一部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.