为什么以下代码容易受到堆溢出攻击

问题描述 投票:1回答:1

我是网络安全的新手,我试图理解为什么以下代码容易受到堆溢出攻击......

struct data {
 char name[128];
};
struct fp {
 int (*fp)();
};
void printName() {
 printf("Printing function...\n");
}
int main(int argc, char **argv) {
 struct data *d;
 struct fp *f;
 d = malloc(sizeof(struct data));
 f = malloc(sizeof(struct fp));
 f->fp = printName;
 read(stdin,d->name,256);

 f->fp();
}

是因为read(stdin, d->name, 256)因为128中的char name读取的struct data缓冲区大小超过heap overflow attack

任何帮助都会很棒

c malloc heap buffer-overflow
1个回答
1
投票

buffer overflow attack类似于d = malloc(sizeof(struct data)); f = malloc(sizeof(struct fp)); ,除了不覆盖堆栈中的值,攻击者践踏堆中的数据。

请注意,在代码中有两个动态分配的值:

d

所以f现在保存堆中128字节内存块的地址,而f->fp = printName;保存8字节(假设64位机器)内存块的地址。从理论上讲,这两个地址可能无处可靠,但由于它们都相对较小,因此操作系统可能会分配一大块连续内存,并为您提供彼此相邻的指针。

所以一旦你运行 | | +------------------------+ f -> | <Address of printName> | +------------------------+ | ▲ | | 11 more rows | | not shown | | | d -> | <Uninitialized data> | +------------------------+ | | ,你的堆看起来像这样:

注意:每行宽8个字节

d

您对漏洞来源的初步评估是正确的。 d指向128字节的内存,但是让用户将256字节写入该区域。 C没有边界检查的机制,所以编译器非常乐意让你写出f内存的边缘。如果d就在d旁边,那么你将落在f的边缘并进入f。现在,攻击者只需写入d即可修改d的内容。

为了利用此漏洞,攻击者通过重复输入所有256字节的输入来提供他们写入0xbadc0de的一些代码的地址。如果攻击者在地址0xbadc0de上存储了一些恶意代码,则会将 | 0xbadc0de | +-------------+ f -> | 0xbadc0de | +-------------+ | ... | | 0xbadc0de | | 0xbadc0de | d -> | 0xbadc0de | +-------------+ | | 提供给stdin 32次(256字节),以便堆被覆盖。

f->fp();

然后,您的代码到达该行

f

这是使用存储在f中的地址的函数调用。机器进入内存位置arbitrary code execution并检索存储在那里的值,该值现在是攻击者恶意代码的地址。由于我们将其称为函数,机器现在跳转到该地址并开始执行存储在那里的代码,现在你手上有一个可爱的qazxswpoi攻击向量。

© www.soinside.com 2019 - 2024. All rights reserved.