突破GS之理论篇

GS就是一个缓冲区溢出标志,如果发生缓冲区溢出,该标志会被覆盖,导致其值和其在.data区域的备份值不同,由此系统进入异常处理流程,函数不会正常返回,ret指令也不会执行。

以下情况VS不会开启GS:

  • 函数不包含缓冲区
  • 函数被定义为具有变量参数列表
  • 函数使用无保护的关键字标记
  • 函数在第一个语句中包含内嵌汇编代码
  • 缓冲区不是8字节类型且大小不大于4字节

开GS和不开GS的对比(此处均关闭了代码优化,防止变量位置被编译器调整):

#include "string.h"

#pragma strict_gs_check(on)  //此程序没有4字节以上的缓冲区,故函数不受GS保护,除非使用此句强制开启

int vulfunction(char* str){
	char arr[4];
	strcpy(arr,str);

	return 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
	char *str="yeah,i'm a guy.";
	vulfunction(str);
	printf("hellworld");
	return 0;
}

以下是突破GS的几种策略:

  1. 专门攻击没有GS保护的函数 - -||
  2. 溢出覆盖虚表指针,将程序要调用的虚函数地址替换为我们的shellcode地址

    利用覆盖虚表指针来突破GS的可行原因是:this_ptr存放在[ebp-0C]处,而cookie存放在[ebp-4]处,所以溢出会先覆盖this_ptr;恰好函数返回前(gs检查前)调用了虚函数,所以可以通过只篡改虚表指针达到调用shellcode、且gs保护丝毫不会察觉的效果
  3. 攻击异常处理机制
    溢出覆盖S.E.H中的异常处理函数地址,当发生异常时,就可以直接跳转执行!
  4. 同时替换栈中cookie和.data区域的备份
    在堆中申请数组空间,通过数组越界篡改.data区域的cookie备份,而栈中用到的cookie又是从.data区取的,所以此突破方式简直神不知鬼不觉啊。。。不过不同环境下,.data区的cookie位置可能有所不同。。。同时要注意cookie不是直接存于栈区、直接和备份进行比对的,参见上图中的cookie装载、cookie检测过程
posted @ 2017-10-07 17:28  T_1  阅读(240)  评论(0编辑  收藏  举报