漏洞分析——二进制漏洞

二进制漏洞:传统的缓冲区溢出、UAF(Use-After-Free)等涉及二进制编码的漏洞统称为二进制漏洞
根据缓冲区所处的不同内存空间以及分配方式的不同,缓冲区溢出可以分为栈溢出和堆溢出

栈溢出原理:

栈是一种基本的数据结构,是由编译器自动进行分配、释放的。栈遵循先进后出的规则,生长方向为从高向低生长,也就是地址由高到低
栈中存放的数据:对于要调用的子函数来说,存放子函数的参数、返回地址、局部变量等重要信息。函数可以通过栈来方便的对局部变量进行读取。
在调用一个子函数的时候,我们要做的工作有以下几步:
1:将参数push到栈上
2:将当前eip的值push到栈上进行保存,当作函数调用之后的返回地址
3:执行子函数的函数体
漏洞分析——二进制漏洞_第1张图片
程序在调用子函数的时候,(可以通过OD等工具看汇编代码)会先将ebp压栈调整栈结构,之后会在栈上开辟一段空间,这段空间就是子函数的空间。在实际的函数调用过程中,我们的局部变量是不断变化的,而且需要注意的是 :栈是向低地址的方向生长的,但是局部变量是向高地址生长的
漏洞分析——二进制漏洞_第2张图片
也就是说,变量是向下 “吞噬” 的,这样的话就会产生一个问题:当变量向下“吞噬”的时候,"一不小心"把下边ebp和eip的空间也”吞噬“了,会发生什么事情呢?这个时候就会产生我们说的栈溢出现象,我们知道eip的值是用来函数执行完之后返回用的,但是在被”吞吃“之后,显然栈空间的值已经发生改变,这个时候就会返回错误。这个时候我们也就控制了程序的EIP,可以为所欲为了。那么什么是造成栈溢出的主要原因呢?
代码编写过程的不规范,举个例子:在执行数据复制的操作的时候,不检查源数据的长度直接进行复制,很有可能会因为目的空间不够而导致这种情况的产生,如何避免这种情况呢?最简单的办法就是在执行前增加长度限制判断。

整型溢出漏洞
整形溢出漏洞主要是指在计算机中的数据类型问题导致的溢出漏洞,整型作为一种数据类型,不仅仅存在正负的问题还存在数据范围的问题甚至还包括不同整型数据之间的赋值和转换问题,而在这其中容易产生一系列不严谨的算法,可能会导致溢出漏洞的产生。
因此,综上所述,整型漏洞通常分为以下几种:
1:存储溢出漏洞
2:运算溢出漏洞
3:符号问题导致的漏洞

一:存储溢出漏洞
存储溢出相对比较简单易懂,就是由于使用不同的数据类型来存储整型数造成的。
举个例子:
下边这个代码段,在实际的赋值过程中:作者想要达到的目的可能是将a的值赋给b,但是在实际的输出过程中,我们可以看到,实际的输出结果并不是a的值,输出结果如下:

int a=0x10000;
short b=a;
printf("%d",b);

输出结果:
漏洞分析——二进制漏洞_第3张图片
这是因为,不管哪一种数据类型都是由存储范围的限制的,int型是32位长度的,但是short是16位的数据长度,因此在进行赋值操作的时候,short型的数据没办法将int型数据的所有位数全盘接受,这样就会导致我们之前说的存储溢出漏洞。

二:运算溢出漏洞
相对于存储溢出来说,运算溢出相对来说更加容易理解,顾名思义,运算溢出就是在整型数据在运算过程中导致的溢出,我们都知道,数据类型的范围长度以及范围是有限的,当然基于这一点我们在定义数据类型的时候大多时候还是会谨慎的使用各类数据类型,防止超出数据类型的范围,但是需要注意的是,我们往往将注意力放在赋值以及定义一个变量的时候,但是在定义之后,对该数据的各类运算是不是会超出数据类型的范畴我们通常是不会给太多关注的,因为我们大多情况下关注的都是运算的结果。这样也就导致了,很多漏洞都是通过这类型的溢出导致的。

三:符号问题导致的漏洞
整型数据分为无符号整型数据和有符号整型数据,如果在编写程序代码的时候,忽略符号问题造成的影响,那么就极有可能造成安全事故。举个著名的例子:
Apache Web Server分块溢出漏洞

UAF漏洞
UAF漏洞全称Use-After-Free,字面意思,也就是说在释放之后使用。具体过程如下图解:
漏洞分析——二进制漏洞_第4张图片
UAF漏洞是因为指针的使用不当造成的,在释放空间或指针之后,又重新被后续的函数调用,因此编写程序的时候为了避免这一漏洞的产生,需要在实际运用的过程中,对指针的有效性进行判断。

你可能感兴趣的:(漏洞分析——二进制漏洞)