canary笔记
canary笔记
布局
more
直接泄漏
因为canary最低字节必是'\x00'
(防止填满把它打印出来),则满足下面条件:
- 缓冲区溢出可以填充到且只填充到canary最低字节
- 程序可以输出填充的内容
- 函数返回前还有再次填充机会
这样就可以读出canary后再把它加到payload上,从而绕过canary。
格式化字符串
格式化字符串能够实现任意地址读写的特性,可以读出canary或修改cannary执行___stack_chk_fail()
,具体用法:格式化字符串笔记。
爆破
若程序有fork()
使子程序循环执行,可以通过子程序栈与主程序一致慢慢爆破。
ssp leak
因为函数返回前会检查canary,若不通过会跳转到___stack_chk_fail()
:
因此可以通过修改___stack_chk_fail()
地址和覆盖canary来劫持程序流程,但这里也有一种可以利用的东西:
看一下源码:
__stack_chk_fail
:
void
__attribute__ ((noreturn))
__stack_chk_fail (void) {
__fortify_fail ("stack smashing detected");
}
fortify_fail
:
void
__attribute__ ((noreturn))
__fortify_fail (msg)
const char *msg; {
/* The loop is added only to keep gcc happy. */
while (1)
__libc_message (2, "*** %s ***: %s terminated\n", msg, __libc_argv[0] ?: "<unknown>")
}
libc_hidden_def (__fortify_fail)
__libc_message
的第二个%s输出的是argv[0]
,argv[0]
是指向第一个启动参数字符串的指针,由此我们可以通过缓冲区溢出覆盖掉argv[0]
打印我们想要的地址上的值。