Print This Post Простой контроль целостности процесса под Windows

Суббота, 23. Март 2013
Раздел: C/C++, Windows, автор:

Намедни решил попробовать написать драйвер под Windows. Варианты с "Hello world" показались унылыми, поэтому в качестве тренировки поставил перед собой следющую цель: написать драйвер, который будет контролировать целостность кода процесса по запросу. В общем, драйвер будет считывать данные о загруженных в память секциях, проверять атрибуты и считать простенькую контрольную сумму, а при повторном обращении - сверять её. Совсем детально описывать процесс я не буду, так как в интернете есть куча мануалов по самым основам, да и желающие могут просто посмотреть примеры из WDK, которые достаточно хорошо документированы.

Код, описанный ниже, предполагается вызывать в обработчике IOCTL-запросов. Начнем с реализации основной функции, которая будет осуществлять проверку, и нескольких вспомогательных.

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

Теперь рассмотрим основные функции, реализующие заявленный контроль целостности:

И, наконец, здоровенная функция, которая обрабатывает секции модулей:

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

Теперь возьмем этот код и добавим к какому-нибудь базовому прототипу драйвера. Результат будет выглядеть, например, следующим образом:

Скомпилируем и установим наш драйвер в систему (для этой цели я воспользовался удобной утилитой OSR Driver Loader). Теперь нам необходимо отослать драйверу IOCTL-запрос. Что ж, сделаем небольшую утилиту, которая нам в этом поможет:

Компилируем и запускаем нашу утилиту, а также запускаем DebugView, чтобы видеть отладочный вывод драйвера.

init

Как мы видим, драйвер посчитал контрольные суммы интересующих нас секций и добавил в свой внутренний список. Теперь возьмем OllyDbg и изменим произвольный байт в секции кода. Драйвер незамедлительно сообщает о нарушении целостности секции и пишет об этом в логе:

validation_failed

Надеюсь, пример окажется кому-нибудь полезен.

Исходный код полностью: скачать

 Обсудить на форуме


Получать обновления на почту:     

Комментариев: 30 к “Простой контроль целостности процесса под Windows”

  1. Кому нужна эта хунта

    [Ответить]

    Kaimi:

    Отпишись от RSS, делов то.

    [Ответить]


  2. Max :

    Спасибо за пример.
    Тоже хочу попробовать написать драйвер, который бы перехватывал обращение к определенным папкам и блокировал доступ. Но все руки никак не доходят.

    [Ответить]


  3. _sheva740 :

    Спасибо, прикольно, но думаю для
    новичка сложновато будет.
    ))

    [Ответить]


  4. user :

    Класс. Kaimi какой программой вы компилировали исходный код?

    [Ответить]

    Kaimi:

    MSVC 2012

    [Ответить]


  5. Indy :

    А как же быть с IAT и релоками ?

    [Ответить]

    Kaimi:

    И что же с ними, если это "простой контроль" и цель - контролировать только секции с кодом в обычных исполняемых файлах?

    [Ответить]


  6. Indy :

    То, что они в секциях кода и значения эти изменяются. Из за них кодосекции модуля на диске и в памяти различаются.

    [Ответить]

    Kaimi:

    Так, продолжайте, и что дальше? Если мы читаем и проверяем исключительно исходя из того, что уже загружено в память.

    [Ответить]


  7. Indy :

    Тогда как узнать что модуль в памяти изменён/пропатчен, сравнить ведь несчем ?

    Например mov r,offset proc -- имеется релок для смещенья. Он может как угодно быть переписан.

    IAT по отношенью к модулю на диске вообще содержит произвольные данные.

    [Ответить]

    Kaimi:

    Сравнить с тем, что было при первом запросе на проверку. Это не способ защиты от хитрого хекера или чего-то подобного.

    [Ответить]


  8. Indy :

    Каком есчо запросе ?

    Вы скажите методу, которая позволит определить что образ изменён. А ваши фейковые проверки есмъ типичный аверский ход.

    [Ответить]

    Kaimi:

    IOCTL-запросе. Софт делает запрос к драйверу, считается изначальная контрольная сумма, далее, при повторных запросах, контрольная сумма сверяется с изначальной.
    А я в этом особо не разбираюсь.

    [Ответить]


  9. Indy :

    Вы наверно не понимаете мою речь. Я спрашиваю КАК ОПРЕДЕЛЯЕТСЯ ЦЕЛОСТНОСТЬ ОБРАЗА ?

    Причём тут ваши запросы в дров. Мой вредоносный код изменит образ как сказано выше, пофиксит IAT и как вы узнаете что он целый ?

    [Ответить]

    Kaimi:

    Если IAT будет изменена до запуска процесса - никак, если IAT будет изменена до первого обращения к драйверу - никак.

    [Ответить]


  10. Indy :

    IAT заполняется системным лодером при стартапе. Ежели вся суть чеканья в отправке запроса после запуска приложенья, то это не защита :)

    [Ответить]

    Kaimi:

    Я в курсе. Если хотите - "минимальная защита" от возможного сбоя железа.

    [Ответить]


  11. Indy :

    Был один метод, но дальше теории оно не прошло, возможно вы разрулите http://www.woodmann.com/forum/showthread.php?15158-detecting-or-preventing-patching-in-memory-(code-and-data)&p=94503&viewfull=1#post94503

    [Ответить]


  12. Indy :

    Короче блог сей есмъ паганый холивар. Все вопросы снимаю!

    [Ответить]


  13. user :

    Indy вы больной на всю голову человек, ищите себе без повода задачу или конфликт, но когда вам предлагают что-то решить, в личной обстановке, вы не беретёсь. Человек ясно написал, что решил попробовать написать драйвер, вместо Hello world, он не начал с того, что предлагает хитрую технику проверки кода на целостность.

    Kaimi не слушайте этого идиота, нормальный у вас блог, интересно читать и пользы больше и большему кругу людей, чем от экскрементов Indy.

    [Ответить]

    Indy:

    Вы друг мой явно не понимаете. Ежели человек начинает разрабатывать защиту, то он неизбежно становится авером, причём его не интересует дальнейшая проработка защиты. Именно здесь мы сие и наблюдаем. Дальнейшее сами обмозгуете, или быть может тоже помощь нужна ?

    [Ответить]

    Kaimi:

    Шутить изволите? У меня даже образования в области IT нет, не говоря уже о полном отсутствии желания работать в ней.

    [Ответить]

    Indy:

    У инде тоже его нет и желанья. Это не мешает обходить защиту, пилить морфы и дроверы :)
    А аверы все с такого начинали. Далее будет защита на уровне сервисных таблиц етц, после чего рассмотрена возможность поработать в одной из ав контор(спермский обычно).

    Kaimi:

    Далее мне будет лень, так как слишком сложно, долго и надо делать работу по фармакологии.


  14. user :

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

    [Ответить]

    Indy:

    В себе мну разобрался. С сабжем не до конца.

    [Ответить]


  15. JKornev :

    Спасибо за код, но тут есть 2 недочёта
    1. Если исполняемый файл содержит релоки, то при проецировании в память засчёт рандомизации адресного пространства секция кода должна будет отличатся от той что в файле (адреса релоков ведь загрузчик перепишет под текущее смещение)
    2. Если исполняемый файл накрыт протектором или пакером, то его секции могут все иметь атрибуты RWE или RWEC. Т.е. алгоритм выборки секций работает только на стандартных скомпилиных файлах.

    Если 2 этих недочёта поправить, то выйдет вполне рабочий вариант.

    [Ответить]

    Kaimi:

    1. Так код ведь не оперирует с образом файла на диске, а исключительно с тем, что было уже загружено в память.
    2. Есть такое дело.

    [Ответить]

    JKornev:

    Ага не досмотрел извеняюсь)

    [Ответить]


Оставьте ваш комментарий