KABOOM
大体概述及思路
执行的是testn函数并且需要执行5遍(在应用-n选项的情况下,程序会要求提交输入字符串 5 次,5次输入会面对5个不同的栈空间)
Getbufn(输入超过512导致缓冲区溢出)
第二个if判断要求getbufn的返回值val为cookie,所以要改变getbufn的返回地址。
最关键的一点:因为要执行5次testn函数,每次函数执行完之后原有的栈帧都会被清空,否则就会一直占用着空间,那么就会导致第二次执行testn函数的时候,栈帧扩栈不会在原有的位置上进行扩栈,栈帧在栈中的位置并不能够确定。So,如何确定每次栈帧的位置呢?
可以用gdb中的info registers(即 i r)命令查看esp 和 ebp 的地址,然后再构造攻击字符串。
分析过程
Testn函数
【PS:因为前面有一道题的.......:
0x55683a50+0x20这个 0x20 怎么来的?
首先,我感觉当时我踩的坑是没有搞清楚esp的作用,其实很简单,esp是栈指针寄存器永远指向的是栈的最底端并且栈帧的最顶端一定是函数的返回地址,所以根据汇编
是等到ebx入栈完成后,esp才进行的扩栈即esp-0x14。So,为什么最顶端是返回地址?原因就是call命令在主程序中每次调用函数时,先依次把各参数以相反的顺序入栈;然后call func_name, 这里call要做两件事: 一是把函数的返回地址入栈,二是让指令执行指针%eip指向函数开始处。】
so此函数栈帧:最顶上是返回地址,然后各种入栈
进入正题,看代码:
因为要修改getbufn的返回值,目光移到524行call的位置,getbufn执行完之后走的是525行0x8048e4a的位置,eax即返回值(其实直接看getbufn的汇编代码就能够确定)。
然后确定每次栈的位置,用gdb跟踪getbufn
getbufn函数
这样,刚开始的两大顾虑就解决了,下面就可以构建攻击代码了,根据题目要求:
1. 改变返回的cookie值
2. 恢复testn函数的现场,即比较成功之后testn函数能够继续往下执行。
想要恢复现场,最关键的一点就是要知道ebp的值,如何获取ebp的值?最简单的暴力方法就是直接 i r ebp,但这样是不行的,上一题中的
原来上下两个ebp的值应该是一致的,由下面的可以回溯到上面的,但是现在下面的变了,所以不能够直接看。
回到这个题,继续构建
(一定要有retret指令用栈中的数据,修改IP的值,从而实现转移。)加40是因为
至此,攻击代码构建好了,那么放在哪里又是个问题
因为ebp每次都在变
既然都已经找出来了ebp的位置,不妨来看一下
这里面会产生一个最大值跟最小值差值224确定了ebp跳动的范围,而buf的长度为0x208+4(返回地址)=524.所以,这5次一定有公共的部分,那就可以放攻击代码了。
因为构建的攻击代码长度为0x16远小于公共空间的长度,所以,也一定有个范围
{0x556830F8,max}
max怎么得到呢?
确定了最小值,说明每次运行的时候走的一定有那段公共区域,所以,用ebp的最小值确定最大值,这样,保证了这段公共空间是一定能够执行的。
为什么要用90填充?
nop无作用,英文“no operation”的简写,意思是“do nothing”(机器码90)是一条指令
如果是00就相当于给这段赋了值,可能会影响后续的调用。
特别鸣谢:
-------------------------------------------------------------------------------------------
参考:
作者:何凯-山东工商学院
来源:《CMU LAB3解题详解(Ver 1.0)》