栈溢出笔记1.12 栈Cookie

栈Cookie,也叫安全Cookie。我们先来看一看栈Cookie的实现机制,使用的程序为1.2节中的example_2,重点在函数get_print()部分。还记得在1.2节中我们为了演示栈溢出,去掉了编译设置中的“缓冲区安全检查(GS)”选项,我们先看看未启用该选项时的get_print()函数代码:
这里写图片描述
图78 未启用GS的get_print()函数代码

然后,启用该选项,看启用该选项之后的get_print()函数代码:
这里写图片描述
图79 启用GS的get_print()函数代码

函数开头部分和结尾部分多了上面标注的几行代码,结尾还多了一个函数调用。先看看开头多出来的三行代码:

/*****************************************************************************/
MOV     EAX,DWORD PTR DS:[416000]
XOR     EAX,EBP
MOV DWORD PTR SS:[EBP-4],EAX
/*****************************************************************************/

这三行代码的操作是从取数据段0x416000处的值,然后与当前的EBP进行异或操作,并将结果保存到栈中EBP-4的位置,回想1.1中的图,EBP-4的位置应该就是保存的EBP上面的那个(即紧邻EBP)。也就是说,这段代码往保存的EBP和局部变量区中间插入了一个值,现在栈变成了这个样子:
这里写图片描述
图80 加Cookie之后的栈

接下来看结尾多出来的三行代码:

/*****************************************************************************/
MOV     ECX,DWORD PTR SS:[EBP-4]
XOR     ECX,EBP
CALL    example_.00411014
/*****************************************************************************/

操作是将保存的Cookie值取处到ECX,然后再与当前EBP异或,然后调用example_.00411014函数。这是做什么呢?EBP是没有变化的,因此,若保存的Cookie值也没有变化,则与EBP异或将为原值(即从DS:[416000]取出来的值)。所以,example_.00411014应该是一个检查Cookie是否发生变化的函数,通过ECX的值来判断Cookie值是否被修改,从而做一些操作。

究竟是做什么操作,我们不再往下跟,但从1.2节中程序的表现来看,应该是引发了一个异常。
这就是Cookie的工作原理了,在栈上的局部变量区和保存的返回地址(EIP)之间保存一个值,如果发生了栈溢出,则该值会被修改,从而验证不通过,引发栈溢出异常。这个Cookie是通过保存于数据段中的一个值与EBP异或得到的。

下面,我们在开启了GS时的栈中看一看该Cookie值(输入10个A,不超过缓冲区大小):
这里写图片描述
图81 Cookie值

这就是位于EBP和局部变量之间的Cookie值。

我们重启程序再来看一看:
这里写图片描述
图82 Cookie值

它的值变了!这说明DS:[416000]处的值是一个随机值,每次运行程序都不同。这样,使得Cookie值难以预测。但好消息是,它的位置是固定的。因此,Cookie的作用相当明确,就是保护下面的返回地址不被修改。

启用了栈Cookie之后,会进行Cookie值的检查,因此,绕过的方法之一,就是绕过检查的步骤。这种方法实际上我们前面已经用到了,由于栈Cookie检查在函数最后,因此提前引起一次异常,利用SEH就可以绕过Cookie的检查。当然,依据具体的程序,还有很多其它的方式,具体请看这篇专门讲栈Cookie的文章:Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft Windows 2003 Server, David Litchfield。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值