我正在学习堆溢出攻击,我的教科书提供了以下易受攻击的C代码:
/* record type to allocate on heap */
typedef struct chunk {
char inp[64]; /* vulnerable input buffer */
void (*process)(char *); /* pointer to function to process inp */
} chunk_t;
void showlen(char *buf)
{
int len;
len = strlen(buf);
printf("buffer5 read %d chars\n", len);
}
int main(int argc, char *argv[])
{
chunk_t *next;
setbuf(stdin, NULL);
next = malloc(sizeof(chunk_t));
next->process = showlen;
printf("Enter value: ");
gets(next->inp);
next->process(next->inp);
printf("buffer5 done\n");
}
Run Code Online (Sandbox Code Playgroud)
但是,教科书没有解释如何修复此漏洞.如果有人能够解释漏洞以及修复它的方法那将是很好的.(部分问题是我来自Java,而不是C)
问题是gets()将继续读入缓冲区,直到它读取换行符或达到EOF.它不知道缓冲区的大小,因此它不知道它应该在达到其限制时停止.如果该行是64字节或更长,这将超出缓冲区,并覆盖process.如果输入输入的用户知道这一点,他可以在64位键入正确的字符,用指向其他某个函数的指针替换函数指针,而这个函数是他想要进行程序调用的.
修复是使用除以外的函数gets(),因此您可以指定将要读取的输入量的限制.代替
gets(next->inp);
Run Code Online (Sandbox Code Playgroud)
您可以使用:
fgets(next->inp, sizeof(next->inp), stdin);
Run Code Online (Sandbox Code Playgroud)
第二个参数fgets()告诉它最多写入64个字节next->inp.因此它最多将读取63个字节stdin(它需要允许空字符串终止符的一个字节).