2010年6月,全软Stuxnet蠕虫被白俄罗斯安全公司VirusBlokAda发现时,洞分没人意识到它已经在中东某核设施里悄悄运转了一年多。析技四个0day漏洞同时嵌入一个恶意软件——这个数字本身就说明问题:攻击者手里的全软牌远比你想象的多。
0day,洞分指的析技是厂商尚未发布补丁的漏洞。从发现到修补之间的全软时间窗口,就是洞分攻击者的黄金期。这个窗口有多长?析技没有定数。有些漏洞从被发现到补丁发布只要几小时,全软有些拖了几年。洞分Stuxnet用的析技那四个Windows漏洞,有三个在被发现时微软完全不知情。全软
漏洞从哪来
软件是洞分人写的,人就会犯错。析技缓冲区溢出是最经典的类别:程序往一个固定大小的内存区域写入超出容量的数据,覆盖掉相邻的内存空间。攻击者精心构造这段溢出数据,就能劫持程序执行流程,让它去运行攻击者指定的代码。
看一段简化过的C代码:
void copy_input(char *input) { char buf[64]; strcpy(buf, input); } 如果input超过64字节,buf就被撑爆了。栈上的返回地址被覆盖,函数返回时就会跳转到攻击者控制的地址。这类漏洞在2000年代遍地都是,微软的MS08-067(Conficker蠕虫利用的那个)就是典型。
另一大类是释放后重用(Use-After-Free)。程序释放了一块内存,但没有清空指向它的指针,之后又通过这个悬空指针访问该内存。攻击者可以在内存被释放后迅速占用同一块空间,填入恶意数据。浏览器是UAF的重灾区,Chrome和IE都因此吃过不少亏。
怎么找到0day
Fuzzing(模糊测试)是目前最主流的自动化挖掘手段。原理粗暴:往程序里灌大量随机或半随机的数据,看它会不会崩溃。崩溃往往意味着内存损坏,而内存损坏大概率可以被利用。
AFL(American Fuzzy Lop)是这方面最出名的工具之一。它用遗传算法优化输入样本,覆盖率高的输入会被保留并变异,逐步逼近触发漏洞的那条路径。2010年代中期,AFL帮安全研究者挖出了大量真实漏洞,包括OpenSSL、ImageMagick这些基础库。
但Fuzzing不是万能的。它依赖覆盖率反馈,对逻辑漏洞几乎无能为力。比如一个支付系统允许负数金额转账,这种问题不会导致崩溃,Fuzzer根本发现不了。所以人工审计仍然不可替代,尤其是在协议实现和业务逻辑层面。
利用链的搭建
找到漏洞只是第一步。现代系统有ASLR(地址空间随机化)、DEP(数据执行保护)、CFG(控制流保护)层层设防。一个孤立的漏洞往往不足以完成攻击,需要把多个漏洞串成利用链。
典型的链条是这样的:先用一个信息泄露漏洞绕过ASLR拿到模块基址,再用一个UAF漏洞控制指令指针,最后用ROP(面向返回编程)技术绕过DEP执行任意代码。每一步都需要精确的内存布局控制,偏移差一个字节就可能全盘失败。
这也是为什么浏览器漏洞的利用代码能卖到几十万甚至上百万美元。不是漏洞本身值钱,是完整的利用链值钱。
防守方的困境
补丁管理永远滞后。企业环境里,一个补丁从发布到全网部署,几个月是常态。工控系统更夸张,很多设备根本不允许随便打补丁,停机成本太高。攻击者清楚这一点,所以老旧漏洞依然活跃。WannaCry用的EternalBlue,补丁在漏洞公开前三个月就发了,照样感染了20万台设备。
0day不会消失。只要软件还在写,只要代码还有内存操作,这个游戏就会继续。攻防之间的差距,很多时候不在于技术,在于谁更快、谁更耐心。