四、目标程序 BUFBOMB
bufbomb 是一个可执行的目标程序,是通过编译、链接 bufbomb.c 等源程序得到的。你
可以打开 bufbomb.c 分析一下。
1)bufbomb 在运行时需要你提供命令行参数,这里你要用到的命令行参数只有一个-u,
方法如下:
unix> ./bufbomb -u U201614557
这里,-u U201614557 就是 bufbomb 的命令行参数,U201614557 是你的学号。你输入
的学号在 bufbomb 里通过 getcookie(userid),将如同 makecookie 一样,产生一个由 8 个 16
进制数字组成的 4 字节序列 cookie。Cookie 将作为你程序的唯一标示,而使得你的运行结果
与其他同学不一样。这里你所关心的仅是按照命令行参数的要求输入学号,别的你可以不用
关心。
2)进一步分析,你可以看到,bufbomb 的 main 函数里通过调用 launcher 函数进行后
续的处理,launcher 函数被调用 cnt 次,但除了最后 Nitro 阶段,cnt 都只是 1。这也不是你
关心的重点。
进入 launcher 程序,你会看到它又调用 launch 函数,你不用关心细节,而仅到 launch
函数里找到对 test()或 testn()函数的调用(testn 仅在 Nitro 阶段被调用,其余阶段均调用 test)。
同时你会看到,以后各阶段,如果你的操作不符合预期(也就是执行不成功,!success)时,
会打印“Better luck next time”,这是告诉你这一次没做对。如果你的输入产生这样的提示,
你就要继续尝试其它解了。
3)本实验的主要内容从分析 test 函数开始。这需要你认真分析一下 test 函数的功能。
提示你的是,test 函数调用一个名字叫 getbuf 的函数,该函数的功能是从标准输入(stdin)
读入一个字符串。bufbomb.c 里没有 getbuf 函数的源程序,但告诉你如下:
1 /* Buffer size for getbuf */
2 #define NORMAL_BUFFER_SIZE 32
3
4 int getbuf()
5 {
6 char buf[NORMAL_BUFFER_SIZE];
7 Gets(buf);
8 return 1;
9 }
可见该函数的功能很简单:调用另一个函数 Gets(类似于标准库函数 gets,在 bufbomb.c
里面有它的源程序),从标准输入读入一个字符串(以换行‘\n’或文件结束 end-of-file 字
符结尾),并将字符串(以 null 空字符结尾)存入指定的目标内存位置。在 getbuf 函数代码
中,目标内存位置是具有 32 个字符大小的数组 buf。
getbuf 函数之所以重要,是因为所谓的缓冲区攻击就是从这里开始的。根本原因是,函
数 Gets()并不判断 buf 数组是否足够大而只是简单地向目标地址复制全部输入字符串,因此
输入如果超出预先分配的存储空间边界,就会造成缓冲区溢出。你可以尝试以下输入:
(a)输入到 getbuf()的字符串长度不超过 31 个字符长度。很明显,这时 getbuf()将正常
返回 1,运行示例如下:
评论0