共计 7130 个字符,预计需要花费 18 分钟才能阅读完成。
在实际工作中,最难防的就是接近应用层的攻击。比如针对直播私有协议的机器人,冲击你的频道服务、登陆服务、支付服务等等,量大了也会变成 DDoS 攻击。
越接近应用层,防御和对抗难度越大、挑战越大,误伤越大。这需要结合大数据、机器学习、业务流量模型等知识来进行综合应对,很复杂。偏底层则相对简单,有比较成熟的技术方案,越往应用层越复杂,自然人和机器人的攻击行为和正常行为就越难区分。
以上是给 DDoS 做一个补充。我们很难做的就是业务层的 DDoS,比如私有协议、YY 协议,还有我们的音频、视频协议。如果真有大量的冲击,比如你只能支撑两千万的 PCU,如果超过两千万,你怎么防御?所以需要柔性可活的思路。
本文是来自于我在欢聚时代实际工作中的实践,将分成以下 3 部分来讲解:
每个互联网公司或者每个公司后台用的服务器都不太一样,在 YY 这种主营业务是纯互联网的公司,Linux 服务器占比很高,全网几万台服务器,Windows 只有几百台,剩下都是 Linux,越是互联网公司用 Linux 的比例越高。
我早年毕业的时候在华为网络安全部,当时 Linux 还不是主流,那时使用的是其他系统,比如 Hp-Unix,Aix 等,当时的使用率并没有这么普遍。随着互联网业务和开源技术的飞速发展,Linux 越来越普及了,为什么?
有一个重要原因就是 Linux 上面的开源应用非常多,包括技术框架,业务选型的技术框架等等,现在基于 Linux 的应用越来越多,导致 Linux 操作系统在整个服务器领域的应用越来越广。
当然,这么多的应用在 Linux 操作系统上使用,带来的安全问题也越来越多,下面列出的是给安全人员带来巨大挑战的漏洞们:
- Struts2 远程代码执行漏洞通告 (CVE-2017-5638)
- Linux 内核提权漏洞 (Dirty Cow) (CVE-2016-5195)
- ElasticSearch 远程执行代码安全漏洞 (CVE-2014-3120)
- Bash 远程执行命令漏洞 (Bash 破壳) (CVE-2014-6271)
- Nginx 远程执行代码安全漏洞 (CVE-2014-0088)
- MongoDB 匿名登录漏洞
- 心脏流血漏洞
著名的 Struts2,我印象中这几年闹了几拨,每拨都有几百人升级业务、修复补丁,几乎都要求 24 小时内修复。我们曾经有一个很重要的业务修复 Struts2 的时候,业务不兼容,版本不能上线,最后老大们决定暂停业务,直到修复为止,这说明这些漏洞给整个平台带来影响很大。
Dirty cow 漏洞也很出名,在这边很多服务器也会中招,是在 2016 年非常出名的提权漏洞,还有 elastic search 的漏洞等等很多这样的漏洞。
2016 年比较火的 DDoS 勒索,这个业务天天 DDoS 打你,那个业务,天天 DDoS 打你,直到给“保护费”为止,有的业务一天给 500,有的业务甚至一天给 2000……
看来黑产也是“讲理”的 MongoDB 的勒索也是很火的,几乎每种事件都可以造成勒索,这就是 Linux 下的安全形势。
很多搞安全的人接触比较多,比较熟悉的漏洞是心脏流血,还有这个著名的 Dirty cow 提权,本质是 Linux 的内存的写权限管理 bug,导致不具有写权限的进程写入权限。
2016 年年底出名的事件,我们国家浙江一个厂商躺枪了。这种案例很多,僵尸物联网“肉鸡”把半个美国都打瘫痪了。
业务版本快速迭代、业务开放、网络边界复杂、开源组件多元化、技术架构复杂、标准化和规范化缺乏等等,这些都是挑战。
前面介绍了 Linux 的开源组件用得比较多,同时在 Server 端用得比较广。这边总结了为什么 Linux 下的安全挑战比较多,可能和传统制造业有些区别。
对于互联网公司来说业务版本迭代很快,要有很好的安全防御的理解。比如认证机制要设计好,鉴权机制要完善,其实设计完善是不容易的。往往老板的指标是一周上线,想设计好并没有那么多的时间。业务迭代版本过于频繁也给安全带来很大的挑战。
互联网业务本来就很开放,像以前在华为有明显的网络边界,内部都是内网,网络边界很明显。互联网业务本来就是对外,所以这就造成了业务整个边界外延,整个都是开放的。机房几十上百个,整个网络都是对外开放状态。
网络边界的复杂,互联网讲求分布式部署、高可用,一般 5 个点、10 个点、20 个点。分布式部署带来网络边界过于复杂,交叉认证。
开源组件多元化,开源组件很多,五花八门,例如缓存中间件,这个哥们儿用这个架构,另一个用那个架构,一个公司有十几个架构。如果在你公司没有达到一定高度的时候,标准化、规范化没有很完善的情况下,就更加复杂,挑战更大。
同样业务端也很复杂,很多还有 Windows 端、移动端、Web 端,各种各样的业务。今天这个功能上线,明天那个功能下线,所以技术架构是一点点积累,想做很标准的技术架构也不容易。
由于前面的版本迭代、网络边界等,带来标准化、规范化都是滞后的,像 BAT 可能做得好一点,但多数公司的标准化、规范化还是不太健全。
上图展示的都是 Linux 安全挑战真实的案例,都是实实在在的工作中遇到的安全问题。
对于普通运维团队或者安全团队可能都比较常见的,像服务器资源被占用,但是不知道是哪个进程占用;发现某个进程占用资源,但是却杀不死,或者杀死一会儿又启动,因为它有守护或者自动拉起。还有密钥泄露,这个很常见。
有些人把密钥放在邮箱或者服务器什么地方存着,如果他的办公机被入侵,他的邮箱被撞破,他的密钥就泄露了。密钥泄露不是最惨的,而是密钥的密码和他的邮箱密码或者是跟他什么 CSDN 的密码用同一个,这个更惨。
大家说这是小概率事件,但是一千人,千分之一的概率发生就入侵了。还有业务被挂马,这是 Web 业务中很常见的;还有 Redis 缓存突然失效,导致 MySQL 扛不住,整个业务直接瘫痪,而且扩容不了,我只是说有这种可能性。
如果你的业务使用 Redis 缓存,而且 Redis 是默认匿名,如果真的有人做 APT 研究你们,把你的 Redis 都干掉了,业务就瘫痪了,大公司可能很长时间都恢复不起来。
操作系统 OOM,很多人说服务器怎么又 OOM?前两天才刚重装,为什么又 OOM?因为有一个木马不断提权,一提权就崩,所以肯定有 OOM,这也是实际过程中的一个案例。
做防御首先要了解进攻的方式。这是一个真实的案例,了解攻防的人可以看到,这是典型的 Linux 匿名,Redis 默认匿名登陆,不需要用户名、密码。
Redis 还有几个奇怪的功能我可以分享一下:Linux 有一个功能可以通过一个端口写到本地文件,如果我要写一个文件,而这个文件是木马,那就自动拉起了。如果写入自己签名的公钥,用自己的私钥解公钥,自己解自己的,所以直接替换公钥,就是通过 Redis。
有人问,你怎么记录下来这些呢?其实很多攻击者都会去清除掉日志,我们需要想些办法让他不能清除,保证审计可追溯,否则入侵之后就追溯不出到底是什么原因。
所以黑客用 Dirty cow 提权,黑客上来就把自己的操作清除掉了,不让你看见。你知道他要清除,你就想办法不让他侵掉,不然追查不到。
其实他入侵你的服务器不是最终目的,最终的目的是扩大战果,最简单的方式是监听和收集相关的通信,再做一些扫描之类。如果这些机器有关于运维体系的脚本、域名,可能都危险了。
以前给外面做分享,都觉得你说的攻击方式发生概率不是很高。不说真实案例,大家就觉得真实概率不是很高;有了真实案例,大家觉得小概率事件还是会发生。
Linux 下面渗透的方式有这么几个步骤:
- 首先扫描,他知道你 IP 是否存活,前端是否有防火墙;
- 扫描之后尝试渗透,看有哪些端口的权限是什么;
- 接下来看通过开源的应用或者渗透方式怎么入侵,有哪些东西可以利用;
- 入侵之后,普通账号怎么提权到 root,最后怎么扩大战果。
这是 Linux 常用的渗透,扫描之类的,大家可以试一下。
2.2.1 SSH 暴力破解
在很多公司规范里面,SSH 不允许对外开放,要开放给跳板机,这都是有目的的。换个端口,很多默认扫描是指定的 22,这样可以减少被发现的概率。
如果 SSH 登陆只认跳板机也可以防止被撞库。大家想一想你们自己的密码,和在公司用的密码,服务器的密码和私钥密码和互联网的密码有多少是相同的?比如 12306、京东等都有可能相同,人家一旦泄露了,密码就泄露。所以这个撞库的概率不能避免,因此要应对暴力破解。
2.2.2 查看历史命令(histroy)
黑客侵袭你的服务器之后,histroy 给他提供很多线索,所以你的帐号退出之后 histroy 要清掉。
2.2.3 Redis 入侵实战
上图演示了怎么通过 Redis 写入反弹 shell,黑客常用这种案例。Redis 默认就是匿名,他信任可信客户端。所以这种机制导致你在使用上要整合很多认证机制和访问控制,否则会非常危险。另外这个功能都是可以关闭的,servers 可以不要写的,相当于安全极限。
Redis 匿名,如果公司没有统一的规范和标准,一般作为开发人员来说,直接 Redis 是匿名最简单、最高效,所以 Redis 匿名漏洞在互联网环境中非常多。PoC 工具也非常多,基本直接沦陷。
2.2.4 提权演示
这是 Linux 的声卡内核提权的漏洞,我介绍两个提权,这是其中一个,从普通用户提权到 root。这是我录的视频,可以看一下。
真实案例的提权和这个一样,没有太多区别。既然打开这个视频,再给大家看看 Dirty cow 的提权,这是 2016 年最火的提权漏洞,80% 的 Linux 会沦陷。
刚才给大家演示了两个视频,这是提权的过程,从普通用户怎么提到 root 的。这种怎么防御后面会有介绍。要及时修复这些补丁,不要以为提权影响不大,其实影响很大的。root 能干的事和普通帐号能干的事差别很大。
给大家演示了 Dirty cow 的提权,其实最关键的漏洞在于 Linux 里有一个内存管理写权限的 bug,导致不该具有写权限的进程它写进去了。
我们写的代码,根本产生的原因是很多线程竞争资源的时候,Linux bug 出现的概率非常高。所以要写很多的线程通入经营资源,这里面还用了一些东西的注入,后面会有介绍。本来不具有写一个 password 权限的,但是 Linux 写权限产生 bug 的时候,会导致你可以写进去。
2.2.5 进程注入
上图演示的代码,我准备用 sinclude 注到这个里面去,分别是两个进程在跑。其实注入有几个基本的,你要了解 Linux ELF 文件格式,还有系统调用,还有 CPU 执行过程中的整个逻辑。
多线程之间的进程很关键,这个情况我现在遇到的不多,真正我们遇到被入侵事件中,内核态木马的遇到不多,以前 Windows 有很多。我们自己有写过这种木马,所以这种情况我很少遇到过。只是之前在其他的领域确实遇到过几次,所以给大家介绍这种。相当于 Windows 状态下的一种木马,在 Linux 情况下也存在,杀伤力还很大。
我介绍一下执行的原理,这些系统调用内核态的执行过程。你原来的执行过程是这样的:我要把你 hook 掉,系统调用执行过程后我转给你,无论是进程起用,文件读写都被我控制了,可做的事情很多,而且隐蔽性很大很难找。
这是我们做的测试代码,首先建了目录,目录里面写了一些文件进去,但是把内核态木马加进去之后,你再进去,就没有了。这种一般守护的时候比较有用,要隐藏木马或者守护木马文件、进程文件比较有用,你看不到的时候依然可以读写。
你明明在里面 insmod 一个模块,但是看不到,它把你 insmod 内核模块 read 也给劫持了,所以你看不到它。
再演示一下这个代码,这很常见,服务器中为什么莫名其妙解析错了?
Linux 有一个解析的配置,加了这个代码,其实我有注掉。但是加载了这个之后,我看的时候,普通运维人员、研发人员看不到。大家看百度还是会解到本地的,其实已经被本地劫持了,但是很难查。
我前面有介绍反弹唤醒的技术,一种是木马主动向控制器去上报我自己的 IP 和端口,达到控制。
还有等待对方的唤醒,唤醒报文很讲究,这个唤醒用 ICMP 报文载荷定制一个特殊的“key”报文,做一个特殊的字符唤醒。唤醒木马,这是一个特殊的报文,完全可以唤醒我的木马对那台机器执行操作。“.168” 这是典型的 ICMP 唤醒的技术。再加上内核,应用很难发现。
我刚才介绍了很多 Linux 下的一些嗅探、注入、提权等机制。我们有针对性的了解这些机制,是为了保证业务稳定可靠的运行,肯定要有对应的防御手段。
不管是否做到自动化,或者手动也好,总要有手段。不同的公司在不同的规模、不同的发展阶段,策略不一样。我先介绍一下我们现在的防御想法、思路和进展情况。
漏洞扫描、入侵检测、主动防御、事件预警、行为审计、应急响应、标准规范等都是防御策略。
我们防御考虑不一定是通过某个环境,绝对的识别到这次入侵或者拦截到这次防御。但是要层层设防,比如业务上线前,不可能像 CMMI 那种,有很多评审点,在互联网公司里面版本快速迭代,基本做不到 CMMI 的要求,没有评审通过就不能上线,我觉得做不到。
如果真的拖慢了业务上线的速度,业务死了,安全团队也没有价值,所以,肯定是业务第一。
我觉得业务在上线的时候,我做异步的时候做扫描,并发评估,尽可能不影响业务上线。包括 Redis 的匿名等,都可以做匿名,在构建的时候发布一条线,还可以扫到另外一条线。
还有入侵检测机制,被入侵的情况还是要有些预警或者防御的手段。至少你要知道,全网可能几百台、几千台甚至几万台服务器,完全不知道状况,那就没办法做后续相关的跟进了。
如果能做到更牛逼的防御,比如主动防御,这是大家最终的理想状况,很多公司做不到。我曾经想过,木马起动的时候,如果不在签名的进程不让它起,代码写出来了,而且 Demo 写了但是不敢上线,因为我担心出内核兼容性问题,要背锅,主动防御这里涉及到整个平台的所有服务器的兼容,需要谨慎,是下一个里程碑。
所以我觉得有些东西可以做一些妥协。比如木马文件的自动化隔离,检测是一条思路,如果主动防御可以自动隔离掉,不让有任何写权限、启动权限当然会更好。
预警,出了事情要知道,不要等到业务保障或者用户投诉到客服。业务已经瘫痪了,你还不知道什么原因?一查,好像两台服务器被入侵,很多数据被删了。所以要提前预警,优先于业务保障之前及时掌握安全状况。
行为审计,刚才我介绍的入侵的案例,没有行为审计。很多入侵事件不一定找到入侵路径,很多同学出问题找不到原因最喜欢的是“重装操作系统”。其实重装并没有任何意义,因为漏洞依然存在,重装是没有任何意义的,还是要想办法溯源,找到入侵路径在哪里。
应急响应,要有应急响应的机制,因为你将来不是绝对安全,一定有漏洞,一定有弱点,每种方式要做出相应的预案。
规范化和标准化,不同公司发展阶段不同,其实它程度也不一样。
3.2.1 漏洞扫描
我们这边可能会有内部的自动化扫描,如果业务存在漏洞,会直接触发一封邮件,要求 24 小时修复,给剩余的修复时间。
相关的自动化预警,我们做得并不完善,只是把著名的开源软件做到,其实我们还做不到那么完善。
3.2.2 入侵检测
入侵检测,如果发现有可疑的进程,我们会直接预警出来,避免对业务造成影响。
3.2.3 行为模式审计
行为模式审计,这是我们发生入侵的事件,曾经有一个帐号,这个预警是把历史信息清掉。这对我们来说是很可疑的,最终是这个人的私钥丢了,所以这就是一起突发安全事件。
我们这边有恶意 IP 的识别,外挂、机器人之类的会收录下来,你历史上攻击过我们或者冲击我们服务的 ip,我们会收录下来。如果你服务和黑产进行通信,我们都会预警。这里面可能误报,但是我们肯定会跟进这个事。
3.2.4 应急响应
刚才我提到应急响应要有应急预案。刚才讲 DDoS 也是一样,DDoS 一定有一个防御的上限,比如 120G,比如你并发处理能力是 1 万,如果超过 1 万,怎么办?到底是攻击还是由于活动造成的陡增?都要有预案。对今天讲的 Linux 的入侵,攻防,最主要入侵事件要找到入侵路径。
即使找不到也要推出几种可能性,而且这几种可能性要有针对性的修复或者改进,否则你单纯的重装操作系统,我觉得完全没戏,只是给后面安全问题留下更大的坑。
3.2.5 标准规范
规范化、标准化,这需要跟公司的企业文化、公司的发展阶段,跟公司整体要搭。我们正在持续努力中,对我们来说推进挑战也是很多,有些可以推,有些也不容易。
我们每出一次安全事件都借这个安全事件推动很多规范,以事件为导向推动安全规范相对容易一些。所以这需要下点功夫,而且要结合公司自己的运维体系、发布体系、监控体系做这个事。
安全永远没有绝对的安全,永远存在漏洞。这时候你和业务一定要有平衡,不要为了绝对安全而影响业务。不能绝对说存在问题、存在风险,这个业务不能上线,这种决策还是要评估一下。
我觉得业务做起来,安全才有更大的机会,完全阻碍业务版本的迭代,其实安全也会有问题。毕竟业务发展起来,平台大了,安全才有更大的产出。
另外就是效率,安全和效率永远有冲突,你让他登陆跳板机,服务器不能交叉认证,再回跳板机,再跳服务器,很多人就怒了。几十上百台服务器天天维护,太麻烦了。
安全和效率之间的冲突,有些要做平衡,有些还是要坚持。需要持续的改进,我认为 PDCA 这种模型非常适合 Linux 的攻防对抗去持续改进、持续 check。