VC++中利用/GS开关防止缓冲区溢出

缓冲区溢出通常表现为一个最为常见的漏洞而存在于今天的各种软件之中,黑客可以用恶意的输入,从而更改程序的执行流程,由此入侵相应的进程、电脑、或整个域。如果进程运行于一个高度受信的账户之下,如管理员或本地系统账户,那么黑客带来的破坏将是极其严重,并有潜在广泛传播的危险。近几年来爆发的一些"知名"病毒,如红色代码、冲击波、震荡波等等,都源于C/C++代码缓冲区溢出的结果。

从程序的角度来看,缓冲区溢出只是一个再简单不过的编程错误--都是关于复制一个内存区域的内容到另一个内存区域,而目标内存区域容量太小无法容纳。以下的代码作了简单的演示:

char* source = "A reasonably long string";

char dest[10];

::strcpy(dest, source);

在本例中,源字符串的长度为25个字符(包括了空结束符),它对目标内存块来说,无疑太大了,而目标内存块声明在堆栈上;当此代码执行时,将会破坏掉原有堆栈,程序会因为一个访问违例而崩溃。如果此源内存块由外部第三方提供,那么就有可能存在一个漏洞,因为它允许传入函数的内存块以一种特定的方式修改堆栈。

当在C/C++中调用一个函数时,调用函数的返回地址被存放在堆栈中,因此在被调用函数执行完毕时,执行流程能重新返回到原处。如果调用了一个可能包含潜在缓冲区溢出的函数,返回地址可能会被修改,而且执行流程将会跳到缓冲区数据中指定的地方。通过改变函数的返回地址,攻击者可获取进程中任意位置的代码以执行,一般而言,主要可以两种方式被利用:

·如果带有漏洞的程序是已知、且容易访问到的,攻击者可查找某函数的地址,这通常会在所有进程实例的一处固定地址处被找到;并修改堆栈,等着此函数被调用。

·要执行的指令可作为缓冲区的一部分传递到进程地址空间,攻击者利用此来完成攻击。

防范缓冲区溢出

防范缓冲区溢出最简单的方式是限制复制的数据大小,使其不能大于目标缓冲区容量。虽然此方法看上去微不足道,但实际上,经验证明,要在那些大型的C/C++代码中,完全消除了缓冲区溢出的隐患,是件非常艰巨的任务。另外,使用如 .NET或Java这样的受托管技术,也能极大地降低缓冲区溢出的危险,但把大型项目移植到此技术上,实施起来不太可能也不适当。

基于堆栈的缓冲区溢出可如此简单地被利用的原因在于,编译器生成的指令,会把函数的返回地址存储在堆栈中,但要认识到,编译器在这个问题中,只扮演了一个小小的角色。从Visual C++.NET(7.0)开始,Visual C++开发小组采取了一种方法,可从编译器方面减少此类问题发生的机率,他们在堆栈中保存函数返回地址的数据之下,插入了一个带有已知数值的cookie,由此,如果缓冲区溢出改变了函数的返回地址值,同样也会覆盖这个cookie,而在函数返回时,一般会对这个cookie进行检测,如果检测到cookie已被修改,就会抛出一个安全异常,而如果这个异常未被处理,此进程就会终止。以下的代码演示了一个带有安全异常处理方法的简单程序:

void _cdecl sec_handler( int code, void *)

{

if ( code == _SECERR_BUFFER_OVERRUN )

{

printf("检测到一个缓冲区溢出。 ");

exit(1);

}

}

int main()

{

_set_security_error_handler( sec_handler );

//主程序代码在此省略。

}

Visual C++.NET 2003(7.1)通过移动易受攻击的数据结构--(如异常处理方法的地址)--到堆栈中位于缓冲区之下的某个位置,增强了缓冲区溢出的保护力度。在编译器的7.0版本中,可通过破坏缓冲区与cookie之间的敏感数据,绕过安全cookie所提供的保护;然而,在新版本的编译器中,已把这些数据移到位于缓冲区下的一个区域,现在,想要通过修改这些数据而达到溢出,似乎是不太可能了。

