了解:
首先了解一下什么是格式化字符串:
C语言里面有一个经常用于向屏幕输出字符的函数:printf。printf的第一个参数是字符串,被称为格式化字符串。
我们在使用的时候经常使用如%d、%s、等占位符,然后printf就会依据这些占位符和其他参数整合出一个完整的字符串输出
其实书画字符串函数不仅仅是printf一个,还有以下几个 :
scnaf
fprintf
vprintf
vfprintf
sprintf......
漏洞的产生:
接下来就来看看漏洞是怎么产生的:
产生的原因主要是因为没有给printf提供变量printf ("........%d\n",a) //正常的
printf ("........%d\n") //错误的
那么如果不给变量的话printf还是能打印出数据,那么这个数据是哪里来的呢?
这就得讲到printf的原理了
printyf打印原理:
出现这种问题是因为printf不会检查格式化字符串的占位符是否与所给的参数数目相等。而在printf输出的过程里面,每遇到一个占位符就会到“约定好的位置”获取数据并跟据该占位符的类型解码输出。
那么约定好的位置在那个地方呢?
首先我们来看一下printf是怎么访问到实参的:
当printf访问实参的时候,按照C语言函数调用栈的规则,父函数会将实参倒序压入栈里面,并且第一个参数与子函数的return_address 相邻,因此printf知道第一个的实参为“.......%d\n”的地址,位于:ebp + 2 * sizeof(word);
同理,第二个实参(此处第二个实参为整数 10)位于:ebp + 3 * sizeof(word)
。
再来看一下错误的情况:
因为没有提供参数a,所以父函数只把第一个参数压入栈,而它的上方就是其他的数据了,到那时printf还是认为 它的父函数会像以前一样把需要的参数压入栈,那么当它想访问第二个参数的时候就会认为 ebp + 3 * sizeof(word)
就是第二个参数,但实际上它是其他的数据
那么当我们传入%x的话,就会通过我们传入的N个%x就会泄露n*8个字节的内存数据,造成数据泄露:
Comments | NOTHING