现代计较机根基上都是成立在冯-诺伊曼体系之上,而这一体系有一个最大的问题就是数据和指令都生存在存储器中。
在计较机的内存中,既包括了措施运行的所有代码指令,又包括了措施运行的输入输出等各类数据,并没有一种强制的机制将指令和数据区分。因为对付计较机来说它们都是一样的二进制0和1,大部门时候都是靠措施凭据既定的“法则”去表明领略内存中的这些0和1。而一旦这些“法则”领略错误,工作就变得糟糕起来。
详细到我们现代CPU和OS,不管是x86/x64处理惩罚器,照旧ARM处理惩罚器,均回收了寄存器+仓库式的设计,而这个仓库中,既包括了措施运行各个函数栈帧中的变量数据等信息,还生存了函数挪用发生的返回地点。
所谓栈溢出进攻,则是通过一些手段输入到栈中的缓冲区中,突破缓冲区原有的边界,将存储返回地点的位置包围为一个数值,使其指向进攻者提前部署的恶意代码位置,挟制了措施的执行流程。
防止手段:现代操纵系统针对栈溢出进攻已经有很是成熟的应对方案,像Linux平台的Stack Canary,Windows平台的GS机制等等,措施员需要做的就是充实操作这些机制。
重点存眷:C/C++工程师
整数溢出进攻和栈溢出进攻一样,整数溢出进攻也是属于溢出类进攻,纷歧样的是溢出的方针不是栈中的缓冲区,而是一个整数。
我们知道,计较机数值以补码的方法暗示和存储。在暗示一个有标记数时,最高位是用来暗示这是一个正数(0)照旧一个负数(1),好比对付一个16位的short变量而言,+1和-1的暗示要领如下:
+1: 0000 0000 0000 0001-1: 1111 1111 1111 1111一个16位的short变量暗示的范畴是-32768~32767,此刻思考一个问题,如果一个short变量的值此刻是32767:
32767: 0111 1111 1111 1111假如此刻对其执行+1操纵,将酿成:
1000 0000 0000 0000而这正是-32768的补码形式!
试想一下,假如这个变量名字叫length作为百思特网strcpy参数,或是叫index作为数组的下标,整数的溢出将导致可骇的效果,轻则历程瓦解,处事宕机,重则长途代码执行,拿下节制权。
重点存眷:所有措施员
空指针进攻空指针一般呈此刻指针没有初始化,可能利用new举办工具建设/内存分派时失败了,而粗心的措施员并没有查抄指针是否为空而举办会见导致的进攻。
大大都环境下,这将导致内存地点会见异常,措施会瓦解退出,造成拒绝处事的现象
而在一些非凡的环境下,部门操纵系统答允分派内存起始地点为0的内存页面,而进攻者假如提前在该页面筹备好进攻代码,则大概呈现执行恶意代码的风险。
释放后利用进攻释放后利用Use After Free意为会见一个已经释放后的内存块。较多的呈此刻针对欣赏器的JavaScript引擎的进攻中。
正常环境下,一个释放后的工具我们是没法再会见的,但假如措施员粗心大意,在delete工具后,没有即时对指针配置为NULL,在后续又继承利用该指针会见工具(好比通过工具的虚函数表指针挪用虚函数),将呈现内存会见异常。