图1演示了在C++编译器6、7.0、7.1中,堆栈概念上的布局,并演示了堆栈由高地址向低地址空间方向增长,这也是当程序执行时,堆栈增长的方向。堆栈向下增长,正是导致缓冲区溢出的主要原因,因为溢出会覆写在比缓冲区更高的内存地址空间上,而此正是易受攻击数据结构的栖身之地。

图1:堆栈逻辑布局

除了把异常处理方法等信息移到堆栈中数据缓冲区之下,Visual C++.NET 2003的链接器也把结构化异常处理方法的地址放到可执行文件的头部中。当异常发生时,操作系统可以检查堆栈中的异常信息地址,是否符合记录在文件头信息中的异常处理方法,如果情况不符,异常处理方法将不会执行。比如说,Windows Server 2003就可检查结构化异常信息,而此项技术也在Service Pack 2中移植到了Windows XP上。

而Visual C++ 2005(8.0)在此基础上又更进了一步,通常当有函数调用发生时,如果其中的一个本地缓冲区超出限度了,攻击者可能改写堆栈中在此之上的任何东西,包括异常处理、安全cookie、帧指针、返回地址和函数参数。而这些值的大多数被不同的机制所保护(如安全异常处理),但对一个有函数指针作参数的函数来说,仍有机会被溢出。如果一个函数接受一个函数指针(或结构、类中包含有函数指针)作为参数,攻击者就有可能改写指针中的值,使代码执行任何他想要的函数。鉴于此,Visual C++ 2005编译器将分析所有可能存在此漏洞的函数参数,并复制一份函数参数--并不使用原有的函数参数,把它放在堆栈中本地变量之下。如果原有函数参数被溢出改写了,只要副本中的值仍保持不变,整个函数就不会被攻破。

应用缓冲区保护

只需简单地打开/GS编译器开关,就可启用缓冲区保护。在Visual Studio中,此开关可在"C/C++"选项页的"代码生成"选项中找到(如图2所示)。默认情况下,在Debug配置下为关,而在Release配置下为开。

图2:设置/GS开关

如果用最新版本的编译器进行编译,并生成结构化异常信息,那么在默认情况下,安全结构化异常处理将是打开的,另外,也可以使用/SAFESEH:NO命令行选项来关闭安全结构化异常处理,在Visual Studio的工程设置中,是没办法关闭安全结构化异常处理的,但仍可在链接器中使用此命令行选项来完成。

/GS及更远的安全前景

仅仅是打开一个编译器开关,不会使一个程序彻底变得安全,但在安全漏洞以各种形式出现的今天,它将有助于使程序更加安全。基于堆栈的缓冲区溢出是安全漏洞中的一大类,但随着黑客攻击技术的不断更新,相信它的谢幕,还有一段很长的路要走。

在Microsoft正式的术语中,/GS和SAGESEH均为软件强制的数据执行保护(DEP),软件强制的DEP也能以硬件的方式实现,如在实现了此功能的CPU中,如果数据出现在被标记为"不可执行"的内存页中,将不会执行它。Windows XP SP2及Windows Server 2003现在已支持这些技术,目前市面上的大多数的32位CPU及全部的64位CPU,都支持No Execute(NX)这类安全增强技术。

任何一个好的安全系统,均有多层防范措施应对安全威胁。本文所涉及的编译器开关,它能防范或减少普通编码错误所带来的安全隐患,而且它具有易于使用和低成本的特点,在这场没有硝烟的战争中,不失为一个好的解决方案,绝对值得你的程序采用。

本篇文章来源于:开发学院 http://edu.codepub.com   原文链接:http://edu.codepub.com/2008/1217/190.php

缓冲区溢出通常表现为一个最为常见的漏洞而存在于今天的各种软件之中,黑客可以用恶意的输入,从而更改程序的执行流程,由此入侵相应的进程、电脑、或整个域。如果进程运行于一个高度受信的账户之下,如管理员或本地系统账户,那么黑客带来的破坏将是极其严重,并有潜在广泛传播的危险。近几年来爆发的一些"知名"病毒,如红色代码、冲击波、震荡波等等,都源于C/C++代码缓冲区溢出的结果。

