ctfshow53
(1)checksec

发现并没有开canary保护,其实这道题只是在栈上放了一个作用与canary类似的,程序运行过程中也会比较它的值是否改变
思路:我们可以逐字节的将canary爆破出来
(2)ida代码审计

看看Canary

意思就是先声明了一个指针变量 stream,打开canary.txt文件,如果没有这个文件就退出,如果有使用 fread 函数从打开的文件中读取 4 个字节的数据存储在全局变量global_canary
看看ctfshow

将global_canary赋给s1,然后是一个while循环, 使用read函数读取字符到v2中,直至遇到换行符 \n(ASCII码为10)停止,v5记录存储的个数,每当存储一次v5的值就+1,,然后使用 __isoc99_sscanf 函数将 v2 中的字符串转换为整数,并存储到 nbytes 中,nbytes为size_t 类型无符号型,当我们输入-1时候就会被解释为一个非常大的数((通常是 0xFFFFFFFF,即 size_t 类型的最大值)),所以我们可以输入-1来绕过while循环,并且可以利用第二个read进行栈溢出
最后if循环就是比较canary的值是否改变的,将s1的值与global_canary比较如果不一样输出”Error *** Stack Smashing Detected *** : Canary Value Incorrect!”并且退出,一样的话输出”Where is the flag?”
最后flag

意思就是打开flag的文件,通过puts函数将flag的值输出
(3)思路

先将canary逐个字节爆破出来,然后通过栈溢出返回到flag的地址就可以
1.canary爆破
爆破canary s1中储存的就是canary的值,我们可以先覆盖0x20个数据覆盖到s1,然后一个字节一个字节的去覆盖s1的值,因为只覆盖一个字节,其他的不变,通过看puts函数输出的值判断是否覆盖正确,当第一个字节正确就把他记录下来,然后爆破第二个字节时,再将第一个字节输入进去再爆破第二个字节,依次类推,这里我们可以借助脚本去爆破,粘贴一个大佬写的脚本我来解释一下
1 | from pwn import * |
2.栈溢出
exp
1 | from pwn import * |