Secur1ty just lik3 a girl. B0th of th3m h4ve s0me h0les. Y0u alw4ys try to t0uch the h0le, but n0t 3very tim3 y0u c4n 3xpl0it it!
查看文章 |
不可预测性与安全
2009-01-12 17:34
忙里偷闲来写篇blog,时间关系,不能写太具体和发散了。 今天的主题是不可预测性(non-predictable) 这一点往往可以用来防止伪造类的攻击。 为了说明问题,我们先回忆以下的一些场景: Debian ssh key 生成范围可以预测漏洞 2008年出来的漏洞,漏洞描述的记忆有点模糊了,大致是由于Debian上生成ssh key的库与进程数有关(1-65535?),导致生成出来的key在一定的范围内,所以是可以预测的。攻击方法就是生成那么几万个key,然后一个个去尝试连接。 CSRF(跨站点请求伪造) 攻击要求知道对方的url才行,往往是 <img src=http://fvck.com/delete.do?id=123 />类似这种;防御方案一般是加一个系统随机生成的token,比如以上url改为 http://fvck.com/delete.do?id=123&token=AS323ASfdq398jedf11,这样攻击者猜测不到这个token,也就无从发起CSRF攻击。(这里指纯CSRF攻击,混合了跨站的在我这里叫XSRF,不进入考虑) PHP的rand() 函数 再来看看PHP的rand,直接引用manual里的一段描述: On some platforms (such as Windows), getrandmax() is only 32768. If you require a range larger than 32768, specifying min and max will allow you to create a range larger than this, or consider using mt_rand() instead. Linux Classic Stack Buffer Overflow 以前的经典溢出,特别是一些栈溢出,都是直接精确计算地址,然后覆盖了EIP后,指引程序流程直接jmp到shellcode在栈上的地址,这是因为古老linux(包括其他UNIX类OS)的栈基址是不变化的。 现在,不论是linux还是windows都加入了ASLR,让栈基址随机变化,类似的变化还有 stack cookie -- 这个值也是随机的, heap 中也是如此。 内存攻击中在可预测性上的发展 上面刚说了有ASLR等手段来对抗原始的溢出攻击,那么到了现在,发展出了一些更高级的攻击方式。比如 Heap Spray ,因为IE、flash、java等分配的内存堆是在一定范围内的,如果正好在这个内存范围内存在一个可以作为指令执行的地址,而该指令又不会影响到程序,类似NOP,就能成功HEAP Spray。 如果说举这个例子还不够说明问题的话,那么看下面这个例子。 在windows中,TEB的地址经常是随机变化的,不过这个变化的范围往往也是有限的,比如TEB的基址经常在 0x7ffdxxxx 以上变化, 我们就可以采用尝试多次连接的方式,促使多个TEB填满这些地址,从而保证我们在执行shellcode时,能够利用到TEB内的一些东西来做些事情(比如把shellcode放到TEB,或者是其他利用方式)。 ![]() 比较有趣的例子还有一个。在ASLR大行其道的今天,Stack基址的预测也开始出现。因为在Windows上,据说stack的基址也是存在一个变化范围的,如果我们Bruteforce 它,也有可能在数次之后,就能成功溢出。 讲了这么多问题,无非就是为了说明,很多时候,安全都在做这样一件事情:让可预测的东西变得不可预测。 不管是加密算法的加强,还是其他安全方面的架构设计,我们都可以好好的利用这种思想。 比如如下的一种RPC方式: ![]() 这种方式对CSRF本身就是一种有效的防御。 现在很流行的开放平台、开放各类API、JSONP的应用时候,都应该使用这种把远程调用,变得“不可预测”,从而有效抵御“伪造类”的攻击。 吃饭时间到了,下次继续侃。。。。 |
最近读者:



