一次Ubuntu下的排雷记录

本文记录了一次服务器遭遇挖矿病毒的经历,详细描述了病毒如何通过定时任务自动重启,以及如何彻底清除病毒的过程。强调了加强服务器安全的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

起因

某天,发现一台服务器上出现了一个大量占用cpu资源的进程。尝试手动杀掉,但很快就会自动重新创建新的进程。
1055165-20180917183254549-1422030809.png

追查

用命令lsof -p 10316 查看其文件路径:

1055165-20180917183434157-1722838479.png

该进程文件夹/proc/10316下:

1055165-20180917183515792-2022382003.png
1055165-20180917183523061-1308482333.png

看到该文件夹下的exe文件是指向/var/tmp/.../Word,也就是文件夹名字就是"...",查看简要的信息:

1055165-20180917183626422-1411717077.png

其中:
cmdline — 启动当前进程的完整命令
environ — 当前进程的环境变量列表,彼此间用空字符(NULL)隔开;变量用大写字母表示,其值用小写字母表示
cwd — 指向当前进程运行目录的一个符号链接
exe — 指向启动当前进程的可执行文件(完整路径)的符号链接,通过/proc/N/exe可以启动当前进程的一个拷贝
文件介绍

查看cmdline文件发现:

1055165-20180917183849349-1098435069.png

说明这个进程是通过该命令启动的,通过查看进程状态也证实了这一点:

1055165-20180917190334108-290302063.png

为了查找上面cpmg文件的路径,使用find命令find / -name cpmg49nhiCCK4u2Lvt2Y9Tasf8wpnkEYBoeVanWwuFJJRaHMhfPTr5C6QFb4,找到一大堆文件的路径:

1055165-20180917190420174-217312396.png

文件路径基本都是来源于/proc/文件夹中。由于不了解具体是什么内容,我尝试代开其中一个查看:发现并没找到对应的文件,用sudo权限去查找,发现无法找到该cpmg开头的文件。

事情陷入了僵局。回到原处,尝试从启动进程的命令本身寻找线索。

postgres 10316  374  0.0 408984 13844 ?        Ssl  Aug29 202:19 sh                                                          cpmg49nhiCCK4u2Lvt2Y9Tasf8wpnkEYBoeVanWwuFJJRaHMhfPTr5C6QFb4 -o stratum+tcp://monerohash.com:5555 -p x -k -B -l Word.txt --donate-level=1

找到上述exe所指向的可执行文件Word,查看其目录发现:

1055165-20180917190512368-1223917925.png

Word是可执行文件,Word.txt是一个不断增长的类似于日志一样的文件,通过tail –f Word.txt的结果如下:

1055165-20180917190543612-801724879.png

由此大概可以知道前面的启动命令是什么意思了,就是通过与其他机器建立连接,不断地上传数据。
但是仍然不知道它具体是怎么操作的,于是乎上谷歌查了一下stratum+tcp://monerohash.com:5555这个东西,发现有网友出现过相同的问题,另有网页1介绍:

1055165-20180917190607695-82385864.png

原来是些挖矿的病毒程序,上面的情况说明了自己的服务器已经被别人用作挖矿了。相似的网站还有下面这些
stratum+tcp://mine.moneropool.com:8080
stratum+tcp://mine.moneropool.com:3336
stratum+tcp://xmr.hashinvest.net:443
stratum+tcp://xmr.hashinvest.net:5555
stratum+tcp://monero.crypto-pool.fr:3333
stratum+tcp://monerohash.com:5555
stratum+tcp://mine.xmr.unipool.pro:3333
stratum+tcp://xmr.prohash.net:5555
stratum+tcp://xmr.miner.center:2777
stratum+tcp://mine.xmr.unipool.pro:80
stratum+tcp://pool.minexmr.com:7777
stratum+tcp://cryptonotepool.org.uk:7777
stratum+tcp://mro.poolto.be:3000

这样基本可以定位这里就是挖矿程序的源头。
仔细分析其中的文件:
/var/tmp/…/a

1055165-20180917190633859-1791520148.png

cron.d文件
1055165-20180917190653089-1310487057.png

run文件
1055165-20180917190728315-846748153.png

udp文件
1055165-20180917190745807-150626893.png

x文件
1055165-20180917190801195-1853410016.png

基本可以定位它无法杀死的原因就是加入了一个随时的定时任务,一旦杀死就会自动重启。

查看该用户的定时任务列表,当前用户默认只能看到自己的定时任务,所以需要sudo。

sudo crontab –l –u postgres

确实发现了该定时任务:
1055165-20180917190821111-985879751.png

crontab命令选项基本只有对用户操作的选项:
-u 指定一个用户
-l 列出某个用户的任务计划
-r 删除某个用户的任务
-e 编辑某个用户的任务

既然定位了问题,接下来就是解决该问题。
首先要做的就是删掉该定时任务:

sudo crontab –u postgres –r 删除

crontab命令

然后删掉对应的执行文件:

sudo rm –r …/

最后关停掉对应的所有该用户下的进程:

pkill –u postgres