从程序的角度来看,缓冲区溢出只是一个再简单不过的编程错误--都是关于复制一个内存区域的内容到另一个内存区域,而目标内存区域容量太小无法容纳。以下的代码作了简单的演示:

char* source = "A reasonably long string";

char dest[10];

::strcpy(dest, source);

在本例中,源字符串的长度为25个字符(包括了空结束符),它对目标内存块来说,无疑太大了,而目标内存块声明在堆栈上;当此代码执行时,将会破坏掉原有堆栈,程序会因为一个访问违例而崩溃。如果此源内存块由外部第三方提供,那么就有可能存在一个漏洞,因为它允许传入函数的内存块以一种特定的方式修改堆栈。

当在C/C++中调用一个函数时,调用函数的返回地址被存放在堆栈中,因此在被调用函数执行完毕时,执行流程能重新返回到原处。如果调用了一个可能包含潜在缓冲区溢出的函数,返回地址可能会被修改,而且执行流程将会跳到缓冲区数据中指定的地方。通过改变函数的返回地址,攻击者可获取进程中任意位置的代码以执行,一般而言,主要可以两种方式被利用:

·如果带有漏洞的程序是已知、且容易访问到的,攻击者可查找某函数的地址,这通常会在所有进程实例的一处固定地址处被找到;并修改堆栈,等着此函数被调用。

·要执行的指令可作为缓冲区的一部分传递到进程地址空间,攻击者利用此来完成攻击。

防范缓冲区溢出

防范缓冲区溢出最简单的方式是限制复制的数据大小,使其不能大于目标缓冲区容量。虽然此方法看上去微不足道,但实际上,经验证明,要在那些大型的C/C++代码中,完全消除了缓冲区溢出的隐患,是件非常艰巨的任务。另外,使用如 .NET或Java这样的受托管技术,也能极大地降低缓冲区溢出的危险,但把大型项目移植到此技术上,实施起来不太可能也不适当。

基于堆栈的缓冲区溢出可如此简单地被利用的原因在于,编译器生成的指令,会把函数的返回地址存储在堆栈中,但要认识到,编译器在这个问题中,只扮演了一个小小的角色。从Visual C++.NET(7.0)开始,Visual C++开发小组采取了一种方法,可从编译器方面减少此类问题发生的机率,他们在堆栈中保存函数返回地址的数据之下,插入了一个带有已知数值的cookie,由此,如果缓冲区溢出改变了函数的返回地址值,同样也会覆盖这个cookie,而在函数返回时,一般会对这个cookie进行检测,如果检测到cookie已被修改,就会抛出一个安全异常,而如果这个异常未被处理,此进程就会终止。以下的代码演示了一个带有安全异常处理方法的简单程序:

void _cdecl sec_handler( int code, void *)

{

if ( code == _SECERR_BUFFER_OVERRUN )

{

printf("检测到一个缓冲区溢出。 ");

exit(1);

}

}

int main()

{

_set_security_error_handler( sec_handler );

//主程序代码在此省略。

}

Visual C++.NET 2003(7.1)通过移动易受攻击的数据结构--(如异常处理方法的地址)--到堆栈中位于缓冲区之下的某个位置,增强了缓冲区溢出的保护力度。在编译器的7.0版本中,可通过破坏缓冲区与cookie之间的敏感数据,绕过安全cookie所提供的保护;然而,在新版本的编译器中,已把这些数据移到位于缓冲区下的一个区域,现在,想要通过修改这些数据而达到溢出,似乎是不太可能了。

图1演示了在C++编译器6、7.0、7.1中,堆栈概念上的布局,并演示了堆栈由高地址向低地址空间方向增长,这也是当程序执行时,堆栈增长的方向。堆栈向下增长,正是导致缓冲区溢出的主要原因,因为溢出会覆写在比缓冲区更高的内存地址空间上,而此正是易受攻击数据结构的栖身之地。

