游客发表
2017年5月12日,漏洞程序英国一名22岁的漏洞程序网络安全研究员马库斯·哈钦斯在推特上发了一句话:“我无意中发现了WannaCry的 kill switch。”当时他正在分析一个可疑样本,漏洞程序随手注册了一个域名,漏洞程序结果这个动作意外阻止了勒索病毒在全球的漏洞程序进一步扩散。一个漏洞,漏洞程序让150个国家的漏洞程序30万台电脑在几小时内瘫痪;一个临时起意的操作,又把损失摁在了几十亿美元的漏洞程序量级上。漏洞程序这东西,漏洞程序从来不是漏洞程序教科书里温顺的代码缺陷,它更像一颗埋在地下的漏洞程序雷,踩上去的漏洞程序人未必是写代码的那个。
很多人以为漏洞是漏洞程序“错误”。不对。漏洞程序漏洞是漏洞程序系统设计时没预料到的路径。程序员写代码,脑子里有一条主路——用户输入账号密码,验证通过,进主页。但代码跑起来之后,还有无数条小路:输入超长字符串会怎样?并发请求一千次会怎样?把参数改成负数会怎样?这些小路里,有一条能绕过验证、拿到权限、执行命令,那就是漏洞。它不是bug,bug是程序崩溃或者算错数;漏洞是程序“太听话”,你让它干什么它就干什么,哪怕你让它把数据库密码打印出来。
我见过一个真实案例。某电商平台的优惠券接口,前端限制每人只能领一张。后端代码写的是:查用户已领数量,如果小于1,就发券。逻辑没问题。但攻击者发现,这个“查”和“发”之间没有加锁。他同时发100个请求,每个请求都查到“已领数量=0”,然后都发了券。结果一个人领了100张。修复方案也简单,加个数据库唯一索引,或者用分布式锁。但没加之前,这个漏洞程序每天被薅走几十万。写代码的人不是不聪明,他只是默认了“用户会一个一个点”。
漏洞程序最麻烦的地方在于,它往往不是一个人写出来的。一个操作系统几千万行代码,一个浏览器几百万行,一个Web框架几十万行。你调用的每一个第三方库,都可能藏着十年前某个人写下的一个越界读取。2014年爆出的Heartbleed,就是OpenSSL里一个边界检查漏了,攻击者可以每次读取服务器内存里64KB的数据,反复读,就能把私钥、密码、会话令牌全捞出来。这个漏洞存在了两年多,无数大公司用的都是同一份代码。一个人写错一行,全世界跟着遭殃。
那怎么办?有人提出“安全左移”,意思是别等上线了再找漏洞,写代码的时候就想着怎么防。这个思路对,但做起来难。业务催着上线,产品经理要功能,老板要速度。安全测试?排期往后放放。结果就是,漏洞程序被压到生产环境里,等出事再打补丁。WannaCry之后,微软破例给已经停止支持的Windows XP发了补丁,但很多医院、工厂的系统根本没法打——一打补丁,配套的医疗设备、工业控制软件就崩。漏洞程序绑着业务,绑着硬件,绑着几十年的遗留系统。不是不想修,是修不动。
我自己的习惯是,看到任何输入框,先想两件事:这里能不能传个单引号?这里能不能传个超长字符串?不是我要攻击谁,是我想知道这个程序有没有在“听我说话”。一个正常的程序应该只接受它想要的,拒绝其他一切。但很多程序太热情了,你说什么都信,给什么都收。这种热情,就是漏洞的温床。
漏洞程序不会消失。只要还有人写代码,只要系统还在变复杂,就一定有没想到的路径。区别只在于,你是等别人来踩,还是自己先走一遍那些小路。马库斯注册那个域名的时候,没想当英雄,他只是顺手试了一下。但那一试,救了很多人的周末。
友情链接