基于栈随机化的溢出攻击防御方法及系统

文档序号:29423662发布日期:2022-03-26 14:42阅读:214来源:国知局
基于栈随机化的溢出攻击防御方法及系统

1.本发明属于计算机安全技术领域,特别涉及一种基于栈随机化的溢出攻击防御方法及系统。


背景技术:

2.栈缓冲区溢出攻击是通过持续往栈内写入数据,从而覆盖返回地址,从而使软件控制流发生变化。栈缓冲区溢出攻击成功的关键在于攻击者能够准确判断返回地址所在的位置。在现实攻击场景中,攻击者一旦发现软件存在栈缓冲区溢出攻击漏洞,往往可以通过有限次的测试,就判断出返回地址所在的位置。对于栈缓冲区溢出攻击,最为经典的防御方法是stackguard。简单来说,stackguard是在栈中插入一个标志字作为“哨兵”,当攻击者通过持续注入非法地址篡改返回地址时,会覆盖“哨兵”。这样,当程序从子函数中返回时,会首先检查“哨兵”是否正常,如果“哨兵”被覆盖,那么就意味着发生攻击。为了防止“哨兵”被攻击者猜测,还需要对“哨兵”进行必要的处理,典型的方法是随机化。由于非法输入的数据通常都是字符串,那么也可以使“哨兵”包含字符串结束字符,使其无法覆盖“哨兵”。stackshield采用的是备份的方法来保护栈中的返回地址,即“影子栈”。当函数被调用时,它的返回地址会被写入影子栈,然后执行函数主体:当函数即将返回时,会将栈项的返回地址和影子栈中的返回地址作比较,如果两个地址完全相同,那么就能够正常返回,否则程序就会停止执行。当然,在函数即将返回时,也可直接将影子栈中的返回地址直接拷贝到运行时栈项,作为函数返回地址。对于传统的影子栈实现方式,由于内存与寄存器之间多次的值拷贝严重影响了它的性能,以至于防御者们不能在防御功效和性能开销之间找到平衡点。
3.现有防御栈缓冲区溢出攻击的方法往往存在被绕开的可能,同时因为完整性检查的原因导致性能开销较大。从攻击原理上来讲,栈缓冲区溢出攻击就是利用诸如数组之类不安全变量与返回地址之间的相对距离固定,通过反复测试就可以准确覆盖返回地址。现有若干工作都是围绕如何检测返回地址完整性来实施,并没有从根本上打破上述这一规律,这使得这些工作往往都无法真正解决栈缓冲区溢出攻击或者存在较大的代价。例如哨兵策略:攻击者在精确了解到返回地址所在位置后,可以跳过哨兵对返回地址进行覆盖,这样就可以在保证哨兵完整性的前提下实施攻击。例如影子栈策略:有的影子栈仍与返回地址存在一定地址映射关系,所以攻击者在覆盖返回地址后仍然可以继续覆盖影子栈中的返回地址,同时由于影子栈和检测的开销,导致影子栈会给软件运行带来一定性能损失。上述方法围绕着返回地址做必要的检查和防护,但是并没有对返回地址本身做处理。


技术实现要素:

