Linux服务器挖矿木马病毒查杀记录(-bash mcrond bprofr pwnrig ntpdate dbused sysdr)

近期,服务器异常,通过htoptop命令查看CPU占用前几的进程,发现root用户的-bash进程把CPU一半的核占满,而另一台服务器上x用户(被新创建的用户)和一个普通用户CPU占用也异常。

kill -9 进程号杀掉进程后立马又启动了新进程,ll /proc/进程号查看PID目录,可以看到exe指向了一个被删除了的-bash进程(/usr/bin/-bash),使用 netstat -anp|grep ESTABLISHED 查看State为ESTABLISHED的网络连接,发现有异常外网连接,这应该就是-bash病毒木马了。
在这里插入图片描述

处理思路

找出与木马相关的所有关联文件并删掉:!!注意删除文件前一定要谨慎,逐一通过文件内容创建时间来综合判断是否为木马关联文件。

  1. cat /etc/passwd查看是否有异常用户和组,对于木马创建的新用户可以直接删除,逐一检查每个用户目录(包括root)文件是否异常,重点是~/.bash_profile~/.bashrc~/.ssh/authorized_keys
  2. 木马能不停启动,可能会篡改命令,并且有守护进程,重点检查定时任务启动项服务等,排查/bin/sbin/etc/cron*//var/spool/cron*//etc/init.d//etc/rc*//etc/system*//lib/system*//run/system*/目录下是否有异常文件最近修改ls -lt | head)。
  3. 当查到木马脚本后,总结出脚本中的一些 关键文件名称,如mcrondbcrondcrondrbprofrntpdateentpdatelntpdateinitdrbinitdminitdmsysdemsysdlbsysdebsysdlsysdrdbuseddo-dearpwndnspwnrig并用这些关键词作为特征搜索上述目录文件。

下面是整个查杀过程,以下所有操作都在root权限下进行,一定谨慎删除文件,文末会附上我制作的批量查杀脚本:

进程分析

# 分析前几个cpu占用高的进程
ps aux|grep -v PID|sort -rn -k +3|head

# 查看进程文件
ll /proc/进程号
lsof -p 进程号

# 筛选网络连接
netstat -anp|grep ESTABLISHED

# 杀掉进程
kill -9 PID

定时任务分析

# 查看定时任务
crontab -l
# 查看指定用户定时任务
crontab -u username -l
# 编辑定时任务
crontab -e

在这里插入图片描述
这里发现了异常目录/var/tmp/.systemd/和域名pwndns.pw,在所有定时任务文件夹/etc/cron*//var/spool/cron*/查一遍最近修改的文件(目录下有很多子文件夹,如cron.d,cron.daily,cron.hourly,cron.weekly,cron.monthly等,很多都会有),可以使用ls -lt 文件名 cat 文件名查看文件时间和内容是否异常,然后就发现了下面异常文件。
在这里插入图片描述
这里发现了异常文件ntpdatepwnrig,可以看到文件修改时间为9月28日 3点,后面只要查到文件在这个时间附近修改过,就基本是木马文件。查看文件内容:
在这里插入图片描述在这里插入图片描述
从文件里又提取了关键词crondrmcrondbcrond等,发现该脚本已经污染了/bin目录,也发现了木马会使用curlwget从服务器不停请求最新脚本-bash进程启动后,原二进制文件就会被删除,所以不能从进程路径溯源

用关键词重新搜索一遍定时任务

grep -R -E 'mcrond|bcrond|crondr|bprofr|ntpdate|entpdate|lntpdate|initdr|binitd|minitd|msysde|msysdl|bsysde|bsysdl|sysdr|xmr|pwndns|pwnrig|do-dear|update\.sh|root\.sh|\.systemd|\.update' /etc/cron* /var/spool/cron* 2>/dev/null

限制网络连接

检查主机防火墙iptables规则中是否存在可以地址和端口,由于木马会不断通过网络请求下载最新脚本,所以得限制网络连接:

# 检查主机防火墙iptables规则
iptables -L -n
# 阻断挖矿目录网络通信
iptables -A INPUT -s 可疑地址 -j DROP
iptables -A OUTPUT -d 可疑地址 -j DROP

# 暂时修改掉curl和wget
mv curl curl.bak
mv wget wget.bak

# 修改hosts文件
echo "127.0.0.1 pw.pwndns.pw" >> /etc/hosts
echo "127.0.0.1 xmr-rx0.do-dear.com" >> /etc/hosts

在这里插入图片描述

排查/bin /sbin

 cd /bin
 # 分析最近修改
 ls -lt|head -30
 
 cd /sbin
 ls -lt|head -30

cat 可疑文件名

