6.1 KiB
6.1 KiB
name, description
| name | description |
|---|---|
| host-sec-check | Linux/VPS 主机安全检查与入侵取证:先取证再处置。覆盖矿机、ld.so.preload 进程隐藏、带宽挂机容器、对外端口、SSH/Docker/k8s 入口、cron/systemd 持久化、hugepage/OOM。 Use when: 安全检查, 被黑, 入侵, 矿机, 排查端口, 对公网放开, rpcbind, 挂机赚钱, Portainer, 安全审计, host security, compromise, cryptominer, exposure, /host-sec-check. |
host-sec-check
对一台 Linux 主机做安全检查。默认 只读取证 + 出报告。清理、关端口、重启、轮换密钥必须用户明确同意后再做。
需要:SSH 目标(user@host 或 ssh config 别名)、哪张网卡/IP 算公网。没有公网 IP 就只报「监听面」,并标明未做外部探测。
不适用
- Web 应用代码审计、依赖 CVE 扫描(可在报告里列为后续)
- 云厂商安全组控制台(能查就查,查不到就写「未验证」)
- 未获准的破坏性操作(
rm -rf、整盘 wipe、强制重启)
铁律
- 先取证,后动手。 重启、删文件、停服务会毁掉证据。
- 不要把密钥打进对话。 token、密码、authorized_keys、kubeconfig 只写「存在/已轮换/路径」,不贴原文。
- sudo 失败不要停。 用户在
docker组时,用特权容器nsenter看宿主机(见 references/access.md)。 - 怀疑进程隐藏时,不要只信宿主机
ps。 从不加载宿主机ld.so.preload的容器读/proc和文件。 - 宿主机
chattr可能被隐藏库挡住;改 immutable 文件用 Ubuntu/Alpine 自带 chattr 操作 bind-mount 的/host/...。
收集脚本(可选,先跑再解读):
bash <skill-dir>/scripts/collect.sh USER@HOST
<skill-dir> 是本 skill 目录。脚本只采集,不修改系统。
流程
按顺序做。每步记下「正常 / 可疑 / 未查到」。完整项见 references/checklist.md。
1. 快照
- 主机名、发行版、uptime、负载、
free -h、df -h、公网/内网/Tailscale IP ss -lntup(最好 root)docker ps -a、compose 项目- 若有 k3s/k8s:agent 是否在跑、能否
kubectl get pods -A
2. 入口
- sshd:
Port、PermitRootLogin、PasswordAuthentication、authorized_keys(root 与所有 UID≥1000) last/lastb/journalctl -u ssh:异常登录;无交互登录却出现 docker run 也是入口信号- sudoers、
docker组(= root)、NOPASSWD - 对公网的管理面:Portainer / Cockpit / 面板 / k8s apiserver / Docker 端口,尤其
-p 0.0.0.0:…且挂了docker.sock或/:/host - 单元文件或 compose 里的明文 token(k3s
--token、agent secret)
3. 持久化
读 references/persistence.md。至少查:
- crontab(root 与所有用户)、
/etc/cron.* /etc/systemd/system/*.service、timers/etc/ld.so.preload(用外部 cat/hexdump,宿主机 cat 可能被藏空)chattr +i的异常二进制(lsattr)- 隐藏 Docker 数据根(非
/var/lib/docker的 dockerd--data-root)
4. 进程与隐藏库
- 从特权容器列
/proc/*/cmdline(绕过 preload) - 对照宿主机
ps:只在容器视角出现的进程 = 隐藏 /proc/*/maps是否映射陌生.so(libgcwrap、libprocesshider、随机名)- 矿机常见名:
perfcc、xmrig、kdevtmpfsi、javavm64;同体积多副本(例如都是 11MB) - hugepage:
grep Huge /proc/meminfo。nr_hugepages>0且进程列表对不上,多半是矿机预留
5. 容器与编排
docker ps -a:镜像名含 earnfm / packetstream / repocket / traffmonetizer / honeygain / proxyrack / bitping / antgain 等挂机池- inspect:
Privileged、Binds(docker.sock、/:/host)、Ports 是否0.0.0.0 - 第二套 dockerd / 异常
--bridge - k8s:节点上是否有与 Git 仓库无关的 workload;控制面不健康时从 kubelet
pods/*/etc-hosts读 Pod 名
6. 对外暴露
- 本机
0.0.0.0/[::]监听 - 从另一台机器探测公网 IP(含 IPv6)。只看
ss会漏安全组,只看安全组会漏「监听但没防火墙」 - 高危:
rpcbind :111、明文 HTTP 应用端口、Docker/Portainer、k8s 6443、数据库 - 管理 SSH 若可走 Tailscale,公网 SSH 算多余攻击面
7. 资源与日志
- 无 swap + 高 hugepage → 应用易 OOM
journalctl/auth.log在处置时间点附近;日志空也要记- 出站连接:
ss -tp看陌生 IP(不要把结果里的密钥打出来)
8. 补漏(本次 vvps2 没做或做得浅的)
见 checklist 后半:补丁、SUID、世界可写、意外用户、IPv6、定时器、内核模块、出站 C2、云安全组、备份是否可用。
报告格式
先给结论(是否沦陷、最可能入口、对外还开着什么),再给证据表,最后给 需用户点头的处置清单。不要默默清理。
结论: 沦陷 / 可疑 / 未见异常
最可能入口: …
对外端口: …
持久化: …
隐藏/矿机: …
容器/编排: …
未查项: …
建议处置: (等确认)
处置(仅在用户同意后)
- 停并删除未授权容器;镜像也删
- 矿机二进制:删掉后用 空文件 +
chattr +i占路径 - 清空并锁定
/etc/ld.so.preload - 关公网绑定:改成
127.0.0.1或 Tailscale IP(若回源走 Tailscale 主机名,必须绑 TS IP,不能只绑 loopback) - 停无用服务(如
rpcbind.socket+rpcbind.service,必要时 mask) - 重启才能卸掉仍映射已删
.so的老进程(sshd/dockerd)。先取证再重启 - 轮换:暴露过的 token、面板、k3s bootstrap。控制面 API 不通就不要假轮换,写阻塞原因
验证
- 公网探测:已关端口失败;该留的业务域名仍 200
ss:无0.0.0.0:已关端口grep -l libgcwrap /proc/*/maps(或同类库)重启后为 0- 占位文件仍在且 immutable
- 业务容器
restart: always仍在