c - 堆溢出攻击

标签 c buffer-overflow

我正在学习堆溢出攻击,我的教科书提供了以下易受攻击的 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() 将继续读入缓冲区,直到它读取一个换行符或到达 EOF。它不知道缓冲区的大小,所以它不知道在达到限制时应该停止。如果该行是 64 字节或更长,这将超出缓冲区,并覆盖 process。如果输入的用户知道这一点,他可以在位置 64 处键入正确的字符,以将函数指针替换为指向他想让程序调用的其他函数的指针。

修复方法是使用 gets() 以外的函数,因此您可以指定对将读取的输入量的限制。而不是

gets(next->inp);

你可以使用:

fgets(next->inp, sizeof(next->inp), stdin);

fgets() 的第二个参数告诉它最多将 64 个字节写入 next->inp。因此它将从 stdin 中读取最多 63 个字节(它需要允许一个字节用于空字符串终止符)。

关于c - 堆溢出攻击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30358034/

相关文章:

c++ - 来自 Lua 脚本的 nanosleep() 调用暂停了 QT GUI 线程

c - C 中的简单堆栈损坏

c - 内存地址

堆栈帧上缺少注入(inject)字符串的某些部分

c++ - 在 C++ 程序中调用 Python 函数

c++ - 结构体(数组)中出现次数最多的数字

c - Windows 计时器是否与 Sleep() 一样准确?

c - Linux 上的系统调用参数类型是什么?

c - 为什么 "stack smashing detected"不是刷完马上出现?

linux - 缓冲区在 64 位上溢出