C 为什么以下代码容易受到堆溢出攻击
我是网络安全新手,我试图理解为什么以下代码容易受到堆溢出攻击C 为什么以下代码容易受到堆溢出攻击,c,malloc,heap,buffer-overflow,C,Malloc,Heap,Buffer Overflow,我是网络安全新手,我试图理解为什么以下代码容易受到堆溢出攻击 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));
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();
}
这是因为读取(stdin,d->name,256)
,因为它在结构数据中读取的字符名
超过了分配的缓冲区大小128
任何帮助都会很好A与A类似,只是攻击者不会覆盖堆栈中的值,而是践踏堆中的数据
请注意,在代码中有两个动态分配的值:
d = malloc(sizeof(struct data));
f = malloc(sizeof(struct fp));
因此d
现在保存堆中128字节内存块的地址,而f
保存8字节(假设为64位机器)内存块的地址。从理论上讲,这两个地址可能相距甚远,但由于它们都相对较小,操作系统很可能分配了一大块连续内存,并为您提供了相邻的指针
因此,一旦运行f->fp=printName代码>,您的堆看起来像这样:
注意:每行8字节宽
然后,代码到达该行
f->fp();
这是使用存储在f
中的地址进行的函数调用。计算机进入内存位置f
并检索存储在那里的值,该值现在是攻击者恶意代码的地址。既然我们把它称为函数,那么机器现在跳转到那个地址,并开始执行存储在那里的代码,现在你手上有一个可爱的攻击向量。< / P>是的,它允许分配更多的空间。但我认为这是缓冲区溢出而不是堆溢出,尽管我被告知这与指针本身有关。但是,伙计,我非常困惑,而且我对C和一般计算都是新手:(:(read(stdin,d->name,256);
看起来是错误的。确定要在这里使用stdin
和read(int-fd,void*buf,size\u-t-count)
?(启用所有编译器警告)谢谢您的详细解释,先生!很快,什么是f->fp()
意思是什么?什么是fp()
甚至是某种函数调用?箭头操作符(->
)是“解除引用和访问”。f
是指向结构fp
的指针,因此f->fp
相当于(*f).fp
,即获取位于内存位置f
的struct fp
,并访问其名为fp
的成员。fp
成员是指向函数的指针,因此将()
在调用它指向的函数之后。更一般地说,在C语言中,函数名被视为指向这些函数的指针。因此someFunc()
只是将someFunc
作为指向函数的指针加载,然后执行它,就像f->fp()
正在加载f->fp
并执行它。就像您可以存储指向数据的指针一样,您可以存储指向函数的指针,这实际上与按名称调用函数是一样的。我明白了,它现在开始有意义了。所以本质上,在读取中出现了缓冲区溢出(stdin,d->name,256)
因此,一些内存内容泄漏到相邻的结构中。然后,当指针f
解除对结构fp
的引用时,他们可以将其指向堆中的另一个函数??我感谢您迄今为止的帮助-如果您能提供一个图表,那将是非常好的,先生。上帝保佑,先生!!准确地说!我本来想在答案中加入一个图表,但最初决定不这样做。如果对你有帮助的话,我现在会回去编辑答案,包括一些。
| 0xbadc0de |
+-------------+
f -> | 0xbadc0de |
+-------------+
| ... |
| 0xbadc0de |
| 0xbadc0de |
d -> | 0xbadc0de |
+-------------+
| |
f->fp();