2014年9月24日,洞可得知GNU Bash被爆出一个叫Shellshock的洞可得知漏洞,编号CVE-2014-6271。洞可得知攻击者只要构造一段特殊的洞可得知环境变量,就能让Bash执行任意代码。洞可得知这条路径不需要认证,洞可得知不需要用户交互,洞可得知远程就能打。洞可得知当时全球大约有5亿台服务器、洞可得知路由器、洞可得知IoT设备跑着Bash,洞可得知互联网上超过一半的洞可得知Web服务器用CGI调用Bash处理请求。一个漏洞,洞可得知直接把这些数字变成了攻击面。洞可得知
事情的洞可得知本质其实很朴素。Bash在处理函数定义的环境变量时,没有正确截断尾部追加的命令。比如你设置env x='() { :;}; echo vulnerable' bash -c "echo test",Bash会先执行函数定义,然后顺手把echo vulnerable也跑了。这个设计缺陷藏在代码里至少二十年,没人注意到,因为它看起来只是“函数导出”的一个边缘行为。
我第一次看到这个漏洞的PoC时,反应是:这也太简单了。没有堆溢出,没有复杂的ROP链,就是拼一个字符串。可正是这种简单让它致命。利用门槛低到脚本小子都能写,而影响面大到从数据中心到你家路由器。那几天运维圈的状态可以用一个词形容:鸡飞狗跳。打补丁、临时WAF规则、排查暴露面,很多人通宵没睡。
从这件事能看出几个东西。第一,基础设施的脆弱性往往不在最显眼的地方。大家盯着OpenSSL,结果Bash炸了。第二,代码的“历史遗留”不是技术债那么简单,它可能是安全债,而且是复利计算的。第三,开源软件被广泛依赖,但维护者的精力和资源严重不匹配。Bash的作者Chet Ramey一个人维护了这么多年,漏洞曝光后他连夜发补丁,这种模式本身就值得反思。
还有一个细节我印象很深。Shellshock曝光后,很多厂商的响应速度差异巨大。有的几小时内推了补丁,有的拖了一周还在“评估中”。这不是技术能力问题,是流程问题。安全响应不是写代码,是组织能力。你平时有没有预案,有没有人能拍板,有没有测试环境快速验证,这些在危机时刻全暴露出来。
再说回攻击面。Shellshock之后,我养成了一个习惯:每次看到CGI、看到环境变量传递、看到系统调用Bash的地方,都会多看一眼。不是 paranoid,是知道这类接口天然容易出问题。环境变量本来就是给进程传配置的,结果被当成代码执行通道,这个设计意图和实际行为的偏差,就是漏洞的温床。
最后说个具体的。当时有个朋友在一家电商公司做运维,他们内部有个老系统用CGI跑Bash脚本处理订单回调。漏洞爆出来那天,他查了一圈发现这个系统还在线上,而且直接暴露在公网。他连夜加了规则拦截,第二天申请重构。后来他跟我说,如果没有Shellshock,这个系统可能还会再跑五年。有时候一个漏洞的价值不是它本身,而是它逼你去看那些你一直忽略的东西。
Bash漏洞不是第一个,也不会是最后一个。但它提醒了一件事:安全不是加一层防护就完事,而是你得知道你的系统到底在跑什么、怎么跑的、谁在维护。这些问题的答案,往往比漏洞本身更让人不安。