为了更好地理解该漏洞,我试图使用下面的代码触发缓冲区溢出。
我有某些字段,有些字段指定了一个宽度以防止溢出,但我在一种情况下(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
根据我对缓冲区溢出的理解,名字中的额外字符应该会进入另一个字段,但在这种情况下,它从另一个变量中获取用户输入并将其添加到名字中。那么,这种缓冲区溢出行为还是其他原因造成的呢?
发布于 2013-09-18 19:59:54
是的,这是堆栈上的溢出缓冲区。
firstName
输入确实溢出到surName
中。但是在输入时,您更改了surName
,并且它用Example
覆盖了字符。
因为您溢出了firstName
,所以字符串上没有空终止符,所以看起来firstName
比实际长。然后,它的“结束”被覆盖(因为这些字节属于另一个变量)。
这实际上是未定义的行为。您不知道编译器将把缓冲区放在堆栈中的位置。
为了防止缓冲区溢出,您应该使用fgets
来读取字符串,而不是scanf
。
fgets( firstName, 21, stdin );
发布于 2013-09-18 20:00:35
是的,这是缓冲区溢出行为。
第4行,名为scanf
,确实遇到了缓冲区溢出。它保存了从firstName
开始的长名称,并继续到surName
占用的空间中。当然,它的结尾是零终止。
第6行之后,用新的姓“”覆盖,从surName
开始。它还以零终结者结束。
然后,firstName
的printf从firstName
的开头开始,在firstName
结束后继续到surName
,直到找到一个零终止符。
当缓冲区溢出被用作漏洞时,通常是firstName在surName之后被扫描的位置,这样它所写入的溢出本身就不会被覆盖。
发布于 2013-09-18 20:02:52
是的,您将第一个数组溢出到第二个数组中。
在第一个任务中,firstName
包含UmbertoTestingOverflo
,surName
的第一个字符设置为w
。在第二个任务中,surName
被设置为Example
。
当您打印firstName
时,它一直打印字母,直到它遇到\0
字符,该字符位于surName
的末尾。与job
相关的内存从未改变过。
https://stackoverflow.com/questions/18885905
复制