[英]Heap Overflow Attack
我正在学习堆溢出攻击,我的教科书提供了以下易受攻击的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");
}
但是,教科书没有解释如何修复此漏洞。 如果有人能够解释漏洞以及修复它的方法那将是很好的。 (部分问题是我来自Java,而不是C)
代码使用了gets
,它因其潜在的安全问题而臭名昭着:没有办法指定传递给它的缓冲区的长度,它只是继续从stdin
读取,直到它遇到\\n
或EOF
。 因此它可能会溢出你的缓冲区并写入其外部的内存,然后会发生坏事 - 它可能会崩溃,它可能继续运行,它可能会开始播放色情内容。
要解决此问题,您应该使用fgets
。
问题是gets()
将继续读入缓冲区,直到它读取换行符或达到EOF。 它不知道缓冲区的大小,因此它不知道它应该在达到其限制时停止。 如果该行是64字节或更长,这将超出缓冲区,并覆盖process
。 如果输入输入的用户知道这一点,他可以在64位键入正确的字符,用指向其他某个函数的指针替换函数指针,而这个函数指的是他想要进行程序调用。
修复是使用除gets()
之外的函数,因此您可以指定将要读取的输入量的限制。 代替
gets(next->inp);
您可以使用:
fgets(next->inp, sizeof(next->inp), stdin);
fgets()
的第二个参数告诉它最多写入64个字节到next->inp
。 因此它将从stdin
读取最多63个字节(它需要允许空字符串终止符的一个字节)。
您可以通过设置process
的地址来填充超过64个字节的下一个。 从而使人们可以插入任何希望的地址。 地址可以是指向任何函数的指针。
要修复简单,请确保只将63个字节(一个用于null)读入数组inp
- 使用fgets
函数gets不限制来自stdin
的文本量。 如果超过63个字符来自stdin
,则会出现溢出。 gets丢弃LF char,这将是一个[Enter]键,但它在末尾添加一个空字符,因此63个字符限制。
如果inp
的值由64个非空字符填充,因为它可以直接访问, showlen
函数将触发访问冲突,因为strlen
将搜索超出inp
的null-char以确定其大小。
使用fgets
可以很好地解决第一个问题,但它也会添加一个LF char和null,因此可读文本的新限制将是62。
对于第二个,只需要处理在inp
上写的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.