В Unix-подобных операционных системах, таких как Linux, BSD и Solaris, процессы играют ключевую роль в функционировании системы. Каждый процесс имеет своё название, которое служит для идентификации в списках запущенных программ и мониторинговых инструментах. Однако существует ряд техник, позволяющих изменять отображаемое имя процесса в системе, что часто используется как для законных целей — например, кастомизация или удобство администрирования, так и для скрытия вредоносной активности. Обходя стандартные способы выявления процессов, злоумышленники прибегают к модификации имён процессов, чтобы избежать обнаружения и централизации контроля. Понимание того, как это происходит под капотом, и методы обнаружения таких изменений актуальны как для системных администраторов, так и для специалистов по кибербезопасности.
Многие хорошо помнят одну из первых хитростей, применённых вредоносным ПО — червь Морриса, распространённый в конце 1980-х годов. Этот червь маскировался под оболочку shell, меняя argv[0], чтобы процесс выглядел как стандартный терминал, что позволяло ускользать от внимания администраторов. Суть техники достаточно проста: при запуске программы один из параметров — argv[0] — отвечает за отображаемое имя процесса, и оно может быть перезаписано с помощью простой функции strcpy. Однако этого недостаточно, поскольку путь к исполняемому файлу и имя процесса отображается не только через argv, но и через другие системные интерфейсы, такие как /proc/[pid]/comm. В современных системах Linux идентификация процессов и их атрибутов происходит через виртуальную файловую систему procfs.
Процесс имеет несколько представлений имени — cmdline, comm и exe. Cmdline отражает командную строку, переданную при запуске, comm — имя процесса, ограниченное 15 символами, а exe — символическую ссылку на фактический исполняемый файл. Изменение argv[0] влияет на cmdline и, соответственно, на результат работы командных утилит типа ps с параметрами по умолчанию. В то же время comm останется неизменным до тех пор, пока специально не будет вызвана системная функция prctl с опцией PR_SET_NAME. Таким образом, чтобы процесс был замаскирован надежно, нужно менять оба этих значения.
Однако просто переписать argv может быть опасно с точки зрения целостности процесса. Если новая строка будет длиннее исходной, можно повредить соседние области памяти, в том числе переменные окружения, что приведёт к нестабильной работе. Для безопасного изменения имён, особенно если оно предполагает увеличение длины имени процесса, применяется системный вызов prctl с опцией PR_SET_MM, который позволяет переназначить внутренние границы памяти, отведённой для аргументов, например в область кучи. Это требует более глубокого понимания структуры памяти процесса и зачастую — специальных прав или возможностей, таких как CAP_SYS_RESOURCE. Интересно, что для отечественных или нестандартных систем Linux такие методы уже давно являются частью цепочек обхода обнаружения и защиты.
Важное место занимает также несоответствие между comm и cmdline, которое само по себе может служить индикатором посткомпрометационных действий. Хотя на первый взгляд изменение имён кажется лёгкой задачей, с учётом различных способов отображения и странностей работы procfs, на самом деле это достаточно хитроумный процесс, который применяют и современные вредоносные программы. К примеру, исследование, охватившее свыше десяти тысяч образцов вредоносного ПО для Linux, показало, что примерно половина из них динамически изменяют свои имена с целью маскировки. При этом примерно ровно половина меняют thread name, отражаемое в comm, а другая половина — argv, но не обе части одновременно, что даёт некоторую лазейку для обнаружения. Помимо Linux, в мире Unix-подобных систем ситуация разнообразна.
OpenBSD и NetBSD позволяют изменять argv напрямую, и это изменения корректно отражаются и внутри процесса, и снаружи через системные интерфейсы. FreeBSD и Solaris обладают иными механизмами — трэдинг имени или аргументов происходит по-другому, и изменения argv не всегда отображаются во внешних представлениях. В FreeBSD, например, для изменения argv используется системный вызов sysctl с MIB kern.proc.args.
Имя же процесса (equivalent Linux comm) изменить нельзя без загрузки пользовательского ядрового модуля, а это уже технически более сложный и рискованный путь. В BSD-системах, кстати, существует функция setproctitle, которая позволяет менять аргументы процесса безопасно и произвольно, чего нет в Linux по умолчанию. Разработчики портируют или имитируют подобное поведение, например, в таких проектах как LXC. Стоит упомянуть и о так называемом «tricky name» — приём маскировки процесса под системные задачи или kernel threads, когда название берётся в квадратные скобки. Такие процессы, как правило, запускаются системным демоном kthreadd с PID 2, и их внешняя идентификация проста через проверку родительского процесса.
Однако злонамеренный процесс, маскирующийся под kworker или иной служебный поток, может выделяться при детальном анализе дерева процессов. Некоторые вредоносные программы применяют именно такие методы, изменяя argv или comm в зависимости от длины старого имени, чтобы максимально слиться с системными процессами. Для обнаружения процессов с подменёнными именами помимо простого сравнения comm и cmdline актуальны и более глубокие методы. Например, проверка символической ссылки /proc/[pid]/exe, которая указывает на оригинальный исполняемый файл. Даже если файл на диске будет удалён после запуска процесса, появится статус «deleted», что само по себе является индикатором подозрительной активности.
В перспективе возможно и изменение ссылки /proc/[pid]/exe изнутри процесса, что сделает задачу обнаружения ещё сложнее. Подобные техники требуют глубинного понимания и опытных методов защиты. Понимание внутреннего устройства процессов в Linux помогает лучше усвоить, почему и как можно модифицировать имена. В ядре Linux структура task_struct содержит основную информацию о процессе, включая массив для хранения имени comm и структуру mm_struct с детальным описанием виртуального адресного пространства. Массив argv находится в выделенном участке памяти, адреса которого отражены в mm_struct как arg_start и arg_end.
Через системный вызов prctl можно управлять этими адресами, перенаправляя указатели на новые области памяти с нужными строками. Инструменты мониторинга процессов отдают данные именно из этих структур, поэтому изменение их влияет на результаты их работы. Для специалистов по кибербезопасности такая информация бесценна. Эффективная защита требует не только понимания базовых приёмов маскировки процессов, но и подходов к их обнаружению. Современные EDR-решения и инструменты с open source, такие как Sysdig, Falco или osquery, позволяют фиксировать момент исполнения процесса и отслеживать любые изменения аргументов и имён, предоставляя возможность выявить постфактум попытки защиты вредоносного ПО.
Подводя итог, стоит отметить, что изменение имён процессов — не просто техническая «игра» с аргументами и строковыми переменными. Это важный механизм маскировки и обхода защиты, который активно используется как в криминальных целях, так и в административных сценариях. Инструменты и методы должны постоянно развиваться, чтобы администраторы и специалисты по безопасности могли держать руку на пульсе и своевременно выявлять подозрительную активность. Углублённое понимание работы procfs, памяти процесса и системных вызовов — ключ к построению надежной системы мониторинга и реагирования на угрозы в инфраструктуре Unix-подобных систем.