4.为此,本发明提供一种基于栈随机化的溢出攻击防御方法及系统,通过动态插入长度随机变化的数据片段,使栈中返回地址与攻击者溢出的起点(即变量,例如字符数组)之间的相对距离发生变化,以空间换时间策略来增加栈中存储空间的大小,达到减少返回地址完整性检测等时间开销的目的,使栈缓冲区溢出攻击难度增加,通过一定的存储空间
浪费来避免返回地址完整性检测等繁琐工作,提高返回地址保护的整体效率。
5.按照本发明所提供的设计方案,一种基于栈随机化的溢出攻击防御方法,包含如下内容:
6.随机种子发生器根据服务例程提供的控制参数产生随机种子;随机数发生器依据随机种子产生用于表示填充在返回地址和数据溢出点(攻击者可能利用的局部变量)之间数据片段长度的随机数;
7.依据随机数确定用于随机动态插入返回地址的数据片段长度,将该随机数确定长度下的数据片段插入返回地址中并生成返回地址随机化处理的内嵌成分内容;
8.通过编译器将所述内嵌成分内容重编译生成功能相同但增加本发明安全机制的程序,使程序函数调用发生时返回地址在栈中的位置随机不确定化。
9.作为本发明基于栈随机化的溢出攻击防御方法,进一步地,随机种子发生器通过采集处理器内部数据来生成随机种子;随机数发生器利用随机种子作为加密算法明文、密钥和初始向量,对明文进行加密生成密文,将该密文作为用于表示返回地址和数据溢出点相对距离的随机数。
10.作为本发明基于栈随机化的溢出攻击防御方法,进一步地,随机种子发生器利用处理器性能监控计数器来获取处理器内部预设类型事件当前时间所发生的次数来生成随机种子。
11.作为本发明基于栈随机化的溢出攻击防御方法,进一步地,随机种子发生器采集每个类型事件当前时间所发生的次数作为输出数据,并将输出数据的最低两位比特作为随机种子组成成分。
12.作为本发明基于栈随机化的溢出攻击防御方法,进一步地,采用环形结构的随机数缓冲池来缓存随机数发生器生成用于确定插入数据片段长度的随机数,该随机数缓冲池的环形结构具有用于从随机数缓冲池中取走随机数的头指针和用于供随机数发生器使用来向随机数缓冲池写入随机数的尾指针。
13.作为本发明基于栈随机化的溢出攻击防御方法,进一步地,采用封锁机制对随机数缓冲池中多线程并发访问进行并发控制,并定时检测随机数缓冲池中的数据量,依据预设的随机数缓冲池大小、溢阈值和空阈值来对随机数缓冲池实施空溢检测唤醒线程,其中,该封锁机制中,任何线程访问随机数缓冲池头指针时,首先向随机数缓冲池申请锁,申请成功后获取随机数,头指针后移并释放锁。
14.作为本发明基于栈随机化的溢出攻击防御方法,进一步地,将随机数作为数据片段的长度随机因子,利用函数调用填充数据长度因子=函数调用填充数据片段的实际长度

