rhzv0/bat

GitHub: rhzv0/bat

BAT 是一个集成了 C2 通信、内核级 rootkit、进程注入和横向移动的 Linux 高级威胁模拟平台,旨在为安全研究提供最逼真的对手行为模拟能力。

Stars: 32 | Forks: 5

# 行为对抗追踪器 (BAT) banner0 **BAT** 是一个针对 Linux 和 Windows 的逼真、不断演进的对手威胁模型。它不是一个 C2 框架,也不是一个 rootkit。它是一个完整的威胁模拟平台,将 C2 通信、内核级隐蔽 rootkit 模块、用户态规避、权限提升、持久化、进程注入、凭据窃取、数据窃取和横向移动整合为一个单一的、紧密结合的对手。设计目标是在 2026 年实现最复杂、最逼真的 Linux 威胁,而不受任何检测系统当前捕获能力的限制。 它是一对研究组合中的对手方。Aura 框架不断发展以检测 Bat。Bat 不断发展以规避 Aura。对手永远不会受到检测器的约束。 ss ## 快速开始 ### 1. 前置条件 ``` apt install nasm gcc-x86_64-linux-gnu binutils-x86_64-linux-gnu golang-go go install mvdan.cc/garble@latest ``` ### 2. 配置 ``` cp build.env.example build.env nano build.env # RELAY_IP, SECRET, BAT_KEY, CDN_DOMAIN ``` 生成一个密钥:`openssl rand -hex 16` ### 3. 构建 ``` ./build.sh # garble agent (x86_64+arm64) + server (arm64) + netshell ./build.sh agent # agent only ./build.sh server # server arm64 only (EC2 / Mac M-series) ./build.sh server-amd64 # server x86_64 only (PC Intel/AMD) ./build.sh netshell # netshell only ``` 二进制文件存放在 `bin/` 中。 ### 4. 引导中继 ``` # 在 relay VPS 上(以 root 身份) sudo bash -s -- --tg-token $TG_TOKEN --tg-chat-id $TG_CHAT_ID < relay/setup.sh # 从 operator machine source build.env relay/sync.sh ubuntu@$RELAY_IP --key $BAT_KEY --restart-kcc --tg scp -i $BAT_KEY bin/netshell-v11-{x86_64,arm64} ubuntu@$RELAY_IP:/var/www/nexus/agents/ ``` ### 5. 运行 ``` ./bin/bat-server-v11-arm64 # tunnel starts automatically, no flags needed ``` 在目标上部署 agent: ``` sudo setsid /path/to/bat-agent-v11-x86_64 /tmp/.log 2>&1 & disown ``` Agent 将在一个心跳间隔内(默认为 30 秒),以 `@` 的形式出现在 `bat-server` 中。 ## Linux 隐蔽层:[Singularity](https://github.com/MatheuZSecurity/Singularity) 内核隐蔽层(`bat-stealth.ko`,源码位于 `kperf-qos/`)直接构建在 **Singularity** 之上,这是一个高级的内核 rootkit 研究框架。移植并适配了四个核心模块: **`bpf_hook`**:拦截 `bpf(2)` 和所有 eBPF 通信原语。任何 eBPF 传感器接收到的关于隐藏 PID 的遥测数据均为零。适配点:`ARCH_SYS("bpf")` 替换了仅限 x86 的 `__x64_sys_bpf`;为 ARM64 移除了 `__ia32_sys_bpf`;`HIDDEN_PORT` 被替换为可通过 sysfs 配置的全局变量。 **`hiding_fs`**:完全的文件系统擦除:`getdents64`/`getdents` 过滤,`stat`/`statx`/`newfstatat` nlink 调整,`openat`/`access`/`faccessat` 对 `/proc/` 的阻断,以及 chdir 和 readlink 阻断。合并自 Singularity 的五个模块(`hiding_directory`、`hiding_stat`、`open`、`hiding_chdir`、`hiding_readlink`)。适配点:`REGS_ARGn` 宏替换了直接寄存器访问;`should_hide_path()` 为运行时配置的 `bat_hidden_paths[]` 进行了扩展。 **`hide_module`**:将 `bat-stealth.ko` 从所有内核模块列表中移除。扩展点:Singularity 已经保存了 `list.prev`;此版本同时保存了 `list.prev` 和 `list.next`,并对它们进行投毒以阻止双向遍历。添加了 `module_unhide()` 用于可逆移除,这是 K-99 在 `delete_module(2)` 能够按名称定位模块之前所需的。 **`lkrg_bypass`**:抑制 LKRG 对隐藏进程的执行:挂钩信号传递以阻止向隐藏任务发送 `SIGKILL`,挂钩 `vprintk_emit` 以丢弃 LKRG 日志消息,在 agent 执行期间禁用 UMH 验证。直接移植,无架构更改。 以下模块是独立开发的: - `become_root`:通过信号 59 挂钩调用 `commit_creds(prepare_kernel_cred(NULL))` 以授予 uid=0 (K-03) - `selfdefense`:阻止 LiME 内存获取,隐藏 kallsyms 条目,阻止对 agent 符号的 kprobes,在任何枚举尝试时重新隐藏模块 - `audit`:抑制隐藏 PID 的 auditd 事件 - `sysrq_hook`:拦截 SysRq-T 以将隐藏进程从任务转储中排除 - `taskstats_hook`:过滤隐藏 PID 的 NETLINK taskstats 响应 - `reset_tainted` + `clear_taint_dmesg`:将 `/proc/sys/kernel/tainted` 清零,并过滤包含模块加载证据的 dmesg 行 - `hooks_write`:拦截所有内核写入路径(write/splice/sendfile/tee + io_uring_enter/enter2 + ia32 compat),以在匹配 agent 字符串的日志条目到达 syslog 或 journald 之前将其丢弃 - `pid_manager`:fork tracepoint,用于在子进程间维护隐藏 PID 集合 完整的技术栈使得 agent 及其所有工件对以下内容不可见:`ps`、`top`、`ss`、`netstat`、`lsof`、隐藏路径上的文件系统遍历、`lsmod`、sysfs、kallsyms、auditd、所有 eBPF 传感器、LKRG、LiME 和 SysRq 取证。 ## MITRE ATT&CK 覆盖范围 | ATT&CK ID | 技术 | Bat 实现 | |---|---|---| | T1036.005 | 伪装:匹配合法名称 | TTP 1:通过 `prctl(PR_SET_NAME)` 设置为 `kworker/0:1` | | T1055 | 进程注入 | TTP 11:将 shellcode + rawsock 线程注入到活动进程中 | | T1205.001 | 流量信令(魔数数据包) | UDP/ICMP 触发器将 agent 从休眠状态唤醒 | | T1071.001 | Web 协议 C2 | 通过 :443 或 :9443 的 HTTPS 信标 | | T1573.001 | 加密通道:对称加密 | 通过 TLS 的 HMAC-SHA256 认证信标 | | T1090.004 | 代理:域前置 | CDN 配置文件将 agent 流量路由通过边缘代理层 | | T1574.006 | 劫持执行:LD_PRELOAD | TTP 10:通过 `/etc/ld.so.preload` 加载 `bat-rootkit.so` | | T1014 | Rootkit | `bat-stealth.ko`:隐藏 PID、端口、文件、模块及其自身 | | T1562.001 | 破坏防御:禁用工具 | `bpf_hook` 致盲 eBPF 传感器;`lkrg_bypass` 禁用 LKRG | | T1562.012 | 破坏防御:禁用 Linux 审计 | `audit` 模块抑制隐藏 PID 的 auditd 事件 | | T1068 | 利用漏洞进行权限提升 | K-03:信号 59 触发 `commit_creds` 将 uid 提升至 0 | | T1543.002 | 创建/修改系统进程:Systemd | TTP 6:systemd unit 持久化 | | T1053.003 | 计划任务:Cron | TTP 6:crontab 持久化 | | T1070.002 | 清除 Linux 日志 | `clear_taint_dmesg` 过滤 dmesg;`reset_tainted` 将 taint 标志清零;`hooks_write` 在内核中丢弃日志条目 | | T1070.004 | 清除痕迹:文件删除 | TTP 222 销毁:完整的工件擦除 | | T1003 | 凭据转储 | TTP 7/23:`/etc/shadow`、shell 历史、环境变量秘密 | | T1552.004 | 不安全的凭据:私钥 | TTP 21:SSH 密钥、known_hosts、配置文件 | | T1552.005 | 云实例元数据 | TTP 23:AWS IMDS 凭据窃取 | | T1018 | 远程系统发现 | TTP 20/34:ARP 枚举 + /16 CIDR 扫描 | | T1046 | 网络服务扫描 | TTP 20/34:对已发现主机的 TCP 端口扫描 | | T1021.004 | 通过 SSH 横向移动 | TTP 22/35:通过 SCP 将自身复制到已发现的主机,脱离终端执行 | | T1078 | 有效账户 | TTP 22/35:横向移动使用窃取的 SSH 密钥 | | T1048 | 通过替代协议外传数据 | TTP 30/31/32:通过信标通道进行文件和目录窃取 | | T1059.004 | Unix Shell 执行 | TTP 4:任意命令执行 | | T1027 | 混淆文件或信息 | garble `-literals -tiny -seed=random`;XOR(0x5A) 配置编码 | | T1620 | 反射式代码加载 | TTP 11:在目标进程地址空间中执行 shellcode;通过 `memfd_create` 加载 `bat-stealth.ko` | ## 系统架构 ``` Target Relay (VPS) Operator (local) bat-agent --HTTPS:443--> nginx:443 -> :8443 --tunnel--> bat-server:9443 --TCP:9443 --> sshd:9443 --tunnel--> --UDP/ICMP --> (trigger forwarded) bat-agent --HTTPS:9444-> kcc-server:9444 (kernel compile) ``` | 组件 | 角色 | |---|---| | `bat-agent` | Agent。发送信标,执行 TTP。经过 Garble 混淆。 | | `bat-server` | 操作员控制台。交互式 CLI。管理所有 agent。 | | `netshell` | 交付二进制文件。看起来像系统工具;实际上是一个完整的 agent。 | | `bat-rootkit.so` | LD_PRELOAD 用户态 rootkit。隐藏文件、PID、端口、环境变量。 | | `bat-stealth.ko` | 内核隐蔽层(基于 Singularity)。 | | `kcc-server` | 中继服务。按需为目标正在运行的内核编译 `bat-stealth.ko`。 | | `relay/` | 中继基础设施:nginx、TLS、设置、同步、交付脚本。 | ## 已绕过的防御机制 | 类别 | 防御 | 绕过机制 | |---|---|---| | 进程监控 | `ps` / `top` / `/proc` 列表 | `hiding_procs.c`:`getdents64` 挂钩在用户态读取之前将 agent PID 条目从 procfs 中移除 | | 进程监控 | `/proc//status`、`/proc//cmdline` | `hiding_procs.c`:`filldir` 挂钩从所有 readdir 结果中过滤 PID 前缀 | | 文件系统 | 针对代理文件和目录执行 `ls` / `find` | `hiding_fs.c`:针对目标路径的 `getdents64`/`getdents` 挂钩;stat nlink 已调整为匹配 | | 文件系统 | `lsattr` / `chattr` 检测 | `hiding_fs.c`:对代理文件路径的 `ioctl` 拦截 | | 文件系统 | `/proc/modules` / `lsmod` 列表 | `hiding_module.c`:从所有 sysfs 和 procfs 模块列表中移除 `bat-stealth.ko` 条目 | | 网络 | `ss` / `netstat` 端口列表 | `hiding_net.c`:`tcp4_seq_show`/`tcp6_seq_show` 挂钩从输出中剥离 C2 端口条目 | | 网络 | `/proc/net/tcp`、`/proc/net/tcp6` | `hiding_net.c`:seq_file 读取拦截丢弃 C2 套接字行 | | 日志 | `syslog` / `journald` 写入路径 | `hooks_write.c`:`write`/`splice`/`sendfile`/`tee` 拦截;匹配 agent 字符串的日志条目在内核中被丢弃 | | 日志 | `io_uring` 异步写入路径 | `hooks_write.c`:拦截 `io_uring_enter`/`io_uring_enter2`;覆盖 ia32 兼容路径 | | 内核安全 | `rkhunter` / `chkrootkit` | 模块从 `/proc/modules` 中隐藏;代理文件从文件系统中隐藏;已验证零警告 | | 内核安全 | ClamAV | Garble `-literals -tiny` 混淆 + 无嵌入明文字符串;已验证 0 检出 (DB 2026-04-20) | | EDR / eBPF | 基于 eBPF 的传感器读取 `/proc` | 隐藏挂钩在生成 eBPF 环形缓冲区事件之前在内核级别进行拦截 | | 内省 | 针对 agent 符号的 `ftrace` / `kprobes` | `selfdefense` 模块阻止在 agent 函数地址上附加 kprobe | | 内核取证 | LiME 内存获取 | `selfdefense` 阻止 LiME 模块加载和原始内存设备访问 | | 内核取证 | SysRq-T 任务转储 | `sysrq_hook` 将隐藏进程从 SysRq-T 写入的任务列表中排除 | | 内核取证 | NETLINK task | `taskstats_hook` 过滤隐藏 PID 的 taskstats NETLINK 响应 | | 内核完整性 | LKRG 强制执行 | `lkrg_bypass` 抑制 LKRG `SIGKILL` 传递并丢弃 LKRG 日志消息 | | 审计子系统 | `auditd` 系统调用记录 | `audit` 模块在内核审计层抑制所有隐藏 PID 的审计事件 | ## 系统调用挂钩 所有挂钩均由 `bat-stealth.ko` 在加载时通过 ftrace 安装。ia32 条目仅在 x86_64 上编译(`#ifdef ARCH_SYS_IA32`)。 | 系统调用 / 函数 | 模块 | 目的 | |---|---|---| | `getdents64` | `hiding_procs.c` | 从 `/proc` 目录列表中隐藏 agent PID | | `getdents` | `hiding_procs.c` | 32 位兼容:隐藏 agent PID | | `filldir` (readdir) | `hiding_procs.c` | 针对遗留 readdir 调用者的补充 proc 条目过滤器 | | `getdents64` | `hiding_fs.c` | 从目录列表中隐藏 agent 文件 | | `getdents` | `hiding_fs.c` | 32 位兼容:隐藏 agent 文件 | | `ia32_getdents64` | `hiding_fs.c` | x86 兼容系统调用 | | `ia32_getdents` | `hiding_fs.c` | x86 兼容系统调用 | | `ia32_stat` / `ia32_lstat` / `ia32_fstat` | `hiding_fs.c` | 针对隐藏路径的 32 位 stat 拦截 | | `ia32_open` / `ia32_openat` / `ia32_access` | `hiding_fs.c` | 32 位 open/access 拦截 | | `ia32_readlink` | `hiding_fs.c` | 32 位 readlink 拦截 | | `ia32_chdir` | `hiding_fs.c` | 32 位 chdir 拦截 | | `ioctl` | `hiding_fs.c` | 拦截代理路径上的 `lsattr`/`chattr` ioctl | | `tcp4_seq_show` | `hiding_net.c` | 从 `/proc/net/tcp` 中隐藏 C2 端口条目 | | `tcp6_seq_show` | `hiding_net.c` | 从 `/proc/net/tcp6` 中隐藏 C2 端口条目 | | `bpf` | `bpf_hook.c` | 将所有 eBPF 程序中隐藏 PID 的遥测数据置零 | | `write` | `hooks_write.c` | 在包含 agent 字符串的日志条目到达 syslog 之前将其丢弃 | | `splice` | `hooks_write.c` | 通过 splice 路径进行相同拦截 | | `sendfile` | `hooks_write.c` | 通过 sendfile 路径进行相同拦截 | | `tee` | `hooks_write.c` | 通过 tee 路径进行相同拦截 | | `io_uring_enter` | `hooks_write.c` | io_uring 异步写入拦截 | | `io_uring_enter2` | `hooks_write.c` | io_uring 异步写入拦截(v2 系统调用) | | `sched_process_fork` (tracepoint) | `pid_manager.c` | 在 `fork`/`clone` 之间继承隐藏状态 | | `vprintk_emit` | `lkrg_bypass.c` | 丢弃 LKRG 内核日志消息 | | `finit_module` / `init_module` | agent (kcc loader) | 通过 `memfd_create` + 匿名 fd 进行无文件内核模块加载 | ## TTP 参考 | TTP | 名称 | 描述 | |---|---|---| | 1 | masquerade | 将进程 comm 重命名为 `kworker/0:1`(或自定义) | | 2 | reverse_shell | 到 relay:4445 的反向 TCP shell | | 3 | memory_rwx | 分配匿名 RWX 内存(检测探针) | | 4 | shell_exec | 执行任意 shell 命令 | | 5 | beacon | 强制立即进行额外签入 | | 6 | persist | 安装持久化(cron / systemd / rc.local / openrc / profile / XDG autostart) | | 7 | creddump | 窃取 `/etc/shadow`、bash 历史、环境变量机密、AWS IMDS | | 9 | exec_chain | 生成进程链(检测探针) | | 10 | install_rootkit | 通过 `/etc/ld.so.preload` 部署 `bat-rootkit.so` | | 11 | inject + exit | 将 beacon + rawsock 线程注入到活动进程中,然后自行退出 | | 20 | network_recon | ARP 表 + 本地子网的 TCP :22 扫描 | | 21 | ssh_harvest | 收集私钥、known_hosts、authorized_keys、配置文件 | | 22 | lateral_move | 通过 SSH 将自身 SCP 到已发现的主机,脱离终端执行 | | 23 | creddump_full | 扩展凭据窃取 + 环境指纹识别 | | 30 | exfil-file | 读取任意文件并通过信标通道以 base64 块传输 | | 31 | exfil-dir | 将目录打包为 Tar+gzip 并通过信标通道窃取 | | 32 | exfil-auto | 监视配置的路径并在更改时自动窃取 | | 34 | netmap | 扫描 /16 CIDR 以查找活动主机和开放端口 | | 35 | autospread | 使用窃取的密钥通过 SSH 横向移动到已发现的主机;复制 agent 并脱离终端执行 | | 36 | smbprobe | 用于横向移动候选目标的 SMB 端口探测 (:445) | | 99 | kill | 静默自终止 | | 222 | destruct | 移除所有工件,擦除内存,退出 | | 1003 | K-03 (privesc) | 内核信号 59 触发 `commit_creds` 将 uid 提升至 0 | | 1099 | K-99 (unload) | 通过 sysfs + 原始 `delete_module(2)` 进行两阶段的 `bat-stealth.ko` 卸载 | 控制台命令(在 `bat-server` 提示符下): - `kill`:向所有 agent 发送 TTP 99 - `destruct`:向所有 agent 发送 TTP 222 - `destruct @`:针对性擦除 ### KCC:内核编译缓存 `bat-stealth.ko` 是针对目标正在运行的内核按需编译的。Agent 在运行时自动化了整个流程;每个目标不需要预构建的模块: 1. **检测内核**:Agent 读取 `/proc/version` 以获取确切的 `uname -r` 字符串。 2. **请求编译**:Agent 使用 HMAC 签名的请求将内核字符串 POST 到 `kcc-server`(`:9444`)。 3. **kcc-server 编译**:服务器根据匹配的内核头文件构建 `bat-stealth.ko`,并按内核哈希值缓存结果。 4. **接收模块字节**:编译好的 `.ko` 在响应体中返回。 5. **无文件加载**:Agent 创建一个匿名内存文件(x86_64 上通过系统调用 279 / ARM64 上通过 319 的 `memfd_create`),写入模块字节,然后使用空参数字符串调用 `finit_module`(系统调用 273 / 313)。 6. **注册**:模块注册所有挂钩,并在几毫秒内从 sysfs/procfs 中隐藏自身。 在此过程中的任何时刻都不会将 `.ko` 文件写入磁盘。模块在加载后会立即从 `/proc/modules` 中消失。 **最低内核版本:** 6.x(K-00 探针;agent 在较旧内核上跳过隐蔽加载)。 **已测试:** 6.1.0 (Debian 12 / Ubuntu LTS)、6.8.0 (Ubuntu 22.04 GCP)。 ## 构建配置文件 ``` make lab SECRET= # direct: agent -> relay:9443, UDP trigger make cdn SECRET= # CDN: agent -> edge proxy -> relay:443 make singularity SECRET= # ICMP trigger only, no UDP port exposure ``` 所有配置文件都需要 `SECRET=`。使用 `RELAY=` 覆盖中继 IP。 ## 安全模型 - **HMAC 认证的信标**:每次签入都使用 `SHA-256(secret)` 进行签名;服务端拒绝重放。 - **双层配置混淆**:在代码生成阶段使用 XOR(0x5A) 编码,然后在编译阶段使用 garble `-literals` 加密。故意避免使用 `-X ldflags`(ldflag 的值会以明文形式出现在二进制文件中)。 - **操作端无监听端口**:所有连接都通过嵌入在 `bat-server` 中的 SSH 反向隧道出站流动。 - **SSH 密钥内置于服务端**:隧道密钥使用与 C2 配置相同的 XOR 编码进行编译。 ## 伪装页面 `relay/static/` 是中继的公开面孔。此发布版本附带了一个简单的占位符。在运行 `sync.sh` 之前,请将 `index.html` 和支持页面替换为您的伪装身份。交付脚本(`static/i`、`static/api/setup`、`static/api/v1/index.json`)使用 `__CDN_DOMAIN__` 作为占位符;在 `build.env` 中设置 `CDN_DOMAIN=`,`sync.sh` 将自动替换它。在首次部署 nginx 之前,请使用 `server_name` 中的真实域名和 TLS 证书路径更新 `relay/nginx/bat.conf`。 CDN 配置文件将 agent 流量路由通过边缘代理层。Agent 通过 HTTPS 连接到 CDN 域名;代理通过 SSH 反向隧道将流量转发到中继的本地监听器。从网络角度来看,所有 agent 流量都源自 CDN 边缘 IP 范围,而不是中继 VPS。 ### 通过 Telegram 的交付通知 tg --- 当目标从 CDN 端点获取代理二进制文件时,交付警报会立即发送到配置的 Telegram 频道。通知内容包括:源 IP、时间戳、请求路径、检测到的架构(x86_64/arm64)、文件大小、User-Agent 字符串和 CDN 边缘标识符。 `delivery-alert.service` 守护进程会持续跟踪 nginx 访问日志,并在访问诱饵下载路径时触发。在中继引导期间进行配置: ``` sudo bash -s -- --tg-token --tg-chat-id < relay/setup.sh ``` 凭据将写入中继上的 `/etc/bat/tg.env`,并通过 `sync.sh --tg` 传播到所有同步目标。该服务会自动启动并在中继重启后继续运行。 ## 免责声明 本软件专为授权的安全研究、受控实验室环境中的对手模拟以及检测与响应能力的开发而开发。它包含攻击性技术的功能实现,包括内核级 rootkit、进程注入、凭据窃取和横向移动。在大多数司法管辖区,未经系统所有者明确书面授权而在任何系统上部署本软件均属于非法行为,违反了适用的计算机欺诈和滥用法。 作者对因未经授权、疏忽或恶意使用本软件而导致的任何损害、法律后果或伤害不承担任何责任。使用本软件,即表示您确认您是在合法、授权的范围内操作的专业安全人员,并且对使用本软件承担全部法律和道德责任。 未经事先书面同意,不得将本软件重新分发、发布或披露给任何第三方。
标签:APT, C2通信, Conpot, DNS 解析, Docker镜像, evasion, EVTX分析, Golang, Go语言, IP 地址批量处理, PE 加载器, Rootkit, SSH蜜罐, Windows安全, Zeek, 内存分配, 内核级隐藏, 协议分析, 安全工具集合, 安全测试, 安全编程, 对手模拟, 攻击性安全, 攻击框架, 攻击路径可视化, 数据展示, 数据渗出, 日志审计, 权限提升, 横向移动, 汇编, 用户态规避, 程序破解, 紫队, 红队, 编程规范, 网络安全, 进程注入, 隐私保护, 高级持续威胁, 黑客工具