Помимо перехвата системных вызовов, данный руткит использует механизм ftrace для установки хуков на заранее определенный набор функций ядра Linux. Адреса этих функций вычисляются динамически с помощью ранее полученного указателя на kallsyms_lookup_name. Вычисленные адреса используются для корректной установки хуков.
Руткит дополнительно анализирует каждую целевую функцию, определяя в ее коде участок, наиболее подходящий для внедрения хука. После чего с помощью функций ftrace_set_filter_ip и register_ftrace_function регистрирует обработчик, перенаправляющий выполнение функций на их подмененную реализацию.
Полный перечень функций ядра, подвергающихся перехвату, можно разделить на две группы: полностью отключаемые руткитом и те, поведение которых переопределяется. В первую группу входят функции, связанные с механизмами контроля доступа: selinux_file_open, selinux_file_permission, avc_has_perm, file_map_prot_check, selinux_inode_setattr, selinux_inode_permission, selinux_socket_bind и selinux_socket_connect. Обработчики для них полностью заменяют оригинальную логику на простую заглушку, которая всегда завершает выполнение без ошибок (return 0). В итоге любые проверки или действия, которые должны были выполняться, фактически отключаются, поскольку система считает, что они завершились успешно.
Ко второй группе относятся функции sk_diag_fill, tpacket_rcv, tcp4_seq_show, kernel_clone или _do_fork (в зависимости от версии модуля PUMAKIT), а также nf_hook_slow. В более поздних версиях к этому списку добавляется функция inet_sk_diag_fill. Обработчики для каждой из них не блокируют выполнение оригинального кода полностью, а осуществляют предварительный анализ входных аргументов. Во всех перечисленных случаях обработчики извлекают IP-адрес из передаваемых в функцию аргументов и сравнивают их с внутренним списком IP-адресов, хранящимся в структуре руткита (см. рис. 19 и 20). Если среди переданных аргументов обнаруживается совпадение с одним из имеющихся в структуре адресов — оригинальная функция ядра не вызывается, а обработчик вместо этого сразу возвращает нулевой результат, тем самым подавляя выполнение исходной функции. Такой механизм переопределения позволяет эффективно скрывать нелегитимные подключения, процессы и сетевую активность, обеспечивая их невидимость для средств мониторинга и анализа.
Особого внимания заслуживает функция nf_hook_slow, поскольку перехват ее вызова позволяет злоумышленнику обойти работу файрвола на уровне ядра, исключая проверку пакетов механизмами фильтрации.
В стандартной реализации Netfilter функция nf_hook_slow выполняет последовательный вызов всех зарегистрированных в ядре хуков, включая обработчики iptables и nftables. Именно эти хуки принимают окончательное решение о том, пропустить, заблокировать или перенаправить пакет.
Однако в данном случае внедренный обработчик анализирует пакет до его передачи в оригинальную функцию, извлекая исходный и целевой IP-адреса и сравнивая их с внутренним списком, хранящимся в рутките. Если хотя бы один из них совпадает — обработчик возвращает NF_ACCEPT (1), сразу принудительно разрешая прохождение пакета без его передачи в nf_hook_slow.
Такой подход позволяет атакующему полностью скрывать трафик от механизмов мониторинга и обходить политики файрвола, поскольку пакеты, принудительно принимаемые обработчиком, минуют стандартные процессы фильтрации и анализа. Таким образом, файрвол не имеет возможности зафиксировать, проанализировать или заблокировать такой трафик. В результате злоумышленник может беспрепятственно устанавливать скрытые соединения, не оставляющие следов в системах мониторинга и журналирования, полностью избегая наложенных ограничений безопасности.