C语言函数调用过程 | 缓冲区溢出攻击

C语言的函数调用过程是怎么样的呢?如何传递参数?运行后如何从函数跳转回来?

利用栈的函数调用方式

在函数调用时,按如下的顺序压入栈:
• 函数的参数(按声明的逆序即从右到左的顺序,当然有的编译器采用的是正序)
• 函数的返回值(开辟一个空间)
• 函数的返回地址(使得调用完成后,eip能正确指向下一条指令)
• ebp的值(记录函数调用前的栈底,用于调用结束后恢复原来地址)

下面举例说明main函数调用fun的过程。

调用前

在调用前,首先栈中存放了ebp,用于本程序执行完成后,ebp能回到原来的位置。
然后将局部变量4和5入栈。

before-function-calls

 

调用时

  1. 函数参数入栈,这里入栈的顺序和参数的声明顺序相反
  2. 接着开辟个空间,用于存放返回值
  3. func函数执行后的返回地址压入栈
  4. 跳转到函数执行
  5. ebp地址入栈
  6. ebp = esp (mov ebp,esp)

during-function-calls

调用结束,要返回时

函数返回栈如下,将返回地址写入返回值的栈中。

 

 

end-of-function-calls

Attack 实验

我们可以通过栈溢出覆盖返回地址,来达到攻击。比如如下的代码,我们希望输入非goodpass,但是能通过验证。这里是(Access granted)

 

查看返回地址和ebp

由汇编看到puts(“Access granted”); 地址为 0x004010DD

attack-see-the-return-address
同时,查看其ebp地址为0x0012ff80

输入编辑

由于Password数组长度为12,因此要进行溢出攻击,首先要把它填满,输入任意字符到12个为止。接着,输入ebp的地址,然后在输入返回地址。

edit-input-to-attack

攻击测试

打开CMD,使用重定向输入,并运行该程序,即出现了Access granted.

attack-result
PS:上述的程序中, 要是没有设置正确的EBP值(随便设置一个)那么也可以出现access granted,但是程序会报错退出。

 

此外,还有return-into-libc的攻击方式。

 

防御措施-Canary

Canary(金丝雀)技术是一种用来检测和阻止栈溢出攻击的机制,在运行时为程序提供安全保护。
它一般由编译器实施,在程序运行时在被保护的栈中插入一个难以伪造的值canary (一般为一个32位的随机值,也称为cookie或guard),canary值将在函数返回时被进行检查,如果其被修改则认为发生了溢出。

canary-protect

 

本博客若无特殊说明则由 hrwhisper 原创发布
转载请点名出处:细语呢喃 > C语言函数调用过程 | 缓冲区溢出攻击
本文地址:https://www.hrwhisper.me/understanding-stack-frame-of-function-call-and-buffer-overflow-attack/

打赏一杯咖啡钱呗

信息安全, 计算机基础 . permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *