3.5 选择在不同的维度做防御
攻击的方法千千万万,封堵同一个安全风险的防御方法往往不止一种,如何选择性价比最高的手段是甲方安全从业者需要权衡的。
1. 技术实现维度场景
在纵深防御的概念中(参考后面的“技术篇”)企业安全架构是层层设防,层层过滤的,常见漏洞如果要利用成功需要突破几层限制,所以退一步对防御者而言有选择在某一层或某几层去设防和封堵的便利,比如SQL注入,治本的方法当然是代码写对,治标的方法WAF过滤,中间的方法SQL层过滤,从效果上说治本的方法固然最好,但在现实中总归会遇到各种各样的问题而无法全部选择最安全的解,最后是退而求其次,还是选择某一层或者某几层去防御,需要整体考虑。比如SQL注入如果在HTTP层面去解决无论是静态规则还是机器学习都需要对抗HTTP编码的问题,不是解决这个问题ROI最佳的点,但是在SQL层面,一切SQL语句都是真实的。现实生活中唯一的问题只是你能不能在最佳的点上推动解决方案。
2. “一题多解”的场景
假如同一个问题有>1种解决方案,可能会因场景不同而面临选择。比如对于SSH蠕虫的暴力破解,你可以选择:1)使用证书;2)选择外部防火墙上关闭22端口,只通过堡垒机登录;3)修改SSHD监听非标准端口;4)修改sshd源代码对源限制,只接受可信的客户端地址;5)使用类似fail2ban这样的工具或自己写shell脚本,或者所谓的HIPS的功能。乍一看有的做法比较小众,有的则属于偏执狂式的。1),2),5)属于大多数人都认同的普遍的做法,4)和5)看上去都比较小众,有的人认为可能不适合用作生产网络,其实要看场景。对于大型互联网公司内部自用而言:4)和5)其实都成立,尽管偏离了业界标准,但只要在公司内部的自治生态里做到“一刀切”就可以,业界普遍是SSHD跑在22端口,你可以让公司内部的都跑在50022端口,只要公司内部的服务器全都维持这个统一策略,但是这个方案价值不大的地方在于这种信息不对称很容易被打破,你花了那么大力气让运维们都去连50022端口了,但攻击方很快就能知道,然后努力就白费了。而对于开源软件的修改,如果基础架构研发比较强大,Linux、Nginx、SSHD、MySQL这些全都可以是改过的私房菜,加点有意义的安全功能也未尝不可。不过中小型公司不需要考虑这一点,自研毕竟是有门槛和成本的。假如场景切换到公有云给租户用的环境,这样干就不合适了,你还是应该提供跟业界兼容的标准运维环境,在标准运维环境之上提供额外的保护。
3. 跨时间轴的场景
对于涉及跨时间维度的防护,典型的场景包括shellshock这样的漏洞公布时,各厂商在第一时间分析漏洞评估影响,这种影响是多层面的,不只是说可能拿到什么权限,还包括影响线上系统的哪些组件,这些组件的实时在线要求,修复漏洞会不会导致关联服务不可用。每一个漏洞修复的过程都是攻防双方和时间赛跑,攻击者尽量在厂商没有修复之前寻找利用点并发动渗透,而厂商尽可能在没出POC时赶紧把洞补了。在这个时间窗口中,甲方安全团队需要考虑的就是跨时间维度上的布防。出补丁之前是不是就干等不作为呢,显然不是的,细心的人会发现老牌安全公司的漏洞通告的解决方案里通常都会有一条,叫作“临时规避措施”,经验不足的团队是不会写上这条的。修不了漏洞时可以采用一些治标的补救性措施,比如对有漏洞的页面做访问控制,只允许有限的src.ip访问,比如在前端的WAF/IPS设备上加规则过滤对应的恶意请求,或者临时性的去掉一些权限,或者干脆关掉某些功能,但凡你想得到的通常总能找到临时规避方案,即便是有了补丁升级也不是立即完成的,在大型互联网生产网络里,全网打完一个补丁是需要不少时间的,有可能一个礼拜都弄不完,而且修复过程中要考虑服务可用性需要使用灰度和滚动升级的方法,比如修复前先把负载均衡上的流量切换到备用节点,然后对坐节点的服务器打补丁,打完再把流量切回去,然后对备用节点的服务器打补丁……打完补丁后把临时防御措施再“回滚”掉(有价值的保留,核心设备上不建议留太多臃肿的规则),然后把特征加入全流量和主机IDS。回顾整个时间轴的防护措施依次是:临时性规避措施—push补丁/根治措施—取消临时性措施—添加常态性的特征检测措施—检测到漏网之鱼—继续上述过程,这个过程离最佳实践实际上还差了一个环节,不过这里只是用来说明开头提到的那个问题故而不展开了,后面会介绍对于一个漏洞修复是否需要上升层次的问题。
4. 风险和影响的平衡
假如你遇到一个安全问题是这样的:vlan数目不够,vxlan又不可用,提交问题后研发的反馈的方案A是如果要彻底修复则需要新增一个dhcpd的安全功能大约包含10000(loc)即1万行代码,此时产品线又处于整体加班加点赶工大版本的状态,有人提出了方案B做IP/MAC双向绑定的缓解性措施,但这样的结果很可能是客户觉得太麻烦,而且配置一多容易出错,此时你想到了一个折中的办法 方案C:给大客户单独vlan,若干小客户共享一个vlan,这样的好处是不需要太多成本,风险降低到可控,客户可以接受。如果选择方案A是不是更好?这个要看,假如这1万行代码只是用来临时的解决这个问题,显然ROI比较低,但是如果后续的版本本来就要加入这个功能,不妨考虑一下。又如果后续版本不需要这个小众的功能,研发心里其实本不打算去开发的,说不定下次告诉你说要2万行代码,然后你到CTO那里也说不清风险到底多么严重,就会陷入僵局。风险缓解的原则是在以下三者之间做最大平衡:1)风险暴露程度;2)研发运维变更成本;3)用户体验的负面影响。
5. 修复成本的折中
一个安全漏洞的修复如果研发说要开发一周,另外一个方案是运维改一个服务器配置,而你其实心里知道在WAF上加条规则就能过滤,只不过你怕被绕过心里对这个措施不是特别有底气。对于这个场景我也不打算直接给出答案,但通常情况下改产品的成本是最高的,成本最高的往往不容易推动,推不动就无法落地,最后就是一堆安全问题。
Amazon有一个研发理论,用一种T-Shirt Size 估计的方式来做项目。产品经理会对每一条需求评估上业务影响力的尺寸,如:XXXL 影响一千万人以上或是可以占到上亿美金的市场,XXL影响百万用户或是占了千万金级别以上的市场,后面还有XL、L、M、S,这样逐级减小。开发团队也一样,要评估投入的人员时间成本,XXXL表示要干1年,XXL干半年,XL干3个月,L干两个月,M干一个月,S干两周以下。等等。
于是,可以这样推理:
当业务影响力是XL,时间人员成本是S,这是最高优先级。
当业务影响力是M,时间人员成本是M,这是低优先级。
当业务影响力是S,时间人员成本是XL,直接砍掉这个需求。因为是亏的。
当业务影响力是XXL,时间人员成本是XXL,需要简化需求,把需求简化成XL,时间人员成本变成M以下。
安全其实也类似,风险和修复成本去比较,在坚守底线的基础上选择最优解。
综上所述,大家可以发现最优解往往不一定是最安全的解,市场上乙方公司渗透测试报告中提的修复方案有些也是无法实施的,很多批判企业安全做得不好的帽子们,有机会真应该到企业里体验一下,企业安全岂是找洞补洞这么简单的事。
参考资料
陈皓的“加班与效率”(http://coolshell.cn/articles/10217.html#more-10217)。