/bin/sbin目录下不少被篡改的命令,并且被添加了-ai保护属性,常规的rm -rf 文件名删除不掉,可以chattr -ai 文件名减除保护属性后删除。注意:如果某文件减除保护属性后还删除不掉,请检查上级目录是否被添加保护属性。

# 查看文件保护属性
lsattr 文件名
# 删除文件保护属性
chattr -i 文件名
# 删除文件
rm -rf 文件名

在这里插入图片描述
如果还删除不掉,可以使用inode节点的方式删除:

ll -i 文件名
find ./* -inum 节点号 -exec rm -ri {} \;

排除异常用户和home目录文件

# 检查异常组和用户
cat /etc/passwd
# 发现了异常新建用户x,直接删除(谨慎核对后操作)
userdel -r x

发现很多用户目录下~/.bash_profile~/.bashrc~/.ssh/authorized_keys被篡改(root用户、mail用户、普通用户下均有发现篡改)
在这里插入图片描述

检查 SSH 授权密钥有无异常密钥

awk -F: '{print $6}' /etc/passwd | xargs -I {} grep -EH 'ssh-rsa|ecdsa-sha2-nistp256|ed25519' {}/.ssh/authorized_keys 2>/dev/null | awk -F: '{print "User: " $1 "\nKey: " $2 "\n-------------------------"}'

启动项和服务分析

# 排查启动项
chkconfig
systemctl list-units --type=service | grep -E 'mcrond|bcrond|crondr|bprofr|ntpdate|entpdate|lntpdate|initdr|binitd|minitd|msysde|msysdl|bsysde|bsysdl|sysdr|xmr|pwndns|pwnrig|do-dear|update\.sh|root\.sh|\.systemd|\.update'

# 关闭恶意启动项
chkconfig 服务名 off
systemctl disable 服务名

在这里插入图片描述
发现了系统级服务,结合上面的各种关键字,干脆在 /usr/lib/systemd//etc/rc.d//etc/systemd/ /lib/systemd/文件夹里搜索一遍吧,搜索到有问题的再逐一核对删除:

grep -R -E 'mcrond|bcrond|crondr|bprofr|ntpdate|entpdate|lntpdate|initdr|binitd|minitd|msysde|msysdl|bsysde|bsysdl|sysdr|xmr|pwndns|pwnrig|do-dear|update\.sh|root\.sh' /etc/rc*/ /etc/init*/ /lib/system*/ /etc/system*/ 2>/dev/null

清除预加载so

环境变量LD_PRELOAD和文件/etc/ld.so.preload可以自定义程序运行前优先加载的动态链接库(该文件默认为空),木马通过修改该文件添加恶意so实现挖矿进程隐藏等恶意功能。

# 排查环境变量
echo $LD_PRELOAD
# 查看ld.so.preload
cat /etc/ld.so.preload
# 清除异常动态链接库 
echo "" > /etc/ld.so.preload
# 删除恶意so
rm -rf /usr/local/lib/libprocesshider.so

在这里插入图片描述

检查系统日志

grep -R -E 'mcrond|bcrond|crondr|bprofr|ntpdate|entpdate|lntpdate|initdr|binitd|minitd|msysde|msysdl|bsysde|bsysdl|sysdr|xmr|pwndns|pwnrig|do-dear|update\.sh|root\.sh' /var/log/ 2>/dev/null

在这里插入图片描述
找到来源了,xmrminer从某98.12服务器过来,可以确定这是挖矿木马病毒,并通过日志确定了可疑用户x以及/tmp/.pwn/tmp/systemd-private*/var/tmp/.update/var/tmp/.system*/var/tmp/systemd-private*等目录。

编写批量查杀脚本

基于以上分析,基本确定了病毒传播方式和一些关联文件和目录,编写批量查杀脚本scan_bash.sh

# Linux server mining Trojan virus detection
# @author [jackhanyuan](https://github.com/jackhanyuan)
# @Date October 10, 2024

#!/bin/bash

# Define keywords (optimized regular expressions)
keywords='mcrond|bcrond|crondr|bprofr|ntpdate|entpdate|lntpdate|initdr|binitd|minitd|msysde|msysdl|bsysde|bsysdl|sysdr|dbused|xmrminer|xmr-rx0\.do-dear\.com|pw\.pwndns\.pw|pwndns|pwnrig.*|do-dear|processhider|root\.sh|reboot\.sh'