长度随机因子来将数据片段插入函数调用目的地址和返回地址之间。
15.作为本发明基于栈随机化的溢出攻击防御方法,进一步地,返回地址压栈操作中,利用push指令将返回地址压栈,并向栈中持续写入随机数长度的数据片段,利用jmp指令跳转到函数调用的目的地址。
16.进一步地,本发明还提供一种基于栈随机化的溢出攻击防御系统,包含:随机数生成模块、随机数内嵌模块和进程编译模块,其中,
17.随机数生成模块,用于随机种子发生器根据服务例程提供的控制参数产生随机种子;随机数发生器依据随机种子产生用于表示返回地址和数据溢出点相对距离的随机数;
18.随机数内嵌模块,用于依据随机数确定用于随机动态插入返回地址的数据片段长度,将该随机数确定长度下的数据片段插入返回地址中并生成返回地址随机化处理的内嵌成分内容;
19.进程编译模块,用于通过编译器将所述内嵌成分内容重编译生成功能相同但增加本发明安全机制的程序,使程序函数调用发生时返回地址在栈中的位置随机不确定化。
20.作为本发明基于栈随机化的溢出攻击防御系统,进一步地,还包含:多软件共享的用户控制接口模块,用于通过用户输入来设置控制参数及相关阈值数据。
21.本发明的有益效果:
22.本发明针对产生的栈缓冲区溢出攻击产生的必要条件(即:数据溢出点与返回地址之间位置固定)进行防御,通过在每一次函数调用中改变数据溢出点与返回地址之间的相对距离,使攻击者每次攻击尝试都只有1/n成功的概率(n为最大随机化阈值),增加了栈缓冲区溢出攻击的难度;本案方案还可与现有一些其它防御方法互补的,由于切入点的不同,防御手段不存在重复交叉,诸如哨兵、影子栈的防御方法可以与本发明结合,以实现共同防御栈缓冲区溢出攻击,便于实际场景应用,具有较好的应用前景。
附图说明:
23.图1为实施例中基于栈随机化的溢出攻击防御方法流程示意;
24.图2为实施例中栈缓冲区溢出攻击防御原理示意;
25.图3为实施例中方案整体概貌示意;
26.图4为实施例中方案系统架构示意;
27.图5为实施例中内部随机数发生器示意;
28.图6为实施例中随机种子发生器工作流程示意;
29.图7为实施例中随机数缓冲池组织及访问原理示意;
30.图8为实施例中call指令替换伪码示意;
31.图9为实时例中ret指令替换伪码示意。
具体实施方式:
32.为使本发明的目的、技术方案和优点更加清楚、明白,下面结合附图和技术方案对本发明作进一步详细的说明。
33.栈缓冲区溢出攻击是通过持续往栈内写入数据,从而覆盖返回地址,从而使软件控制流发生变化。栈缓冲区溢出攻击成功的关键在于攻击者能够准确判断返回地址所在的位置。在现实攻击场景中,攻击者一旦发现软件存在栈缓冲区溢出攻击漏洞,往往可以通过有限次的测试,就判断出返回地址所在的位置。本发明实施例,提供一种基于栈随机化的溢出攻击防御方法,参见图1所示,包含如下内容:
34.s101、随机种子发生器根据服务例程提供的控制参数产生随机种子;随机数发生器依据随机种子产生用于表示返回地址和数据溢出点相对距离的随机数;
35.s102、依据随机数确定用于随机动态插入返回地址的数据片段长度,将该随机数确定长度下的数据片段插入返回地址中并生成返回地址随机化处理的内嵌成分内容;
36.s103、通过编译器将所述内嵌成分内容重编译生成功能相同但增加本发明安全机
制的程序,使程序函数调用发生时返回地址在栈中的位置随机不确定化。
37.利用随机数将返回地址和数据溢出点之间的相对距离随机化处理,使返回地址在栈中的位置并不固定,在每次函数调用过程中都会发生变化,从而使攻击者无法确定返回地址位置(即使攻击者在某次测试中成功溢出,但是在攻击实施时也大概率会失败,因为每次函数调用时返回地址的位置都是发生变化的)。
38.参见图2中(a)和(b)所示,栈缓冲区溢出攻击可以立足于当前栈中某个变量(比如字符数组),攻击者持续写入数据,从而导致返回地址被覆盖。一旦函数返回时就会执行被覆盖后的地址(可能是导向恶意代码的地址),从而使软件控制流发生非法的转移。本案实施例中,将返回地址与数据溢出点的相对位置进行改变,通过随机在返回地址和数据溢出点之间填充长度变化的随机数流。此外,为了增加攻击者的难度,在每一次函数调用时所填充的随机数流长度均可发生变化,从而使得攻击者从数据溢出点出发覆盖返回地址的相对距离始终处于变化的状态,攻击者难以通过穷举达到攻击成功的目的。举例来讲,原来变量与返回地址的相对距离为18个字节,那么攻击者可以在连续覆盖18个字节开始写入恶意地址。采用本案实施例中方案策略后,在某次函数调用时随机填充数据的长度为10,那么攻击者再按照18个字节的方式进行覆盖显然无法成功攻击。当然,攻击者可以进一步尝试,希望发现当前相对距离为28个字节。但是本发明要求每次函数调用时填充的数据长度都会发生变化,在下一次攻击场景中,该长度可能已经变成16,攻击者仍然无法成功。这样,可能使攻击者的攻击尝试在每一次的函数调用中都会归零。
39.假设攻击者不能直接窥视软件运行时数据。具体来说,攻击者可以获得软件的拷贝,并分析软件代码和内部数据,但是不能直接窥视软件运行时所持有的内部数据。更形象来说,攻击者可以提前获知某软件的拷贝,并获知其将在某主机上运行,但是攻击者无法获知该软件在该主机上运行过程中所产生的运行时数据。这一假设是合理:获得软件拷贝是相对容易,但是要获得软件运行时的数据则较为困难。如果攻击者没有获得操作系统控制权,往往是不能得知软件运行时的状态数据。而栈缓冲区溢出攻击本身则是攻击者获得操作系统控制权的契机。故而,可以合理的认为软件运行时的状态数据,攻击者是难以获得的。
40.本案实施例中,参见图3所示,可在操作系统内新增系统服务例程,该服务负责为进程提供若干控制参数,这些参数对于整个操作系统内的所有进程均有效。所有进程内部均植入若干内嵌成分,这些成分将完成返回地址随机化的具体操作。系统服务将按照传统的软件开发方式开发,进程的内嵌成分则通过重编译的方式植入到软件内部。gcc编译器:一种开源编译器,支持c、java等多种语言的编译。由于gcc编译器是开源的,可以修改内部源码改变编译过程,从而实现特有的编译目的,例如:在软件某个类型位置插入指定的代码片段。针对gcc编译器说明,其它编译器也存在类似过程,本案实施例方案不作要求。基于gcc编译器,可以在源码开放的前提下,通过重新编译产生符合要求的可执行指令。
41.系统架构可如图4所示,每个操作系统拥有一个服务例程,作为与用户的交互接口,专门接收用户的控制参数。用户可为整个操作系统设置统一的控制参数,也可以为特定进程设置特定的控制参数。进程内部的嵌入成分主要有:内部随机数产生单元、随机数缓冲池、缓冲池管理单元以及若干榫卯。榫卯:中国木艺的一种结构,利用凹凸匹配的方式实现木件的连接。本案实施例中方案借用该名词来描述在函数返回前和返回后所替换的代码片
段。在函数调用前改变指令序列,所以也需要对函数调用后进行变换,这种相对应的关系与榫卯相符,故采用该名称描述替换的前后代码片段。图示中的内部随机数产生单元包括随机种子发生器和随机数发生器。随机种子发生器从用户控制接口单元接受控制参数产生随机种子,并提供给随机数发生器。随机数发生器产生随机数,并输出至随机数缓冲池。榫卯是与软件内部函数调用配合,负责返回地址的随机化处理。缓冲池管理单元负责缓冲池的访问和填充。
42.作为本发明实施例中基于栈随机化的溢出攻击防御方法,进一步地,随机种子发生器通过采集处理器内部数据来生成随机种子;随机数发生器利用随机种子作为加密算法明文、密钥和初始向量,对明文进行加密生成密文,将该密文作为用于表示返回地址和数据溢出点相对距离的随机数。
43.为了避免攻击者猜测返回地址的位置,必须保证插入数据长度的随机性,为此,本案实施例中,利用软件内部持有的随机数发生器,可简称内部随机数发生器。内部随机数发生器的特点是不依赖容易被攻击者获知或猜测到的外部资源来产生随机数流,使得内部随机数发生器所产生的随机数不易被攻击者所获知或影响。如图5所示,内部随机数发生器主要有两个部分组成:随机种子发生器和随机数发生器。随机数发生器是产生伪随机数流的基础,可采用分组加密算法为基础来产生随机数,简单来说就是反复加密输出的密文分组,并且将不断产生的密文分组输出作为伪随机数。要保证输出的数据流不被攻击者猜测,就必然要保证分组加密算法的初始向量、明文和密钥不被攻击者猜测。这些初始数据将由随机种子发生器产生。从内部随机数发生器的结构来看,要保证随机数的质量,关键在于随机数的初始种子的随机数,或者说不被攻击者猜测到。从计算机体系结构来看,最难以被攻击者控制的是处理器。处理器是高速运转的计算机部件,状态信息一直快速变化。这些状态信息可以被软件采集作为随机种子,而且攻击者想要采集到这些状态信息时,往往信息已经发生了极大的变化。虽然这种方法并不如一些专有内置的硬件随机数发生器所发生的质量要高,但是由于其不对硬件作特殊要求,因此,可以适用广大商用计算机系统。
44.作为本发明实施例中基于栈随机化的溢出攻击防御方法,进一步地,随机种子发生器利用处理器性能监控计数器来获取处理器内部预设类型事件当前时间所发生的次数来生成随机种子。进一步地,随机种子发生器采集每个类型事件当前时间所发生的次数作为输出数据,并将输出数据的最低两位比特作为随机种子组成成分。
45.处理器性能监控计数器是intel处理器的一种硬件特性,用于记录处理器内部一些特定事件发生的次数。从物理形态上来看,就是若干寄存器。一部分寄存器用于设置,主要是选择所要记录的处理器事件(因为有许多处理器事件可以记录,而限于寄存器数量,在某次监控过程中只能记录少量几个事件);一部分寄存器用于记录处理器事件发生的次数(一般处理器型号只有4个寄存器记录次数)。本案实施例中,通过处理器性能监控计数器(performance monitor counter)来采集处理器内部状态数据。处理器性能监控计数器是intel处理器所提供一种硬件特性,它主要用于软件调试等目的,其目的是向用户反馈处理器内部状态。本案实施例中,利用处理器性能监控计数器,就可以获知处理器内部某类型事件当前时间所发生的次数,这些次数就可以用于生成随机种子。需要说明的是,并非所有处理器都拥有处理器性能监控计数器这一硬件特性,但是其它类型处理器大都拥有类似,或者部分类似的硬件特性,用于向处理器用户反馈处理器内部数据。所以本发明所提供的思
路,仍然可以用于其它类型处理器。由于处理器性能监控计数器的采集能力限制,每次采集只能采集少量事件,一般intel处理器型号往往只支持4种事件的采集。为此,本案实施例方案中,默认可设定采集4种事件数量作为初始种子的输入数据。4种事件的选择由软件用户来设定,即接受用户控制指令。这样,可以增加攻击者不可控因素(用户输入),使得攻击者更加难以猜测随机种子的采集。
46.只采集每个事件数量的输出数据的最低两位比特作为随机种子的组成成分。由于任何处理器状态变化必然需要一定时间,即使事件变化时间是1ms,那么对于计数值变化而言,最低比特位(二进制)变化是1ms,而次比特位变化就变成2ms。所以高位比特变化的频率必然慢位比特变化的频率。为了减少被攻击者猜测的概率,本案实施例中,只取采集数据最低两个比特,尽可能保证输入数据的随机性。
47.综上所述,随机种子发生器的工作过程如图6所述。(1)用户输入控制指令,选定所要采集事件集合,并据此设定处理器性能监控器计数器的配置参数;(2)采集单元定时采集处理器状态数据,为确保数据随机性,第一次采集数据均丢弃;(3)采集单元将一次采集的4个数据提交给处理单元,处理单元统一截取最低两个比特,形成1字节的随机种子;(4)根据分组加密算法的分组长度、密钥长度、初始向量长度等需求,采集单元和处理单元协同工作,输出足够长度的随机种子。随机种子将作为分组加密算法的明文、密钥和初始向量,随机数发生器将按分组进行加密,并将加密后的密文作为随机数输出。同时,当前分组的密文将再次作为“明文”循环加密,再次输出密文。这样可以持续不断的输出随机数。关于分组加密算法,本案实施例方案中不作要求,一般而言可以采用aes等通用分组算法,可以采用cbc等加密模式。
48.为了确保输出的随机数小于最大随机化阈值n,所有输出的随机数将采用模运算进一步处理。例如:产生的随机数为x,并且x=num*n+y,那么通过模运算,随机数发生器将最终输出y,而非x。这样确保输出的随机数最大不超过n。结合实际情况,最大随机化阈值n不超过65536,即两个字节的表示范围。过大的最大随机化阈值会导致较为严重的空间损耗。当n小于256,随机数发生器用1个字节表示1个随机数;当n大于256且小于65536时,随机数发生器用2个字节表示1个随机数。随机数的大小对于随机数使用者(榫卯)透明,在随机数获取时,缓冲池管理单元会根据n的大小判断是一次输出给榫卯1个字节,还是2个字节。
49.需要说明的是:本案实施例中所强调的随机数,并不是对其随机性能的要求,而是强调在较小代价的前提下,防止被攻击者所猜测。即使随机性能不佳,只要无法被攻击者猜测,或者猜测的代价过高,即可以满足要求。随机数发生器可以选用其它算法,如序列密码算法,来产生随机数流,或者由用户直接设定初始随机种子亦可。本案实施例中不作此要求。
50.作为本发明实施例中基于栈随机化的溢出攻击防御方法,进一步地,采用环形结构的随机数缓冲池来缓存随机数发生器生成用于确定插入数据片段长度的随机数,该随机数缓冲池的环形结构具有用于从随机数缓冲池中取走随机数的头指针和用于供随机数发生器使用来向随机数缓冲池写入随机数的尾指针。
51.参见图7所示,为了提高榫卯获取随机数的效率,采用随机数缓冲池,并利用环形结构组织,其具有头指针和尾指针。头指针供榫卯使用,用于从缓冲池中取走一个随机数,同时头指针向后移动一个位置(一个位置相当于一个随机数的大小,例如随机数为1字节,
那么就移动一个字节,随机数的大小将根据最大随机化阈值n的范围来设定)。尾指针供随机数发生器使用,用于向缓冲池中写入随机数,每写入一个随机数,尾指针也向移动一个位置。缓冲池管理单元负责缓冲池的管理工作,主要包括:并发控制和空溢检测。
52.作为本发明实施例中基于栈随机化的溢出攻击防御方法,进一步地,采用封锁机制对随机数缓冲池中多线程并发访问进行并发控制,并定时检测随机数缓冲池中的数据量,依据预设的随机数缓冲池大小、溢阈值和空阈值来对随机数缓冲池实施空溢检测唤醒线程,其中,该封锁机制中,任何线程访问随机数缓冲池头指针时,首先向随机数缓冲池申请锁,申请成功后获取随机数,头指针后移并释放锁。
53.为了支持软件多线程工作,缓冲池访问支持多线程并发访问,并发控制由缓冲池管理单元完成。缓冲池管理单元采用封锁机制:任何线程访问头指针时,首先向缓冲池申请锁,只有申请成功以后,才可以获取随机数,获取成功且头指针后移后,释放锁。这样可以支持多个线程中的榫卯共同访问缓冲池。尾指针不需要并发控制,因为只有随机数发生器对其进行操作。缓冲池管理单元定时检测缓冲池的数据量。缓冲池管理单元以线程的形式运行,定时被唤醒实施空溢检测。设缓冲池的大小为size,当前数据量为cur,余量比例则为cur/size。溢阈值设置为ko,空阈值设置为kn。当cur/size《kn,表明缓冲池中数据已经低于警戒线,缓冲池管理单元要求随机数发生器开始补充随机数。当cur/size》ko,表明缓冲池中数据已经高于警戒线,随机数发生器停止补充随机数。为了避免频繁补充缓冲池,用户应该根据软件使用随机数的需求,合理设置缓冲池的大小size。
54.基于以上内容,关于随机数缓冲池的主要工作归纳如下:(1)用户设置缓冲池的主要参数,包括缓冲池大小size,溢阈值ko,空阈值kn等;(2)缓冲池管理单元唤醒随机数发生器,开始填充随冲池,直至达到溢阈值ko;(3)软件运行过程中,分散在软件内部的各个榫卯开始按照封锁要求,通过头指针访问随机数;(4)缓冲池管理单元定时检测缓冲池当前数据量cur是否小于空阈值,如果是则唤醒随机数发生器过行填充,否则不作操作;(5)当软件退出时,缓冲池存储空间也被清空。
55.作为本发明实施例中基于栈随机化的溢出攻击防御方法,进一步地,将随机数作为数据片段的长度随机因子,利用函数调用填充数据长度因子=函数调用填充数据片段的实际长度

