摘要
莫名其妙的服务器就被攻击了,又被薅了羊毛,当做免费的挖矿劳动力了。
一、起因
上班(摸鱼)好好的,突然收到一条阿里云的推送短信,不看不知道,两台服务器被拉去作为苦力,挖矿去了。这不是耽误我摸鱼吗,再说你挖到的矿币又不带我分,岂能忍。本着对公司负责任的态度(实在没办法),这不收拾一下过分的挖矿脚本,对不起这么多年积攒的专业知识。
登录服务器,top
一下,ps
一下,crontab -l
一下,好家伙,只看到 CPU 异常占用了,却没发现到底是哪个玩意贪了我这么多资源。与以往的不太一样啊(你特么在逗我?)。
按照以往的经验,ps -aux --sort=-pcpu|head -10
一下,贪渎者肯定原形毕露。难不成穿了个马甲。仔细分析,可能不仅仅是马甲这么简单,更有可能是隐身衣。使出万能的百度大法,果然有几篇秘籍指出问题,一一对照下,只能发现大概,定位不到最终的"宝藏"地点。看来百度不行,得 google 一下了。这次秘籍多了起来,给出了一项专门破解隐藏进程的功法。
二、寻"宝"
BusyBox 是一个集成了 300 多个最常用 Linux 命令和工具的软件。甚至还集成了一个 http 服务器和 telnet 服务器,集成的包大小只有 1M 左右。有人将 BusyBox 称为 Linux 工具里的瑞士军刀。简单点说 BusyBox 就是一个集成了许多 Linux 工具和命令的大的工具箱。在嵌入式软件中,BusyBox 有着广泛的运用。
所以,下载 BusyBox,安装:
$ wget https://busybox.net/downloads/binaries/1.30.0-i686/busybox
$ mv busybox /usr/bin/busybox
$ chmod +x /usr/bin/busybox
查看 BusyBox 基本功能
$ busybox --help
使用瑞士军刀查看一下进程信息
$ busybox top
作祟者原型毕露,有个 /bin/daemon
进程,占用过高的 CPU 使用
同时使用 netstat
查看一下程序端口占用
$ netstat -anp | grep ESTAB
结果如下:
可以看到有一个程序占用端口 14444
,连接的ip为 217.182.169.148
,却并没有打印出程序的进程号,在shadan搜索一下,ip 为法国的,基本确定入侵使用的端口为 14444
,先把端口禁用掉。
三、"六娃"的能力
既然确定是 /bin/daemon
,那就需要找出这个玩意是怎么具有"六娃"的能力,又是如何进行挖矿的。
首先可以确定的是 /bin/daemon
是一个二进制执行程序,那就可以看看它的动态库依赖关系
$ ldd /bin/daemon
此时还未发现有任何异常的结果(请原谅眼神不好使,四个眼睛都没发现问题)
既然 ldd
无法找出异常,祭出大招,看看 /bin/daemon
所执行的系统调用
$ strace /bin/deamon
好家伙,不看不知道,居然有一个 ld.so.preload
,来了个预加载。
一般来说,预加载 so
有两种方式:
- 修改/etc/ld.so.preload配置文件,这种方法对配置修改后运行的进程有效,而无法影响已经在运行的进程
- 启动进程前设置LD_PRELOAD环境变量,此方法只对当前进程生效
LD_PRELOAD
可以影响程序的运行时链接,它允许定义在程序运行前优先加载的动态链接库,通过这个环境变量,可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数。
进程在启动后,会按照一定的顺序加载动态库:
- 加载环境变量
LD_PRELOAD
指定的动态库 - 加载文件
/etc/ld.so.preload
指定的动态库 - 搜索环境变量
LD_LIBRARY_PATH
指定的动态库搜索路径 - 搜索路径
/lib64
下的动态库文件
从上面的结果来看,加载了一个 /usr/local/lib/libprocesshider.so
动态库,从上面的 ldd
返回结果也看到了这个动态库,再仔细一看,这名字,不就是 process+hider
。
libprocesshider.so,Hide a process under Linux using the ld preloader. 官方的解释,本来可能只是作者觉得一个好玩的玩意,却被别有用心的人拿来做坏事。
找到这家伙,那好办了,先把它直接干掉。
$ rm -rf /usr/local/lib/libprocesshider.so
啥?万能的 rm -rf
大法居然失效了,这家伙身上居然给自己加了个盾,大招居然没有收到人头。
冷静一下,仔细分析。既然不能删除,那就是有着隐藏属性,等待技能冷却,我还有招。
$ lsattr /usr/local/lib/libprocesshider.so
果然,文件被追加了隐藏属性。可以看到有 i
和 a
属性。
文件隐藏属性解释:
属性选项 | 功能 |
---|---|
i | 如果对文件设置 i 属性,不允许对文件进行删除、改名,也不能添加和修改数据;如果对目录设置 i 属性,只能修改目录下文件中的数据,但不允许建立和删除文件 |
a | 如果对文件设置 a 属性,只能在文件中增加数据,不能删除和修改数据;如果对目录设置 a 属性,只允许在目录中建立和修改文件,不允许删除文件 |
u | 设置此属性的文件或目录,在删除时,其内容会被保存,以保证后期能够恢复,常用来防止意外删除文件或目录 |
s | 和 u 相反,删除文件或目录时,会被彻底删除(直接从硬盘上删除,然后用 0 填充所占用的区域),不可恢复 |
既然加了盾,那把盾给破了就是:
$ chattr -ia /usr/local/lib/libprocesshider.so
什么,chattr
没权限,这是反弹伤害吗?这,玩不下去了啊。
试试分身术吧。
$ cp /usr/bin/chattr /usr/bin/chattr2
$ chattr2 -ia /usr/bin/chattr
没报错,嗯,再试试
$ chattr -ia /usr/local/lib/libprocesshider.so
咋,还提示没权限。
再看一下 chattr
$ file /usr/bin/chattr
这这这,跟我这虚晃一枪呢。你把我原来的文件删了,给我放个空文件,你是想骗谁呢。
看来要重装 chattr
了,但是机器上跑了不少服务,担心有影响。集中精力,冥想三分钟,条条大路通罗马,此路不通,换路走。谁让咱兄弟姐妹多呢。
服务器都是选择的一样的镜像,版本一致,从其它未被攻击的系统中拷贝一份 chattr
,(划重点)拷贝到服务器上时,请换一个文件名称,通过新的文件修改原来的文件。如 chattr2
。
$ chattr2 -ia /usr/bin/chattr
$ rm -rf /usr/bin/chattr
$ mv /usr/bin/chattr2 /usr/bin/chattr
正主归位,一切妖魔邪道即将化为无形。
$ chattr -ia /usr/local/lib/libprocesshider.so
$ chattr -ia /etc/ld.so.preload
$ rm -rf /usr/local/lib/libprocesshider.so
$ rm -rf /etc/ld.so.preload
此时,通过 top
即可看到 /bin/daemon
进程。没有了隐身衣,无所遁形了吧。
那么,接下来,就应该干掉"罪魁祸首"了。大蛇精和蝎子精已死,救爷爷终于有希望了。
/bin/daemon
是通过软链指向 /usr/bin/daemon
,不墨迹,直接干掉本尊。
$ chattr -ia /usr/bin/daemon
$ rm -rf /usr/bin/daemon
当然,记得杀掉运行中的 /bin/daemon
进程
$ kill -9 2415
四、守护者
一般的挖矿脚本程序肯定都有一个守护进程,保证挖矿的进程被杀之后,可以重新启动,绝大多数是用的定时任务的方式。既然通过 crontab -l
没看到定时任务,那就看看 /etc/cron.d
目录下有没有:
果然,在 /etc/cron.d
目录下,存在着定时任务脚本,查看脚本内容:
$ cat /etc/cron.d/systemd
果然运行了一条定时任务,查看指向的脚本内容:
$ cat /lib/systemd/systemd-login
脚本文件没有内容,file /lib/systemd/systemd-login
very short file(no magic)
什么👻 ,先不管了,干掉再说。
$ rm -rf /lib/systemd/systemd-login
$ rm -rf /etc/cron.d/systemd
$ rm -rf /etc/cron.d/systemd~
$ rm -rf /etc/cron.d/systemz~
打完野怪打小龙,打完小龙打大龙,等一段时间看看,还好,己方水晶没爆。
运行一段时间,一切稳定,算是暂告一段落。
五、总结
本篇文章还有很多的不足之处,并没有找到病毒攻击的入口,又是如何入侵到系统的,挖矿的脚本究竟运行在哪?按照正常的被攻击排错方式,一开始并不顺利。总结一下系统被入侵的排查思路,只是给后来者提供一下解决思路(希望大家的系统都很健壮,不被攻击)。
- 查看系统的
CPU
和内存占用
- 查询占用系统资源过高的进程
- 排查定时任务,
crontab -l
或者/etc/cron.d
目录 - 检查异常端口,如发现,禁用端口,堵漏
- 使用
last
命令查看系统异常登录情况(一般攻击者会抹去入侵记录) - 使用
history
命令查看系统历史执行命令(一般攻击者会抹去历史命令) - 查看开机启动脚本
/etc/rc.local
,是否插入了开机启动进程 - 通过
find /etc/cron.daily/* -mtime -1
查找前一天到现在被修改的文件 - 找一台正常的机器,比较一下被修改文件的
md5
值
后续救援不如从源头堵住疏漏,平时使用系统时,可以从以下方面尽量保证系统安全:
- 检查弱口令,使用强口令,能用证书的,尽量不使用密码
- 不需要在外网访问的端口,尽量不开启,只开放在内网
- 尽量使用普通用户启动服务,不要使用
root
用户启动服务 - 系统被入侵,一般都是通过部署的服务暴露出来的漏洞,及时更新软件版本,加固系统
- 修改常用软件服务的端口,尽量不要使用原有端口
- 定时备份重要的文件数据,以防止服务器被入侵时,丢失重要数据
未完待续...