# Set maximum scan depth (adjust as needed)
max_scan_depth=2
# If the user provides a scan depth parameter, use it
if [ $# -ge 1 ]; then
    if [[ $1 =~ ^[0-9]+$ ]]; then
        max_scan_depth=$1
    else
        echo "Invalid scan depth parameter. Please provide a positive integer."
        exit 1
    fi
fi
echo "Scan depth set to: $max_scan_depth"

# Get all users' Home directories (as an array)
readarray -t homedirs <<< "$(awk -F: '{print $6}' /etc/passwd | sort -u | grep -Ev '^/$|^/proc$|^/(s?bin)$')"

# Define other directories to scan (do not use quotes to allow globbing)
scandir_patterns=(
    /bin/
    /sbin/
    /etc/cron*/
    /var/spool/cron*/
    /etc/init*/
    /etc/rc*/
    /etc/system*/
    /lib/system*/
    /run/system*
    /var/tmp/.system*/
    /var/tmp/.update/
    /var/log/
)

# Merge and deduplicate directories to scan
dirs_to_scan=($(printf "%s\n" "${homedirs[@]}" "${scandir_patterns[@]}" | awk '!seen[$0]++'))

# Define colors
GREEN='\033[0;32m'  # Green
NC='\033[0m'        # No color

# Start scanning
for dir in "${dirs_to_scan[@]}"; do
    if [ -d "$dir" ]; then
        echo "Scanning directory: $dir"
        
        # Build find command to scan only specific types of files, excluding binary files
        find_cmd=(find -L "$dir" -maxdepth "$max_scan_depth" -type f -size -10M -print0)
    
        # Execute find command
        "${find_cmd[@]}" 2>/dev/null | while IFS= read -r -d '' file; do
            # Check if the filename matches any keyword
            filename=$(basename "$file")
            if echo "$filename" | grep -E -q "$keywords"; then
                echo -e "${GREEN}Found suspicious filename: $file${NC}"
                echo "$file" | sed 's/^/    /'
                echo "-------------------------"
            fi
            
            # echo "Scanning:$file"
            # Search for keywords in file content, excluding binary files
            matches=$(grep --binary-files=without-match -E -H -n -i "$keywords" "$file" 2>/dev/null)
            if [ -n "$matches" ]; then
                echo -e "${GREEN}Found suspicious file content: $file${NC}"
                
                # Indent matched content and limit to first 10 lines with a maximum of 200 characters per line
                echo "$matches" | awk 'NR <= 10 { 
                    if (length($0) > 200) { 
                        print "    " substr($0, 1, 200) " ..."
                    } else { 
                        print "    " $0 
                    } 
                } NR > 10 { 
                    print "    ... (truncated)" 
                    exit 
                }'
                echo "-------------------------"
            fi
        done
    else
        echo "Directory does not exist or is not accessible: $dir"
    fi
done

# Check for SSH authorized_keys
awk -F: '{print $6}' /etc/passwd | xargs -I {} grep -iEH --color=always 'ssh-rsa|ecdsa-sha2-nistp256|ed25519' {}/.ssh/authorized_keys 2>/dev/null | awk -F: '{print "User: " $1 "\nKey: " $2 "\n-------------------------"}' | sed 's/\(ssh-rsa\|ecdsa-sha2-nistp256\|ed25519\)/\x1b[32m\1\x1b[0m/g'

# Check /etc/ld.so.preload with highlighted output if not empty
if [ -s /etc/ld.so.preload ]; then
    echo -e "${GREEN}/etc/ld.so.preload contains the following entries:${NC}"
    cat /etc/ld.so.preload | grep --color=auto '.'
    echo "-------------------------"
else
    echo "/etc/ld.so.preload not exist"
fi

# Check for suspicious cron jobs
crontab -l 2>/dev/null | grep -iE --color=auto "$keywords"

# Check for suspicious services
chkconfig --list 2>/dev/null | grep -iE --color=auto "$keywords"
systemctl list-units --type=service | grep -iE --color=auto "$keywords"

# check environment variables
env 2>/dev/null | grep -iE --color=auto "$keywords"

创建scan_bash.sh,添加权限并批量扫描:

# 创建scan_bash.sh文件并编辑
vim scan_bash.sh
# 添加x权限
chmod +x scan_bash.sh
# 执行扫描脚本
./scan_bash.sh
# 也可以添加扫描深度参数,默认为2
./scan_bash.sh 2

!!本脚本仅扫描,不做任何删改,一定记得对照扫描输出逐一核对可疑文件和内容,确认后再删除,以免删错影响系统运行。

到这一步,kill -9 进程号杀掉相关进程,观察2天没有问题,查杀结束,记得恢复curlwget~~~~

后续防护

  • 升级SSH到最新版本openssh-9.9p1
    https://www.openssh.com/portable.html

  • 禁用默认22端口,禁用Root远程登录,禁用密码登录,改用密钥登录

  • 服务器防火墙禁用不常用的端口

  • 如果有docker和数据库等服务,一定要提升安全等级,不要使用默认端口,启用docker持久化,数据库绑定localhost防止非本机数据库连接

其它参考

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值