图1:堆栈逻辑布局

除了把异常处理方法等信息移到堆栈中数据缓冲区之下,Visual C++.NET 2003的链接器也把结构化异常处理方法的地址放到可执行文件的头部中。当异常发生时,操作系统可以检查堆栈中的异常信息地址,是否符合记录在文件头信息中的异常处理方法,如果情况不符,异常处理方法将不会执行。比如说,Windows Server 2003就可检查结构化异常信息,而此项技术也在Service Pack 2中移植到了Windows XP上。

而Visual C++ 2005(8.0)在此基础上又更进了一步,通常当有函数调用发生时,如果其中的一个本地缓冲区超出限度了,攻击者可能改写堆栈中在此之上的任何东西,包括异常处理、安全cookie、帧指针、返回地址和函数参数。而这些值的大多数被不同的机制所保护(如安全异常处理),但对一个有函数指针作参数的函数来说,仍有机会被溢出。如果一个函数接受一个函数指针(或结构、类中包含有函数指针)作为参数,攻击者就有可能改写指针中的值,使代码执行任何他想要的函数。鉴于此,Visual C++ 2005编译器将分析所有可能存在此漏洞的函数参数,并复制一份函数参数--并不使用原有的函数参数,把它放在堆栈中本地变量之下。如果原有函数参数被溢出改写了,只要副本中的值仍保持不变,整个函数就不会被攻破。

应用缓冲区保护

只需简单地打开/GS编译器开关,就可启用缓冲区保护。在Visual Studio中,此开关可在"C/C++"选项页的"代码生成"选项中找到(如图2所示)。默认情况下,在Debug配置下为关,而在Release配置下为开。

图2:设置/GS开关

如果用最新版本的编译器进行编译,并生成结构化异常信息,那么在默认情况下,安全结构化异常处理将是打开的,另外,也可以使用/SAFESEH:NO命令行选项来关闭安全结构化异常处理,在Visual Studio的工程设置中,是没办法关闭安全结构化异常处理的,但仍可在链接器中使用此命令行选项来完成。

/GS及更远的安全前景

仅仅是打开一个编译器开关,不会使一个程序彻底变得安全,但在安全漏洞以各种形式出现的今天,它将有助于使程序更加安全。基于堆栈的缓冲区溢出是安全漏洞中的一大类,但随着黑客攻击技术的不断更新,相信它的谢幕,还有一段很长的路要走。

在Microsoft正式的术语中,/GS和SAGESEH均为软件强制的数据执行保护(DEP),软件强制的DEP也能以硬件的方式实现,如在实现了此功能的CPU中,如果数据出现在被标记为"不可执行"的内存页中,将不会执行它。Windows XP SP2及Windows Server 2003现在已支持这些技术,目前市面上的大多数的32位CPU及全部的64位CPU,都支持No Execute(NX)这类安全增强技术。

任何一个好的安全系统,均有多层防范措施应对安全威胁。本文所涉及的编译器开关,它能防范或减少普通编码错误所带来的安全隐患,而且它具有易于使用和低成本的特点,在这场没有硝烟的战争中,不失为一个好的解决方案,绝对值得你的程序采用。

本篇文章来源于:开发学院 http://edu.codepub.com   原文链接:http://edu.codepub.com/2008/1217/190.php


