快速链接:
.
👉👉👉 个人博客笔记导读目录(全部) 👈👈👈
Linux 系统中,为了防御栈溢出漏洞的利用,通常会部署 Canary 漏洞缓解措施.
下面简单描述下 Canary 的原理。对于栈溢出漏洞的利用,最简单的方法就是通过溢出数据修改栈中函数返回地址为目标内存地址,当函数返回时将会跳转到目标内存处执行指令,从而实现控制流劫持。为了防御这种利用方法,分配栈空间时在 EBP-4 的位置存放一个 Canary 值,函数返回之前会校验该值是否被修改,若检测到被修改则调用 __stack_chk_fail 函数抛出异常并结束进程。可见,要覆盖函数返回地址必须修改 Canary,从而可防御该攻击方法。gcc 编译器默认开启该缓解机制,编译时可用 -fno-stack-protector 选项关闭该机制。
libc 中 __stack_chk_fail 的源码如下,该函数调用 __fortify_fail 输出异常信息,其中包含 libc_argv[0] 指向的程序名:
void __attribute__ ((noreturn)) __stack_chk_fail (void)
{
__fortify_fail ("stack smashing detected");
}
void __attribute__ ((noreturn)) internal_function __fortify_fail (const char *msg)
{
/* The loop is added only to keep gcc happy. */
while (1)
__libc_message (2, "*** %s ***: %s terminatedn",
msg, __libc_argv[0] ?: "<unknown>");
}