长度随机因子来将数据片段插入函数调用目的地址和返回地址之间。进一步地,返回地址压栈操作中,利用push指令将返回地址压栈,并向栈中持续写入随机数长度的数据片段,利用jmp指令跳转到函数调用的目标地址。
56.为了将返回地址与攻击溢出位置的相对距离动态变化,本案实施例中将随机长度的数据片段插入到两者之间。为了实现这一目的,可采用指令替换的方法。在传统方法中,返回地址是由call指令完成压栈操作。然而call指令可以视为压栈和跳转两个操作的集合,而这两个操作无法分拆。为了在跳转前继续在栈中写入数据,必须将call指令进行替换,使两个操作分别进行,从而使得将随机长度数据段插入成为可能。
57.如图8所示,将call指令替换为一系列指令。这一系列指令,不仅需要完成原来call指令的功能,这需要在返回地址后继续向栈中写入若干数据。如图8右部所示,主要分为四个内容。(1)使用push指令将返回地压栈,即伪码“push返回地址”。(2)持续的写入数据,写入数据的长度由随机数而定。(3)将包含填充数据长度的因子压入栈中,即伪码“push n”。(4)最后是跳转到目的地址,即所调用的函数,即伪码“jmp*”。
58.说明包含填充数据长度的因子。软件每次运行时,会由随机数发生器产生一个与地址等长度的随机数,称之为长度随机因子len_r。用len表示本次函数调用填充数据的实际长度,那么包含填充数据长度的因子用len_n表示,存在关系len_n=len

