0x00 前言
网上查阅相关文章后自己做的笔记
0x01 格式化字符串绕过
程序:
1 | #include <stdio.h> |
程序正常的走完了流程,到函数执行完的时候,程序会再次从把canary的值取出来,和之前放在栈上的canary进行比较,如果因为栈溢出什么的原因覆盖到了canary而导致canary发生了变化则直接终止程序
可以看到canary
保存在ebp-0xc
处
那么我们要怎样泄露canary的值呢?既然canary的值保存在栈中,那么就可以使用格式化字符串读出来,我们只需要知道偏移即可,那么gdb在调用printf函数处下断点,然后跑起来:
1 | mask@mask-virtual-machine:~/canary$ gdb ./bin |
然后随便输一个值,123456
1 | [----------------------------------registers-----------------------------------] |
栈的情况:
1 | [------------------------------------stack-------------------------------------] |
因为canary保存在ebp-0xc
= 0xbffff05c
,格式化参数format保存在0xbffff040
,根据栈布局可以知道参数偏移为7
那么接下来只要通过格式化字符串读取canary的值,然后在栈溢出的padding块把canary所在位置的值用正确的canary替换,从而绕过canary的检测。
还有一点,fun函数的地址,直接IDA查看便是:
1 | .text:0804863B ; =============== S U B R O U T I N E ======================================= |
下面编写exp:
1 | from pwn import * |
运行:
1 | mask@mask-virtual-machine:~/canary$ python exp.py |
0x02 针对fork的进程绕过
原理引用一位大佬的博客的原文:
对fork而言,作用相当于自我复制,每一次复制出来的程序,内存布局都是一样的,当然canary值也一样。那我们就可以逐位爆破,如果程序GG了就说明这一位不对,如果程序正常就可以接着跑下一位,直到跑出正确的canary。
另外有一点就是canary的最低位是0x00,这么做为了防止canary的值泄漏。比如在canary上面是一个字符串,正常来说字符串后面有0截断,如果我们恶意写满字符串空间,而程序后面又把字符串打印出来了,那个由于没有0截断canary的值也被顺带打印出来了。设计canary的人正是考虑到了这一点,就让canary的最低位恒为零,这样就不存在上面截不截断的问题了。
程序:
1 | #include <stdio.h> |
exp:
1 | from pwn import * |
跑呀跑呀跑呀~