月度归档:2020年05月

偶遇 SSH rookit,我的服务器基本全军覆没

事情是这样的,昨天晚上我收到了腾讯云的异地登录告警,一开始我并不是太在意。腾讯云经常会有一些误报告警,不怪腾讯云,有时候我带着笔记本回老家,笔记本竟然没睡死,在合上的状态连上了我的服务器(目测是 VSCode 远程开发),而老家的电信宽带竟然有时候 ip 是其他城市的,就会引起异地登录报警。

然而这次的告警收到的时候我正在深圳家里电脑前,没有移动设备,而且 IP 也十分诡异,查询为拉脱维亚的 IP。以为是密码泄露,登上去草草改了密码就睡觉了。

第二天起来看 log,发现第一次登录只有一个 disconnect 的 log,我就在想这个异常 IP 到底是不是真的有成功登录我的机器呢,找了腾讯云安全的大佬们协助排查。后来发现第二次的登录有完整的 log,可以明显的看到 Accept 了来自公钥的登录。使用的公钥来自我另一个机器上(后称为 B 机器)的用户密钥对。

告警的机器我们把他叫做 A,A 机器是最近新购的,腾讯云最近 SA2有优惠啊,于是买了一台,准备把老机器 B 停止续费,迁移数据和服务换到价格更便宜配置更高的 A 机器。迁移过程完全是手工操作,没有粗暴的对拷数据,认真的整理了哪些服务已经不需要了,也重新规划了目录结构和权限。为了方便迁移数据(我使用 scp 拷贝),我把 B 机器的公钥添加到了 A 机器的authorized_keys 中,因此 B 机器是可以直接免密 ssh 到 A 机器的。

安全的同学相当的给力,很快的从情报上发现了入侵 IP 相关的一个文章,这个病毒叫 Ebury,感染后会替换掉ssh 依赖的 libkeyutils.so,使得 ssh 会加载一个病毒载体 libxxx.so(文件名不定,我这里见过 libtsr.so/libpw5.so/libhdx.so 等),他会记录你 ssh 到别的机器的时候用到的密码或密钥,通过 DNS 请求把数据发回去黑客的服务器。相关的日志信息可能会被抹除而无法查询,文件的修改时间也会被改到一个以前的时间来迷惑你(stat 看 change 时间可以发现问题),还把 rpm 相关签名信息改掉,你通过 rpm 检查包签名也是查不出来的。我遇到的变种基本可以通过 objdump 查看 libkeyutils.so 有奇怪的 libxxx.so 依赖来判断受感染,这个 libxxx.so 上传到 virustotal 站点是可以识别出来 ebury 病毒的。

除了腾讯云国内的机器,国外我还有其他供应商的机器,这些机器很多时候(主要是晚上)SSH 卡顿困难,所以我时常会有借国内机器 SSH 管理国外机器,果不其然,国外的几个机器查了下全都被感染了!!!病毒样本最早的时间在2017年,所以其实在我的机器上已经潜伏了很久,随着机器之间互相 ssh 登录互相传染病毒。

国外廉价 VPS 大多属于 Unmanaged VPS,基本是没有什么技术支持,更别说像腾讯云这种入侵检测告警之类的,所以问题其实早已存在,只是没什么症状,没什么明显影响,没有被发现而已。

在善后问题的处理上面,我发现 clamav 有奇效,可以扫描出受感染的文件来。由于重装比较麻烦,尤其是感染到我一台用于存储数据备份的机器(没错,国外的,还不像云服务简单的做定时快照之类的就能实现备份目的),所以我决定暂时清除相关感染文件(重新安装正规来源的 keyutils-libs,删除 libxxx.so),撤换受感染机器的 ssh keys,撤换互相登录过的机器 root 密码,禁止 root 密码登录,后续也不准备允许长期的跨机器互登公钥信任。

======

Update:某些比较老的机器上 clamav会超内存无法扫描,还有的机器clamav通过包管理安装,病毒库更新到最新,但扫样本so的时候竟然报没被感染,因此并不是很靠谱。

我的处理方法:

  1. objdump -x /lib64/libkeyutils.so.XXX | grep NEEDED 确认入侵痕迹,会依赖一个不知名libxxx.so
  2. yum reinstall keyutils-libs 重新安装正常版本的libkeyutils.so,再次使用1中命令确认已经不再依赖不知名libxxx.so
  3. reboot重启机器,让内存里面已经加载的不知名libxxx.so自然消散
  4. 重启后 lsof | grep /lib64/libxxx.so 确认内存中已经没有该文件,再次使用1中命令确认已经不再依赖不知名libxxx.so
  5. 删除libxxx.so
  6. 重新生成机器的公私钥 ssh-keygen

SSH 连接超时,VSCode 远程开发断链问题排查

嗯最近晚上有时在家使用 vscode 远程开发连接腾讯云的机器写点小东西,有几个晚上发现 vscode 远程很容易断开,甚至断开之后无法重连,这时候 ssh 也无法连接,但是 ping 很正常,原本还怀疑是电信宽带日常晚上常规垃圾表现。

后来在腾讯云的管理控制台上发现我断连无法接上的时候,云监控里面连上报数据都没有,显示缺失了数据。但是可以大致看到出现这个情况前 CPU、内存、IO 迅速爬升直到爆满,当 CPU 下来的时候就自愈了。考虑到我这个是腾讯云底配1C1G 的机器,资源紧张是很正常的,但我还是想看看是哪个鬼把资源耗尽了,于是我做了一个小脚本。

脚本内容很简单,每5秒把 top 的结果打到文件里面,保留最近30分钟的记录。果然没过几天情况又出现了,这时候试了下腾讯云 VNC 的控制台还可以勉强登上机器,只是比较慢,实时看 top 的时候发现 wa 很大,负载巨高,内存也所剩无几。大致可以瞄到是 gopls 进程和 vscode 远程开发相关的 node 服务占了大部分。

待机器喘息过来,我想去看脚本收集的日志的时候发现出问题的时间段前一分钟只落盘了两份文件,后一分钟一个文件都没有,正常5秒一落一分钟有12个文件,机器看来完全卡死哈哈,我从那两份文件里面简单看了一下,大致如下。

会发现这里 wa 又好好的,显然是 wa 缓过来了文件才能落盘,wa 爆炸的时候脚本已经完全卡住了。不过从上面的信息来看内存爆满是不争的事实,进程列表里面也看到 kswapd0跑出来了,一定是内存爆炸之后系统开始 swap,上图也可以看出来 gopls 用了 17.1%的内存 virt 500m 以上。

我想可能是时候升级一下这个祖传 1C1G 机器了,这个老机器裸机是 S2型42软妹币一个月,最新的 AMD 的机器SA2 1C1G 已经做到了29软妹币一个月,1C2G 32软妹币一个月,性价比非常高,老用户也可以买,新用户当然是买爆款1核2G云服务器,首年99元