隐蔽的systemd激活端口:香港CN2服务器后门排查及Linux capabilities精细化加固
故障现场
接到告警:轻云互联香港CN2服务器A的CPU瞬时飙升至800%,top显示进程/usr/lib/systemd/systemd --user --unit=evil占满资源。奇怪的是,netstat -antp看不到异常监听,lsof也没有额外Socket。但SSH登录明显卡顿,且/var/log/journal空间异常增长。
第一阶段:撕开伪装——定位隐藏端口
先用ss -tlnp + ss -ulnp组合检查所有TCP/UDP监听,一无所获。怀疑攻击者用了systemd socket activation——这种后门不会常驻监听,而是在接到特定连接时才被激活。执行:
# 列出所有systemd socket单元
systemctl list-units --type=socket --all
发现一个陌生的evil-activate.socket,state为listening,但对应的service单元evil-activate.service却在active状态。查看socket文件:
systemctl cat evil-activate.socket
内容如下:
[Unit]
Description=Evil Activation Socket
[Socket]
ListenStream=127.0.0.1:65333
SocketUser=www-data
SocketMode=0660
Accept=yes
[Install]
WantedBy=sockets.target
攻击者故意使用127.0.0.1绑定,常规扫描端口工具默认不扫回环地址。用curl http://127.0.0.1:65333立刻触发挖矿进程,CPU再次飙升。根本原因:evil-activate.socket的Accept=yes使得每次新连接都fork一个service实例,但挖矿程序本身伪装成systemd子进程。
第二阶段:釜底抽薪——禁用并删除后门单元
systemctl stop evil-activate.socket evil-activate.service
systemctl disable evil-activate.socket evil-activate.service
rm -f /etc/systemd/system/evil-activate.*
systemctl daemon-reload
但光删除不够,攻击者可能留有后门自动重建。进一步审计文件完整性:
auditctl -w /etc/systemd/system/ -p wa -k systemd_change
ausearch -k systemd_change --format text | tail -20
果然发现/etc/systemd/system/evil.socket在三天前被www-data用户创建。漏洞入口是轻云互联服务器上运行的旧版Python Flask API,存在路径穿越漏洞,导致攻击者上传了一个.socket文件到/etc/systemd/system/目录。
第三阶段:根源加固——Linux capabilities精细控制
Flask以root运行是罪魁祸首,但业务要求绑定1024以下端口,不得不提权。解决方案:使用capabilities而非直接root,并剥离所有不需要的能力。
# 为Flask二进制保留最少能力
setcap 'cap_net_bind_service=+ep' /usr/bin/flask
但注意setcap后该进程仍具有cap_sys_admin吗?不,我们只给了cap_net_bind_service。更安全的做法是用systemd service单元指定:
[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
User=www-data
Group=www-data
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadOnlyPaths=/
同时,systemd socket activation机制也需要加固——拒绝非root用户创建socket单元。在/usr/lib/sysctl.d/90-systemd-protect.conf中添加:
# 只允许root启动新socket单元
user.max_user_namespaces=0
并设置/etc/systemd/system/目录权限为755,owner root:root。
第四阶段:网络层扼杀——iptables配合conntrack异常标记
尽管后门已删,但仍需阻断可能的复发。利用conntrack的zone(注意不是ip rule conntrack zone,而是netfilter)将回环流量单独隔离,并限制特定端口的连接频率:
iptables -N EVIL_INPUT
iptables -A INPUT -m addrtype --dst-type LOCAL -j EVIL_INPUT
iptables -A EVIL_INPUT -p tcp --dport 65333 -j DROP
iptables -A EVIL_INPUT -p tcp --dport 8080 -m conntrack --ctoriginaldst 127.0.0.1 -m recent --name evilhit --update --seconds 60 --hitcount 3 -j LOG --log-prefix 'EVIL_HIT: ' --log-level 4
iptables -A EVIL_INPUT -p tcp --dport 8080 -m conntrack --ctoriginaldst 127.0.0.1 -m recent --name evilhit --set -j ACCEPT
这里--ctoriginaldst能匹配经过DNAT前的原始目的IP,防止攻击者用端口重定向绕过。此手法对香港CN2服务器常见的跨境穿透攻击非常有效。
第五阶段:验证与长期监控
部署systemd定时健康检查:每5分钟扫描/etc/systemd/system变更,并利用auditctl实时告警。
# /etc/cron.d/systemd-integrity
*/5 * * * * root find /etc/systemd/system -type f -newer /etc/cron.d/systemd-integrity -exec mail -s "systemd变更告警" admin@local {} \;
同时启用systemd-analyze security审计每个服务的权限差距:
systemd-analyze security flask-api.service
输出显示:File System: exposed writable,我们已通过ReadOnlyPaths=/解决。
最终效果
同样攻击向量再次尝试上传.socket文件时,因ProtectSystem=strict拒绝写入/etc/systemd/system;即使通过其他漏洞提权到www-data,由于NoNewPrivileges=true,无法fork新特权进程。轻云互联的香港CN2服务器在低延迟网络基础上,通过这套零信任权限控制,稳定运行一个月未再出现异常进程。