相关文章

  • 班级安全活动方案
  • 活动时间:2012年11月10日星期二 活动地点:幼儿园大二班教室 活动目的:1、通过开展“安全教育画展”活动,进一步帮助小朋友树立安全意识,掌握安全知识。 2、提高自我保护和自救能力,养成在日常生活和突发安全事件中正确应对的习惯。 3、小组合作寻找身边的安全隐患,贴上醒目的安全标志。争做安全小卫士 ...

  • 食堂工作安全有哪些
  • 一是液化石油气灶具不能放在卧室、办公室、阳台或仓库、礼堂等公共场所内,以防漏气失火。 二是正确掌握开关的使用方法,要火等气,不要气等火,用毕切记关阀门、开关,阀门坏了要及时更换。不要让儿童使用灶具或随意玩弄开关。 三是使用液化气时,要有人看管,不可远离,随时注意调节火头的大小,防止汤水外溢浇灭焰或被 ...

  • 食堂厨房的消防安全责任书
  • 有效地杜绝安全事故的发生,保障酒店客人及员工生命财产安全;为促进安全生产管理常抓不懈、责任落实到人,按照“谁主管、谁负责;谁使用、谁负责的原则管理日常消防安全生产工作。特制定本消防安全责任书。 1、厨房内的燃气燃油管道、阀门必须定期检查,防止泄漏。如发现燃气燃油泄漏,首先应关闭阀门,及时通风,并严禁 ...

  • 浅谈计算机系统的安全防范
  • 浅谈计算机系统的安全防范随着计算机及网络技术与应用的不断发展,伴随而来的计算机系统安全问题越来越引起人们的关注。计算机系统一旦遭受破坏,将给使用单位造成重大经济损失,并严重影响正常工作的顺利开展。加强计算机系统安全工作,是信息化建设工作的重要工作内容之一。一、计算机系统面临的安全问题目前,广域网应用 ...

  • 用电安全.交通安全.消防安全活动方案
  •   教学目标:   通过学习日常安全知识,使学生树立安全观念,形成自护、自救的意识,使学生安全、健康成长。   教学过程:  一、 谈话引入:   同学们生活在幸福、温暖的家庭里,受到父母和家人的关心、爱护,似乎并不存在什么危险。但是,日常生活中仍然有许多事情需要备加注意和小心对待,否则很容易发生危 ...

  • 5.12防灾减灾讲话稿
  • 亲爱的同学们.老师们: 历史将永远铭记xx年5月12日14时28分地动山摇的发一刻,人类在灾害面前是那么的无助,但从未停止过与自然灾害的抗争,有血的教训,也有成功的经验.另据统计,我国每年大约有一万六千名中小学生非正常死亡,中小学生因安全事故.食物中毒.溺水.自杀等死亡的,平均每天有40多人,也就是 ...

  • 公司管理月份工作总结 
  • 一、 工作概述 主要是根据生产计划对电器车间生产进行组织、安排、管理,以达到按时、按量的完成相关的工作任务。 二、 本月工作内容 保质保量的完成上级安排的各环节的成套协调生产、组装、发货任务。 三、 本月存在的问题 由于电器间各个生产环节的控制因素比较多,且所受定单 市场的影响比较突出,在计划和物料 ...

  • 欧盟植物检疫隔离温室考察技术报告
  • 欧盟植物检疫隔离温室考察技术报告 植物检疫隔离温室是我们此次赴欧盟考察的一个重点,通过对英国农业部中央科学研究院.苏格兰作物研究院.国际园艺中心等研究机构及荷兰温室公司.法国瑞奇公司等大型温室制造企业的考察,我们对欧盟植物检疫隔离温室的设计建造有了全面的了解,现将有关技术内容报告如下: 一.欧盟检疫 ...

  • 机电一体化技术暑期实习报告
  • 实习目的:到公司现场实习是普通高等专科教育中的重要实现教学环节.它对学生掌握基本的理论知识,运用基本知识,训练基本技能,增强实践能力,对达到高等专科教育培养目标的要求有着十分重要的意义和作用.同时,实习在大学中是一个关键环节,对一个理工科学生来说,更是尤为重要.而对于我们即将毕业的学生来说,实习的意

  • 煤矿安全专项整治方案
  • 某某煤矿~年安全专项整治方案 一、指导思想 以党的xx大精神为指导,以《安全生产法》、《煤矿安全规程》等法律、法规为依据,以创建本质安全型企业为主线,坚持管理、培训、装备并重,依法整治,综合治理,强化基础工作,提高生产系统的安全可靠程度,实现安全状况的稳定好转。 二、工作目标 1、消除事故和隐患,实 ...