canary是一种保护机制它在输入缓冲区的最后放置几个字符低地址为0x00的字符用来隔断输入字符串在用户输入字符串之后来检查程序是否发生栈溢出。若发生了栈溢出那么缓冲区最后的几个字符串必定被用户输入覆盖canary值被改变后stack_check_fail函数会让程序直接停止运行。知己知彼百战不殆。想要绕过canary我们先来看看它是什么样的。我们拿一个开了canary的程序举例来看看canary保护机制的代码构成。程序起始我们拿一道题BugKu - canary来示范。作图来解释一下这段汇编rsp先减少二百五开辟了输入空间由于我们输入时是从低地址往高地址输入我们看到在输入缓冲区的最上面八个字节是rax。汇编代码给rax赋值为fs28h这个rax里就是我们的canary。程序结束程序结束时比较fs28h和[rbp-8]的值。jz到程序退出函数locret_4008FE。了解了原理我们现在就来实操一下如何绕过这个检查。拿到题目程序放进ida上面展示的汇编代码其实就是这一道题canary保护的汇编代码。我们可以看到在这一道题中程序的缓冲区空间大小为buf的48buf_1的520个字节568个字节。加上八个字节后等于576刚好就是0x240和rsp-240对应上了。我们给程序发送568个A这样完全覆盖输入栈帧之后会把canary前面用来隔开用户输入字符串的0x00替换掉这样程序接下来输出字符串时就会把我们的输入连带着canary一起输出出来。这样即可得到canary。然后我们还是像往常一样正常构造payload用到pop_rdi binsh进system。在payload中canary后面加上p64(0)用于覆盖rbp。拿到flag完整答案