3

我试图通过使用下面的代码来触发缓冲区溢出,以便更好地理解漏洞。

我有某些字段,有些指定了宽度以尝试防止溢出,但我在一种情况下(firstName)将其省略以使溢出成为可能:

char firstName[21], surName[31], job[16];

printf("Enter first name: ");
scanf("%s", firstName);
printf("Enter surname: ");
scanf("%30s", surName);
printf("Enter job name : ");
scanf("%15s", job);

所以现在当我输入以下内容时:

UmbertoTestingOverflow
Example
Janitor

记录的变量显示为:

UmbertoTestingOverfoExample
Example
Janitor

根据我对缓冲区溢出的理解,名字中的额外字符应该已经跑到另一个字段中,但在这种情况下,它已经从另一个变量中获取用户输入并将其添加到名字中。那么这是缓冲区溢出行为还是其他原因导致的?

4

3 回答 3

3

是的,这是堆栈上的缓冲区溢出。

输入firstName确实溢出surName. 但是surName当你输入它时你改变了,它用 . 覆盖了字符Example

因为你 overflowed firstName,字符串上没有空终止符,所以看起来firstName比实际长。然后它的“结束”被覆盖(因为这些字节属于另一个变量)。

这实际上是未定义的行为。您不知道编译器会将缓冲区放入堆栈的哪个位置。

为防止缓冲区溢出,您应该使用fgets读取字符串,而不是scanf

fgets( firstName, 21, stdin );
于 2013-09-19T03:59:54.300 回答
1

是的,这是缓冲区溢出行为。

第 4 行 firstnamescanf确实遇到了缓冲区溢出。它保存了从 开始firstName并继续到 . 占用的空间的长名称surName。当然,它以一个零终结符结束。

然后第 6 行用新的姓氏“Example”覆盖了长名称,从surName. 它还以零终止符结束。

printf of firstNamethen 从 in 的开头开始firstName并继续,经过firstNameinto的结尾surName,直到找到一个零终止符。

当缓冲区溢出被用作漏洞利用时,通常会在 surName 之后扫描 firstName,因此它写入的溢出本身不会被覆盖。

于 2013-09-19T04:00:35.043 回答
1

是的,您将第一个数组溢出到第二个数组中。

在第一个任务中,firstName包含UmbertoTestingOverflo并且第一个字符surName被设置为w. 在第二个任务中,surName设置为Example

当您打印firstName时,它会一直打印字母,直到遇到.\0结尾的字符surName。与相关的记忆job从未改变。

于 2013-09-19T04:02:52.303 回答