kill -9 10316

至此该问题终于得到解决。

总结

是什么原因导致该病毒文件被放到服务器中?
现在想到的一种可能是登录用户的密码被破解了。由于前面涉及的用户是postgres,所以可能的情况是有人用默认的用户名和密码进行嗅探登录。幸亏该用户没有根权限。但是需要引起注意的就是:

1、 能不创建用户就不创建用户
2、 能禁止登录就禁止登录
3、 密码要尽量复杂
4、 变更默认端口防止嗅探

完。

转载于:https://www.cnblogs.com/zhangjpn/p/9664247.html

好的,以下是一个简单的排雷游戏的C语言代码: #include <stdio.h> #include <stdlib.h> #include <time.h> #define ROWS 10 #define COLS 10 #define MINES 10 void init_board(char board[][COLS], int rows, int cols, char ch); void print_board(char board[][COLS], int rows, int cols); void set_mines(char board[][COLS], int rows, int cols, int num_mines); void get_neighbors(char board[][COLS], int rows, int cols, int row, int col, int *n, int *s, int *e, int *w, int *ne, int *nw, int *se, int *sw); void reveal(char board[][COLS], char mask[][COLS], int rows, int cols, int row, int col); int count_mines(char board[][COLS], int rows, int cols, int row, int col); int main(void) { char board[ROWS][COLS]; char mask[ROWS][COLS]; int row, col, num_mines, num_revealed; srand((unsigned)time(NULL)); init_board(board, ROWS, COLS, '-'); init_board(mask, ROWS, COLS, '*'); num_mines = MINES; set_mines(board, ROWS, COLS, num_mines); num_revealed = 0; while (num_revealed < ROWS * COLS - num_mines) { print_board(mask, ROWS, COLS); printf("Enter row and column (e.g. 3 4): "); scanf("%d %d", &row, &col); if (board[row][col] == '*') { printf("BOOM! Game over.\n"); break; } reveal(board, mask, ROWS, COLS, row, col); num_revealed++; } if (num_revealed == ROWS * COLS - num_mines) { printf("Congratulations! You win!\n"); } return 0; } void init_board(char board[][COLS], int rows, int cols, char ch) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = ch; } } } void print_board(char board[][COLS], int rows, int cols) { int i, j; printf(" "); for (j = 0; j < cols; j++) { printf("%d ", j); } printf("\n"); for (i = 0; i < rows; i++) { printf("%d ", i); for (j = 0; j < cols; j++) { printf("%c ", board[i][j]); } printf("\n"); } } void set_mines(char board[][COLS], int rows, int cols, int num_mines) { int i, j, k; for (k = 0; k < num_mines; k++) { do { i = rand() % rows; j = rand() % cols; } while (board[i][j] == '*'); board[i][j] = '*'; } } void get_neighbors(char board[][COLS], int rows, int cols, int row, int col, int *n, int *s, int *e, int *w, int *ne, int *nw, int *se, int *sw) { *n = (row > 0) ? board[row - 1][col] : 0; *s = (row < rows - 1) ? board[row + 1][col] : 0; *e = (col < cols - 1) ? board[row][col + 1] : 0; *w = (col > 0) ? board[row][col - 1] : 0; *ne = (row > 0 && col < cols - 1) ? board[row - 1][col + 1] : 0; *nw = (row > 0 && col > 0) ? board[row - 1][col - 1] : 0; *se = (row < rows - 1 && col < cols - 1) ? board[row + 1][col + 1] : 0; *sw = (row < rows - 1 && col > 0) ? board[row + 1][col - 1] : 0; } void reveal(char board[][COLS], char mask[][COLS], int rows, int cols, int row, int col) { int n, s, e, w, ne, nw, se, sw, num_mines; if (mask[row][col] == '-') { mask[row][col] = board[row][col]; if (board[row][col] == ' ') { get_neighbors(board, rows, cols, row, col, &n, &s, &e, &w, &ne, &nw, &se, &sw); if (n == '-') reveal(board, mask, rows, cols, row - 1, col); if (s == '-') reveal(board, mask, rows, cols, row + 1, col); if (e == '-') reveal(board, mask, rows, cols, row, col + 1); if (w == '-') reveal(board, mask, rows, cols, row, col - 1); if (ne == '-') reveal(board, mask, rows, cols, row - 1, col + 1); if (nw == '-') reveal(board, mask, rows, cols, row - 1, col - 1); if (se == '-') reveal(board, mask, rows, cols, row + 1, col + 1); if (sw == '-') reveal(board, mask, rows, cols, row + 1, col - 1); } } } int count_mines(char board[][COLS], int rows, int cols, int row, int col) { int n, s, e, w, ne, nw, se, sw, count; get_neighbors(board, rows, cols, row, col, &n, &s, &e, &w, &ne, &nw, &se, &sw); count = 0; if (n == '*') count++; if (s == '*') count++; if (e == '*') count++; if (w == '*') count++; if (ne == '*') count++; if (nw == '*') count++; if (se == '*') count++; if (sw == '*') count++; return count; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值