len_r。之所以引入len_r,而非将长度len直接压入栈中,是避免攻击者通过覆盖len来达到影响函数返回的过程(因为函数返回时,需要指示填充长度len)。
59.注意:(1)写入数据的长度与保护力度相关,写入数据越多,攻击者猜测的难度也越大,两者呈线性递增的关系;(2)将包含填充数据长度的因子压入栈中,并不会影响安全性,因为攻击者可以覆盖len_n,但是并不会知道len的值(本案实施例中给出安全假设所限定的,且安全假设是合理的)。
60.为了保证函数能够正确返回,必须对ret指令做必要的处理。由于ret指令会直接取栈顶数据作为返回地址,并以此为目标地址进行跳转。这会使得ret指令会误将随机压入栈中的数据作为返回地址进行跳转,从而导致函数错误。必须将原来作为随机填充的数据弹出栈,将真正的返回地址作为栈顶元素保留。所以如图9所示,对ret指令进行替换。主要分为四个内容。(1)读取长度随机因子len_r;(2)首先是读取栈顶数据(即:len_n),根据关系len_n=len

len_r得到填充长度len;(3)根据len,执行一系列的pop指令,将随机填充的数据出栈;(4)最后用jmp指令执行真正的跳转。当然,可以直接操作栈顶指针来完成类似的工作。但是考虑到涉及对现有执行流过多的改变,故而,可采用这种只替换call和ret指令的方法来实现返回地址的压栈操作。这些替换后的指令可称为榫卯。榫卯与函数调用匹配使用。在函数调用时,插入了长度随机的数据片段,相当于改变木材接口的原有结构。所以在函数返回时,做同样的修正,使函数能够正常返回。榫卯在本案实施例中要求植入到软件内部。由于软件内部存在多个函数调用,所以榫卯也会有若干个被植入到软件内部。
61.指令替换在编译阶段完成,即可在gcc编译器中完成两类指令的指令替换过程。gcc编译器在内部编译过程中,会首先生成中间环节的atl形式的编译中间结果,这些中间结果会参考编译模板,将其编译成汇编指令形式。通过更改gcc编译器的编译模板,将call指令和ret指令对应内容替换成上述内容。这样,可以在获知源码的前提下,不经过用户修改源码就可以实现本发明的目的。
62.本案实施例中,为了使攻击者的攻击尝试归零,在每次函数调用时,在返回地址与溢出起点之间插入的随机数据的长度发生变化;为了避免攻击者猜测到插入长度的规律,利用基于处理器状态信息的随机数发生器,使攻击者难以通过设置软件外部环境来影响随机数发生流程。从整体上来看,如果动态插入数据的长度范围为[1,n],那么攻击成功的概率为1/n,并且攻击成功的概率不会因为攻击次数的增加而累加。这样,方案中只是通过一定的存储空间浪费,避免了返回地址完整性检测这些繁琐的工作,提高返回地址保护的整体效率。
[0063]
进一步地,基于上述的方法,本发明实施例还提供一种基于栈随机化的溢出攻击防御系统,包含:随机数生成模块、随机数内嵌模块和进程编译模块,其中,
[0064]
随机数生成模块,用于随机种子发生器根据服务例程提供的控制参数产生随机种子;随机数发生器依据随机种子产生用于表示返回地址和数据溢出点相对距离的随机数;
[0065]
随机数内嵌模块,用于依据随机数确定用于随机动态插入返回地址的数据片段长度,将该随机数确定长度下的数据片段插入返回地址中并生成返回地址随机化处理的内嵌
成分内容;
[0066]
进程编译模块,用于通过编译器将所述内嵌成分内容重编译至系统内所有进程中,使函数调用发生时返回地址在栈中的位置随机不确定化。
[0067]
通过本案方案中防御方案,软件工作流程在启动后,植入软件内部的随机种子发生器,会向系统服务请求最大随机数阈值和采集处理器事件序列,并完成随机种子的产生;随机数发生器在接受随机种子以后,会开始产生随机数,填充至缓冲池中,并定时实施空溢检测;一旦触发函数调用,榫卯从缓冲池中取走一个随机数作为随机填充数据的长度,在将返回地址压栈中后,持续写入此长度的数据;函数返回时,榫卯会绕开填充的数据,取得返回地址再返回。
[0068]
注意:随机种子发生器,只在软件启动时执行一次。每个软件启动时会产生一次随机种子,操作系统内的所有软件并不共享随机种子。随机种子作为随机数发生器的输入数据,一旦生成就保存在随机数发生器中,并随着软件的退出而自动消失。随机种子生成由软件启动时触发,随机种子发生器是重编译时植入软件内部,其位置在于操作系统完成软件装载,并完成其它必要的初始化以后,但还未开始真正的业务工作。以控制台控序而言,就可以将随机种子发生器植入到main函数的第一条指令。至于main函数之前的其它初始化函数,可以采用从编译器或者操作系统层面,采用本发明所设计的思想进行优化。
[0069]
软件启动后的整体流程描述如下:软件启动时,从用户控制数据接口单元获取控制数据,为随机种子发生器提供参数。随机种子发生器通过处理器性能监控计数器采集处理器的状态信息,生成随机种子。随机数发生器以分组加密算法为基础,使用随机种子作为算法输入,按需生成伪随机数据流。随机数缓冲池满以后,随机数发生器停止产生随机数,恢复软件原有工作流程。当软件发生函数调用时,对应的榫卯采用封锁机制访问缓冲池,获取一个随机数作为填充数据的长度。榫卯完成指定长度的栈数据填充,并跳转到函数。当函数返回前,对应的榫卯通过栈顶数据知道随机填充数据的长度,然后获取正确的返回地址,返回函数。缓冲池管理单元定时检测缓冲池的数据余量,及时补充缓冲池内随机数。软件退出后,包括缓冲池在内的所有资源释放,结束。
[0070]
作为本发明实施例中基于栈随机化的溢出攻击防御系统,进一步地,还包含:多软件共享的用户控制接口模块,用于通过用户输入来设置控制参数及相关阈值数据。
[0071]
用户控制接口模块可作为面向用户的唯一接口,也是操作系统中多个软件共享的。用户控制接口模块用于输入相应的控制接口参数,指导整个操作系统内所有使用该机制的软件。用户可以通过该接口面向所有软件设置相应的控制参数,也可以通过该接口向指定软件设置特有的控制参数。用户可以根据软件的安全敏感程度的不同,为不同软件指定特定的安全策略。用户控制接口模块最为核心的工作是必要的硬件环境初始化。为了确保随机种子的安全性,可以处理器状态数据为输入,这些数据的采集依赖于处理器性能监控计数器。所以,用户控制接口模块必须首先完成处理器型号查询以及硬件环境的初始化设置。在明确处理器型号以后,用户控制接口模块罗列可使用的处理器事件类型,供用户筛选和确定。故用户控制接口单元首先要完成的工作有:(1)完成处理器型号的查询;(2)完成处理器性能监控器控制寄存器的设置(如:是否采集内核空间的数据);(3)罗列可使用的处理器事件类型,供用户筛选。其中,可采集的处理器事件应该满足两个条件:(1)事件应该是攻击者难以控制或影响的,(2)事件应该是易失的。前者是确保攻击者无法影响随机数种子
的数据来源,一般的这些事件如:br_misp_exec.cond,攻击者即使在完在控制操作系统,甚至硬件本身,也难以准确的控制分支预计事件发生,这一类事件就满足第(1)个条件。后者是强调数据快速变化,攻击者难以与捕捉同一数据,典型的如l2_trans.l1d_wb,由于cache快速的读写,导致这一状态在快速发生变化,从而导致数据变化十分迅速。不同型号处理器有不同的支持范围,但是大多数型号处理器都支持上百种事件,所以用户有足够的事件可供选择。
[0072]
最大随机化阈值n是必须设置的控制参数。最大随机化阈值n是榫卯随机填充数据的最大长度。n不宜过大,否则会造成过多存储空间浪费。因为每一次函数调用,都会生成一个不超过n的、不使用的栈空间。同时由于计算机系统本身也会对栈空间的最大长度作限制,过大的n不会被操作系统所接收。n也不宜过小,否则攻击者猜测的难度将大大减低,减少了保护力度。一般情况下,可以将n设为64,即每次攻击者攻击成功的概率为1/64。用户可以根据需求,给不同软件设置不同的最大随机化阈值n,以实现不同的防护程度。其它参数,例如缓冲池大小等参数,用户也可设置,也可采用默认选项。
[0073]
除非另外具体说明,否则在这些实施例中阐述的部件和步骤的相对步骤、数字表达式和数值并不限制本发明的范围。
[0074]
基于上述的方法和/或系统,本发明实施例还提供一种服务器,包括:一个或多个处理器;存储装置,用于存储一个或多个程序,当所述一个或多个程序被所述一个或多个处理器执行,使得所述一个或多个处理器实现上述的方法。
[0075]
基于上述的方法和/或系统,本发明实施例还提供一种计算机可读介质,其上存储有计算机程序,其中,该程序被处理器执行时实现上述的方法。
[0076]
在这里示出和描述的所有示例中,任何具体值应被解释为仅仅是示例性的,而不是作为限制,因此,示例性实施例的其他示例可以具有不同的值。
[0077]
应注意到:相似的标号和字母在下面的附图中表示类似项,因此,一旦某一项在一个附图中被定义,则在随后的附图中不需要对其进行进一步定义和解释。
[0078]
最后应说明的是:以上所述实施例,仅为本发明的具体实施方式,用以说明本发明的技术方案,而非对其限制,本发明的保护范围并不局限于此,尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,其依然可以对前述实施例所记载的技术方案进行修改或可轻易想到变化,或者对其中部分技术特征进行等同替换;而这些修改、变化或者替换,并不使相应技术方案的本质脱离本发明实施例技术方案的精神和范围,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应所述以权利要求的保护范围为准。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1