栈溢出防御之——Windows安全机制GS编译选项

2024-02-05 19:58

本文主要是介绍栈溢出防御之——Windows安全机制GS编译选项,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

安全漏洞中有个重灾区:栈溢出。利用类似memset之类的字符串修改函数,输入超出正常长度的字符串,导致栈溢出,从而影响其它数据(返回地址、标志变量等)。

维基百科给出的资料http://zh.wikipedia.org/wiki/%E5%A0%86%E6%A0%88%E6%BA%A2%E5%87%BA主要是函数无限调用导致的堆栈溢出,下面给出个0day2里面的例子温习下栈溢出:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #define PASSWORD "1234567"  
  3. int verify_password (char *password)  
  4. {  
  5.     int authenticated;  
  6.     char buffer[8];  
  7.     authenticated=strcmp(password,PASSWORD);  
  8.     strcpy(buffer,password);//over flowed here!   
  9.     return authenticated;  
  10. }  
  11. main()  
  12. {  
  13.     int valid_flag=0;  
  14.     char password[1024];  
  15.     FILE * fp;  
  16.     if(!(fp=fopen("password.txt","rw+")))  
  17.     {  
  18.         exit(0);  
  19.     }  
  20.     fscanf(fp,"%s",password);  
  21.     valid_flag = verify_password(password);  
  22.     if(valid_flag)  
  23.     {  
  24.         printf("incorrect password!\n");  
  25.     }  
  26.     else  
  27.     {  
  28.         printf("Congratulation! You have passed the verification!\n");  
  29.     }  
  30.     fclose(fp);  
  31. }  
(用VC6编译吧,别选上了GS)

编译运行后会发现任何99999999等大于1234567的八位数字字符串都可以通过验证,这是什么原因呢。很简单,首先要了解栈结构,大概说下authenticated栈中位置在buffer字符串后面,而输入8个字符导致最后一个NULL字符串结束标志就覆盖了authenticated的前1个byte(小端规则,这也是为什么要大于1234567,否则覆盖后authenticated是00FFFFFF,而不是00000000),从而认证成功。(authenticated由01000000被覆盖为00000000)

面对这个重灾区,Windows在VS 7.0(Visual Studio 2003)及以后版本的Visual Studio中默认启动了一个安全编译选项——GS(针对缓冲区溢出时覆盖函数返回地址这一特征),来增加栈溢出的难度。(很明显,对没有重新编译的软件来说,得不到保护,仍旧有这种安全漏洞。)


GS编译选项为每个函数调用增加了一些额外的数据和操作,用以检查栈中的溢出:

1、在所有函数调用发生时,向栈帧内压入一个额外的随机DWORD,这个随机数被称为canary(想把栈帧数据当成金丝雀般用笼子圈起来),如果用IDA反汇编的话,会看看到IDA会将这个随机数标志为Security Cookie。

2、Security Cookie位于EBP之前,系统还将在.data的内存区域中存放一个Security Cookie的副本,从而进行校验;

3、当栈中发生溢出时,Security Cookie将被首先淹没,之后才是EBP和返回地址;

4、在函数返回之前,系统将会执行一个额外的安全验证操作,被称作Security Check;

5、在Security Check的过程中,系统将比较栈帧中原先存放的Security Cookie和.data中副本的值,如果两者不吻合,说明栈中的Security Cookie已经被破坏了,即栈中发生了溢出;

6、当检测到栈中发生溢出时,系统将进入异常处理流程,函数不会被正常返回,ret指令也不会被执行。

但是额外的数据和操作带来的直接后果就是系统性能的下降,为了将对性能的影响降到最小,编译器在编译程序的时候并不是对所有的函数都应用GS,一下情况不会应用GS:

1、函数不包含缓冲区;

2、函数被定义为加油变脸参数列表;

3、函数使用无保护的关键字标记;

4、函数在第一个语句中包含内嵌汇编代码;

5、缓冲区不是8字节类型而且大小不大于4个字节。

(有了例外,就有利用相对特性的GS突破。)


除了在返回地址钱添加Security Cookie外,在Visual Studio 2005及后续版本还使用了变量重排技术,在编译时根据局部变量的类型对变量在栈帧中的位置进行调整,将字符串变量移动到栈帧的高地址。这样可以防止该字符串溢出时破坏其他的局部变量。同时还会降指针参数和字符串参数复制到内存中的低地址,防止函数参数被破坏。


GS的Security Cookie产生的一些细节:

1、系统以.data节第一个双字作为Cookie的种子,或者原始Cookie(所欲函数的Cookie都用这个DWORD生成)

2、在程序每次运行时Cookie的种子都不用,因此种子加油很强的随机性;

3、在栈帧初始化以后系统用EBP异或种子,作为当前函数的Cookie,以此作为不同函数之间的区别,并增加Cookie的随机性;

4、在函数返回时前,用EBP还原出(异或)Cookie的种子。


突破方法:

1、利用未被保护的内存突破GS。为了将GS对性能的影响降到最小,并不是所有的函数都会被保护,所有就可以利用其中一些未被保护的函数绕过GS的保护;

2、基于改写函数指针的攻击,如C++虚函数攻击;

3、针对异常处理机制的攻击;

4、堆溢出没有保护。

这篇关于栈溢出防御之——Windows安全机制GS编译选项的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/681999

相关文章

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(

Spring使用@Retryable实现自动重试机制

《Spring使用@Retryable实现自动重试机制》在微服务架构中,服务之间的调用可能会因为一些暂时性的错误而失败,例如网络波动、数据库连接超时或第三方服务不可用等,在本文中,我们将介绍如何在Sp... 目录引言1. 什么是 @Retryable?2. 如何在 Spring 中使用 @Retryable

windows端python版本管理工具pyenv-win安装使用

《windows端python版本管理工具pyenv-win安装使用》:本文主要介绍如何通过git方式下载和配置pyenv-win,包括下载、克隆仓库、配置环境变量等步骤,同时还详细介绍了如何使用... 目录pyenv-win 下载配置环境变量使用 pyenv-win 管理 python 版本一、安装 和

Python使用pysmb库访问Windows共享文件夹的详细教程

《Python使用pysmb库访问Windows共享文件夹的详细教程》本教程旨在帮助您使用pysmb库,通过SMB(ServerMessageBlock)协议,轻松连接到Windows共享文件夹,并列... 目录前置条件步骤一:导入必要的模块步骤二:配置连接参数步骤三:实例化SMB连接对象并尝试连接步骤四:

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

客户案例:安全海外中继助力知名家电企业化解海外通邮困境

1、客户背景 广东格兰仕集团有限公司(以下简称“格兰仕”),成立于1978年,是中国家电行业的领军企业之一。作为全球最大的微波炉生产基地,格兰仕拥有多项国际领先的家电制造技术,连续多年位列中国家电出口前列。格兰仕不仅注重业务的全球拓展,更重视业务流程的高效与顺畅,以确保在国际舞台上的竞争力。 2、需求痛点 随着格兰仕全球化战略的深入实施,其海外业务快速增长,电子邮件成为了关键的沟通工具。

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民,网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席2024年国家网络安全宣传周开幕式和主论坛,并将通过线下宣讲、创意科普、成果展示等多种形式,让广大民众看得懂、记得住安全知识,同时还

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO