Определение требований к повышению в новозапущенных процессах

Вопрос или проблема

Я разрабатываю программу мониторинга процессов, которая определяет процессы, требующие повышения прав.

Мой текущий подход включает:

  • Поток GUI для обработки пользовательского интерфейса.
  • Поток мониторинга использует трассировку событий для Windows, чтобы слушать события создания процессов. Этот поток передает новые идентификаторы процессов, обернутые в классы Process, в поток GUI.
  • Проверка повышения прав: Конструктор класса Process сразу же проверяет его манифестный файл на наличие соответствующей информации, включая <requestedExecutionLevel level="requireAdministrator" />, чтобы определить, требует ли процесс повышения прав.

Это работает для многих процессов, но некоторые исполняемые файлы (например, установщики .msi) требуют повышения прав, не указывая это явно в своем манифесте (если они его имеют).

Я рассматривал возможность мониторинга вызовов consent.exe и svchost.exe:
введите описание изображения здесь

но проблема возникает, когда несколько процессов, требующих повышения прав, запускают другие процессы.

Если один из этих дочерних процессов запускает constent.exe, становится сложно определить исходный процесс, ответственный за запрос на повышение прав, что заставило меня рассмотреть подход, подобный Process Explorer, чтобы выявить деревья процессов, но я опасаюсь сложности и потенциальной нагрузки на производительность.

Это разумное направление или есть более простые и эффективные альтернативы для выявления процессов, требующих повышения прав?

В настоящее время я инкапсулировал логику ETW в класс и фильтрационный механизм для идентификации соответствующих процессов:

// Поток слушателя процессов:
void ProcessListener::onRecord(EVENT_RECORD *record) {
    if ( record->EventHeader.EventDescriptor.Id == EVENT_TRACE_TYPE_START ) {
        EventParser parser( record );
        auto &p_info = parser.getTraceEventInfo();

        for ( auto i = 0u; i < p_info->TopLevelPropertyCount; i++ ) {
            const auto current = p_info->EventPropertyInfoArray[ i ];
            const auto property = std::wstring( reinterpret_cast< LPWSTR >( p_info.data() + current.NameOffset ) );

            if ( current.nonStructType.InType == TDH_INTYPE_UNICODESTRING ) {
                if ( property == L"ImageName" ) {
                    auto data = parser.getPropertyData( property );
                    auto path = std::wstring( reinterpret_cast< const wchar_t * >( data.data() ),
                                              data.size() / sizeof( wchar_t ) - 1 );

                    try {
                        Process process( record->EventHeader.ProcessId, path );
                        if ( filter_func != nullptr ) {
                            if ( filter_func( process ) ) {
                                queue.push( std::make_unique< Process >( std::move( process ) ) );
                            }
                        }
                        else { queue.push( std::make_unique< Process >( std::move( process ) ) ); }
                    }
                    catch ( const std::exception &e ) { spdlog::info(e.what()); }
                }
            }
        }
    }
}

// Поток GUI:
psm.setFilter( [] (const ProcessBase &process)-> bool {
        return process.getPath().extension() == ".exe" &&
               process.needsElevation() && // Проверяет манифестный файл.
               process.getPath().wstring().find( L"\\Windows\\System32" ) == std::wstring::npos;
} );
psm.run();

Ответ или решение

Определение требований к повышению прав в только что запущенных процессах

Ваша задача разработки программы мониторинга процессов, которая определяет, какие процессы требуют повышения прав (elevation), представляет собой важную и интересную задачу в области управления процессами и безопасности. Основной подход, который вы описали, включает использование потоков для обслуживания пользовательского интерфейса и мониторинга процессов с помощью Event Tracing for Windows (ETW). Несмотря на то, что ваша реализация уже функционирует для многих типов процессов, вы столкнулись с некоторыми ограничениями, особенно с процессами, которые требуют повышения прав без явного указания этого в их манифестах.

Подход к определению процессов, требующих повышения прав

Ваша реализация на текущий момент включает:

  1. GUI Поток: для работы с пользовательским интерфейсом.
  2. Поток мониторинга: использующий ETW для отслеживания событий создания процессов, что позволяет передавать новые идентификаторы процессов на GUI поток.
  3. Проверка на необходимость повышения прав: конструктор класса Process проверяет манифест файла на наличие элемента <requestedExecutionLevel level="requireAdministrator"/>.

В таком подходе действительно могут оказаться непростыми случаи, например, с установщиками формата .msi, которые доступ к повышенным привилегиям требуют, даже если это не прописано в их манифестах.

Вы также упомянули возможность мониторинга процессов consent.exe и svchost.exe, чтобы выявить потребность в повышении прав. Однако, как вы уже заметили, это может привести к путанице, когда дочерние процессы вызывают consent.exe, и становится трудно определить, какой из родительских процессов инициировал запрос на повышение прав.

Рекомендации по улучшению стратегии

  1. Отслеживание иерархии процессов: Использование подхода, аналогичного тому, который применяет Process Explorer, для построения дерева процессов может быть реалистичной стратегией. Хотя это добавляет сложность, оно также дает возможность получения более детальной информации о том, какой именно процесс инициировал требование на повышение прав. Для минимизации производительных затрат можно рассмотреть возможность обновления иерархии процессов только при определенных событиях, например, при активных изменениях в процессах.

  2. Анализ атрибутов и аргументов командной строки: Некоторые процессы могут требовать повышения прав на основе их параметров. Можно добавить дополнительную проверку на наличие специфичных аргументов командной строки, часто используемых для вызова процессов с повышением привилегий (например, /a для установщиков).

  3. Системные API для проверки прав: В дополнение к проверке манифестов, использование API Windows, таких как OpenProcessToken и GetTokenInformation, может предоставить информацию о правах доступа процессов. Это позволит вам более точно определять, требует ли процесс действительно повышения привилегий в момент его запуска.

Заключение

Ваш первоначальный подход имеет свои преимущества и уже позволяет идентифицировать множество процессов, требующих повышения прав. Однако, для учета случая с процессами, которые не явно указывают свою потребность в повышении, можно рассмотреть предложенные улучшения. Постепенно добавляя более сложные логические проверки и механизмы контроля, вы сможете значительно повысить надежность вашей программы.

Важно помнить о балансе между производительностью и функциональностью: избыточная сложность может негативно сказаться на общей производительности системы, поэтому проанализируйте, какие действия имеют наибольший приоритет для вашей задачи и могут быть эффективно реализованы.

Оцените материал
Добавить комментарий

Капча загружается...