【计算机系统基础】缓冲区溢出攻击

一、BUG根源:越界访问

二、以一个hacker程序为例

1、准备(execve作为启动程序)

【计算机系统基础】缓冲区溢出攻击

execve可以加载程序,而且它还可以带参数列表。argc代表的是参数列表的长度。

参数列表开始时文件名(可执行文件),以NULL结尾。

比方说,命令行为"./hello"时,agrc = 2;

而输入"./test 1209481904803910341",argc = 3;

总之,别忘了NULL的存在。

我们用exceve就可以构造一个启动程序,这就相当于自己在命令行里输入对应内容。

【计算机系统基础】缓冲区溢出攻击

【问】argv中每个元素不是字符指针吗,怎么能指向字符串呢?

【答】在这种把“某某字符串”赋值给一个字符指针的情况下,的双引号做了3件事:  
1.申请了空间(在常量区),存放了字符串 
2.在字符串尾加上了'/0'    
3.返回字符串的首地址(首个字符的地址)

这样argv[1]指针就可以指向常量区的字符串了。

可以看到,这里argv是个字符指针,第一个指针指向./test",第二个指针就是code,code指向用于攻击的字符串,最后一个是NULL指针,这和前面都是对应的。

这样,就可以用execve来作为启动程序,它将本程序的argv[0]作为待启动程序名,剩下的(除了NULL)作为参数,给下面的这个攻击程序。

 

2、主程序被execve执行,并且收到了关于参数的字符串指针argv[1]。

【计算机系统基础】缓冲区溢出攻击

argv[1]存的始终是“0123....”的地址,它的地址传给了outputs,然后用strcpy给了buffer.也就实现了:将“0123....”拷贝到char数组buffer中!

 

3、从内存的观点看

【计算机系统基础】缓冲区溢出攻击

buffer[0]到buffer[15]被0123456789ABCDEF覆盖,然后EBP的旧值就会被XXXX覆盖。

重头戏在于返回地址。由于图中地址是从低到高生长的,那么存返回地址的内存区域,低地址存\x11,高地址存\x08,又因为默认是小端存储,所以低地址存低位,实际上,返回地址变成了0x08048411,也就是hacker程序的地址。

执行完hacker的printf后,会发生segment fault:原因是:正常调用hacker的时候,会先在调用者的栈帧中放入返回地址(下一条指令的地址),但是本例中hacker执行完,没法正常leave到调用者的栈帧,那么更无法获得正确的返回地址(实际上根本没设定)。这可能导致非法操作。