一个过旧版本有安全漏洞
去年冬天,个过我帮一个做外贸的旧版朋友处理服务器。他的安全网站跑在一台老旧的Linux机器上,内核版本是漏洞2.6.32——2009年发布的。我问他为什么不升级,个过他说“一直没出过事,旧版懒得动”。安全结果三天后,漏洞网站被挂马,个过首页被替换成一张俄语勒索信。旧版攻击者利用的安全正是那个内核里一个2016年就公开的提权漏洞。补丁早就有了,漏洞他没打。个过 这种事不是旧版孤例。很多系统管理员对“旧版本”有种奇怪的安全信任感。机器跑得好好的,网站能打开,数据库能连上,那就别碰。这种心态可以理解,但代价往往是事后追悔。旧版本本身不是问题,问题是旧版本里那些已经被公开、被写进漏洞库、被自动化扫描工具盯上的安全缺陷。攻击者不需要多高明,他们只需要一个脚本,扫全网,找到没打补丁的机器,然后进去。 拿OpenSSL来说。2014年爆出的“心脏出血”漏洞,影响的是1.0.1到1.0.1f版本。这个漏洞允许攻击者从服务器内存里读取最多64KB的数据——可能是私钥,可能是用户密码,可能是会话令牌。当时全球大约有五十万台服务器受影响。修复方法很简单:升级到1.0.1g。但直到2015年,还有大量服务器跑着受影响的版本。为什么?因为升级意味着重启服务,意味着可能出问题,意味着要加班。而“可能被攻击”在很多人眼里只是个概率。 更麻烦的是,有些旧版本漏洞不是“可能被攻击”,而是“一定会被攻击”。比如Apache Struts 2的某个版本,2017年爆出远程代码执行漏洞。这个漏洞的利用代码在公开后几小时内就出现在各种渗透工具里。任何还跑着那个版本的服务器,只要暴露在公网上,基本等于敞着大门。Equifax那次泄露,1.43亿人的数据被偷,起因就是没及时升级Struts。事后调查发现,漏洞公告发布后,他们内部其实收到了通知,但补丁没打上去。两个月后,攻击者来了。 有人会说:我的系统在内网,不暴露公网,旧点没关系。这个逻辑有个漏洞——内网不是保险箱。攻击者一旦通过钓鱼邮件或者U盘进入内网,第一件事就是找那些没打补丁的旧机器做跳板。内网里跑着旧版SMB协议的Windows机器,跑着旧版SSH的Linux服务器,都是横向移动的绝佳节点。2017年的“永恒之蓝”勒索病毒,就是利用Windows SMB漏洞在内网里快速扩散。很多中招的机器其实不直接连外网,但它们所在的网络里有一台连外网的机器中了招,然后整个内网就沦陷了。 升级这件事,技术上不难。难的是决策。一个跑了五年的生产系统,升级可能意味着依赖库不兼容、配置文件要改、测试要重做。这些成本是看得见的。而漏洞被利用的风险,在没出事之前,是看不见的。人天生对看不见的风险不敏感。但攻击者不关心你的成本。他们只关心你的版本号。 我自己的习惯是:任何暴露在公网的服务,版本号必须在官方支持期内。不在支持期内的,要么升级,要么下线。没有第三种选择。内网服务可以稍微宽松,但关键补丁必须打。这不是技术洁癖,是基本生存策略。你不需要比所有攻击者都聪明,你只需要比那些懒得升级的人稍微勤快一点。攻击者也是要算成本的,他们会优先挑软柿子捏。你只要不是那个最软的,大部分自动化攻击就会绕过你。 那个外贸朋友后来换了新服务器,装了最新版系统,配了自动更新。他跟我说:“早知道这么简单,当初折腾什么。”我没接话。很多人都是这样,直到被现实按在地上摩擦一次,才愿意动。问题是,有些摩擦的代价,一次就够你受的。