LinkPro Rootkit:在受感染AWS环境中发现的基于eBPF的GNU/Linux后门
发现概述
Synacktiv的安全研究人员调查AWS托管基础设施入侵事件时,发现了一个复杂的GNU/Linux rootkit,命名为LinkPro。攻击者最初通过利用暴露的Jenkins服务器漏洞CVE-2024-23897获得访问权限,并将恶意Docker镜像(kvlnt/vv,已被移除)部署到多个Kubernetes集群。
LinkPro是一个Golang后门,通过安装两个eBPF模块(Hide和Knock)实现内核级隐身和灵活的命令与控制(C2)。当eBPF模块安装失败时,它会通过捆绑的libld.so回退到ld.so.preload技巧。该后门支持主动(正向)和被动(反向/敲门激活)两种模式,并为C2实现了多种传输协议。
初始访问与传播链
Synacktiv的分析显示事件发展过程如下:
- 攻击者利用暴露的Jenkins服务器漏洞CVE-2024-23897获得初始立足点
- 他们将恶意Docker Hub镜像(kvlnt/vv,基于Kali)推送到Kubernetes节点,该镜像包含:
- start.sh — 启动SSH和payload的脚本
- link — 开源VPN/代理(vnt),用于通过vnt.wherewego[.]top:29872提供远程代理访问
- app — Rust下载器(“vGet”),从S3存储桶获取加密的vShell payload并通过WebSocket连接回C2(56.155.98[.]37)
- 投放到节点的额外payload包括第二个vShell后门和Golang rootkit LinkPro
LinkPro架构与模式
LinkPro以两种互补模式运行:
正向(主动)模式:植入程序使用五种支持的协议之一(HTTP、WebSocket、UDP、TCP或DNS)直接发起与操作者C2的连接。
反向(被动/敲门)模式:LinkPro安装Knock eBPF模块,监控传入TCP流量中的"魔法数据包"(TCP窗口大小=54321的数据包)。检测到后,Knock模块保存源IP并打开一个一小时的窗口,在此期间操作者可以在任意选择的端口上回连到主机。Knock模块还重写数据包头(目标/源端口)将操作者数据包路由到LinkPro的内部监听器(端口2333),同时掩盖原始前端防火墙端口——使日志关联复杂化。
持久性通过安装systemd服务实现,如果eBPF模块安装失败或被禁用,LinkPro将安装共享库libld.so并将/etc/libld.so添加到/etc/ld.so.preload作为备用隐身机制。
隐身机制 — eBPF + ld.so.preload
LinkPro的隐藏机制显著且多层:
Hide eBPF模块:安装Tracepoint和Kretprobe eBPF程序,拦截系统调用(如getdents)以隐藏文件/进程,并拦截sys_bpf调用以隐藏BPF程序本身。这实现了内核级隐藏而无需修改内核模块。(此技术需要内核配置CONFIG_BPF_KPROBE_OVERRIDE;如果不存在,LinkPro使用ld.so技术。)
Knock eBPF模块:使用XDP和TC eBPF程序检测和操作数据包以实现魔法数据包激活,并透明地重写端口。
/etc/ld.so.preload + libld.so:备用机制通过ld.so.preload注入libld.so,使该库被加载到所有动态链接的进程(如/usr/bin/ls)中。libld.so挂钩libc函数以修改输出(文件列表、进程列表、网络套接字),使用户模式工具无法显示rootkit。在基于信号的关闭(SIGHUP、SIGINT、SIGTERM)时,LinkPro移除eBPF模块并恢复ld.so.preload。
功能与操作者特性
LinkPro为操作者提供简洁但强大的命令集:
- 生成交互式shell(在伪TTY中的/bin/bash)
- 执行任意shell命令
- 枚举文件和目录,执行文件I/O操作
- 从攻击者控制的源下载文件到主机
- 建立SOCKS5代理隧道,通过受感染主机进行流量转发和代理
初始部署链还包括vnt VPN/代理组件和Rust下载器,从云存储获取vShell payload并建立WebSocket C2连接。
网络与操作规避
Synacktiv强调了两个值得注意的操作规避点:
- 魔法数据包激活+端口重写 — 允许操作者通过允许的防火墙端口访问,并混淆边界日志和主机活动之间的关联
- 基于BPF的隐藏 — 在内核级别隐藏文件和进程工件,并可拦截日志记录或跟踪尝试;当内核功能不可用时,ld.so技术通过libc挂钩在用户空间隐藏工件
检测指标(来自报告)
从Synacktiv的发现中提取的示例 — 将这些作为分类的起点:
- 恶意Docker镜像:kvlnt/vv(已从Docker Hub移除)
- VPN/代理域:vnt.wherewego[.]top:29872
- C2 WebSocket IP:56.155.98[.]37
- 镜像中观察到的文件:start.sh、link、app(vGet下载器)
- LinkPro工件:libld.so(通过/etc/ld.so.preload安装的路径)、用于持久化的systemd服务条目
- LinkPro监听端口:2333(内部)和代理端口实验中使用的2233用于头部转换
- 相关的内核配置:CONFIG_BPF_KPROBE_OVERRIDE(某些BPF隐藏功能所需)
注意:组织应将这些IoC视为敏感信息,并将其与自己的遥测数据结合使用。攻击者基础设施中的IP/域可以快速更改。
检测与事件响应指南
由于LinkPro力求在内核和用户空间级别实现隐身,防御者应使用多样化的遥测源,并假设仅用户空间工具可能不可靠:
即时分类步骤
- 隔离受影响的主机并快照内存+磁盘以进行取证分析
- 查找意外的systemd服务;检查/etc/ld.so.preload中的意外条目并验证/lib/ld-linux*和相关库的完整性
- 在系统路径中搜索libld.so和其他意外的共享库
- 检查集群上运行的容器镜像中的kvlnt/vv或未知镜像;审查最近的镜像拉取和Kubernetes部署事件
- 关联前端防火墙日志,查找围绕魔法包启发式(异常TCP窗口大小54321可能是指标)显示异常端口映射的入站流量
搜寻基于BPF的隐身
- 查询主机上的内核BPF程序列表(bpftool prog)(需要特权访问)并与已知良好基线比较 — 注意LinkPro尝试隐藏BPF程序,因此此检查应从受信任的取证环境或离线快照执行,攻击者的钩子无法干扰
- 检查内核审计日志和dmesg中的BPF程序加载或XDP/TC更改
- 使用带外监控(虚拟机监控程序/容器运行时,转发到远程SIEM的主机日志)检测进程列表与观察到的套接字/连接之间的差异
遏制与修复
- 撤销提供初始访问的凭据(Jenkins服务账户、受损的VPN凭据、权限过高的AD服务账户)。轮换在受损存储库或配置中发现的密钥和令牌
- 在擦除后从已知良好镜像重建受感染主机;如果存在持久的内核或加载器钩子,不要依赖原地清理
- 从注册表中移除任何恶意容器镜像,并审计CI/CD流水线和镜像构建/部署工作流中的供应链滥用
- 如果使用了BPF程序且内核完整性可疑,更新/重新启动内核并确保从受信任源恢复内核模块和配置
- 轮换所有可能已暴露的凭据(SSH密钥、API密钥、云角色)
缓解与加固建议
- 修补和加固CI/CD端点:关闭或修补暴露的Jenkins实例(CVE-2024-23897)并限制对构建系统的未认证访问
- 加固容器注册表和镜像流水线:强制执行镜像签名、扫描和最小权限部署;限制拉取任意镜像的能力
- 加固Kubernetes集群:使用网络分段、Pod安全策略/OPA/Gatekeeper、限制节点访问并审计RBAC角色
- 出口和防火墙策略:强制执行严格的出口规则并记录所有NAT连接;在可行的情况下考虑TLS检查以检测隐蔽C2
- BPF可见性:尽可能启用集中式内核遥测并将BPF程序加载事件集成到SIEM/更广泛的监控中
- 不可变基础设施:对于怀疑存在内核级泄露的系统,优先选择重建而非修复
- 凭据卫生:移除权限过高的服务账户,应用JIT/JEA,并在泄露后轮换密钥
- 备份与恢复:确保备份离线/不可变并经过测试