Клавиатурные шпионы (кейлоггеры)

ОГЛАВЛЕНИЕ

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

Перехват нажатий клавиш может использоваться обычными программами и часто применяется для вызова функций программы из другого приложения с помощью «горячих клавиш» (hotkeys) или, например, для переключения неправильной раскладки клавиатуры (как Keyboard Ninja). Существует масса легального ПО, которое используется администраторами для наблюдения за тем, что делает работник в течение дня, или для наблюдения пользователем за активностью посторонних людей на своем компьютере. Однако где проходит грань между «законным» использованием «легального» ПО и его использованием в криминальных целях? То же «легальное» ПО зачастую используется и в целях умышленного похищения секретных данных пользователя — например, паролей.

Большинство существующих на данный момент кейлоггеров считаются «легальными» и свободно продаются, так как разработчики декларируют множество причин для использования кейлоггеров, например:

  • для родителей: отслеживание действий детей в Интернете и оповещение родителей в случае попыток зайти на сайты «для взрослых» (parental control);
  • для ревнивых супругов: отслеживание действий своей половины в Сети в случае подозрения на «виртуальную измену»;
  • для службы безопасности организации: отслеживание фактов нецелевого использования персональных компьютеров, их использования в нерабочее время;
  • для службы безопасности организации: отслеживание фактов набора на клавиатуре критичных слов и словосочетаний, которые составляют коммерческую тайну организации, и разглашение которых может привести к материальному или иному ущербу для организации;
  • для различных служб безопасности: проведение анализа и расследования инцидентов, связанных с использование персональных компьютеров;
  • другие причины.

Однако это скорее привычное, чем объективное положение вещей, так как для решения всех указанных задач существуют и другие способы, а ЛЮБОЙ легальный кейлоггер может использоваться во вредоносных целях, и в последнее время именно кража информации пользователей различных систем онлайновых платежей стала, к сожалению, главным применением кейлоггеров (для этих же целей вирусописателями постоянно разрабатываются новые троянцы-кейлоггеры).

Кроме того, многие кейлоггеры прячут себя в системе (т.к. имеют функции руткита), что значительно облегчает их использование в преступных целях. Такое использование делает задачу обнаружения кейлоггеров одной из приоритетных для антивирусных компаний. В классификации вредоносных программ «Лаборатории Касперского» существует специальная категория Trojan-Spy (шпионские программы), в которую попадают программы, содержащие функции клавиатурных шпионов. Согласно определению Trojan-Spy, «эти троянцы осуществляют электронный шпионаж: вводимая с клавиатуры зараженного компьютера информация, снимки экрана, список активных приложений и действия пользователя с ними сохраняются в какой-либо файл на диске и периодически отправляются злоумышленнику».



Чем опасны кейлоггеры

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

После получения конфиденциальных данных пользователя злоумышленник может не только банально перевести деньги с его банковского счета или использовать учетную запись пользователя в online-игре. К сожалению, наличие таких данных в ряде случаев может приводить к последствиям более серьезным, чем потеря некоторой суммы денег конкретным человеком. Использование кейлоггеров позволяет осуществлять экономический и политический шпионаж, получать доступ к сведениям, составляющим не только коммерческую, но и государственную тайну, а также компрометировать системы безопасности, используемые коммерческими и государственными структурами (например, с помощью кражи закрытых ключей в криптографических системах).

Кейлоггеры, наряду с фишингом и методами социальной инженерии (см. статью «Кража собственности в компьютерных сетях»), являются сейчас одним из главных методов электронного мошенничества. Однако если в случае фишинга бдительный пользователь может сам себя защитить — игнорировать явно фишинговые письма, не вводить персональные данные на подозрительных веб-страницах, — то в случае с клавиатурными шпионами никаким другим способом, кроме использования специализированных средств защиты, обнаружить факт шпионажа практически невозможно.

По словам Кристины Хойперс (Cristine Hoepers), менеджера бразильской команды немедленного компьютерного реагирования (Brazil's Computer Emergency Response Team), работающей под эгидой Комитета регулирования Интернета Бразилии (Internet Steering Committee), кейлоггеры оказались самым распространенным способом кражи конфиденциальной информации, передвинув фишинг на второе место, и действуют все более избирательно: отслеживая веб-страницы, к которым обращается пользователь, они записывают нажатия клавиш только при заходе на сайты, интересующие злоумышленников.

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



Примеры использования кейлоггеров злоумышленниками

Одним из самых известных недавних случаев использования кейлоггеров стала кража более 1 млн. долларов со счетов клиентов крупнейшего скандинавского банка Nordea. В августе 2006 года клиентам шведского банка Nordea стали приходить от имени этого банка электронные письма с предложением установить антиспам-продукт, якобы содержащийся в приложении. При попытке получателя письма скачать прикрепленный файл на свой компьютер устанавливался специальный вариант широко известной троянской программы Haxdoor, который активировался при регистрации жертвы в онлайн-сервисе Nordea и выводил на экран сообщение об ошибке с просьбой о повторной регистрации. После этого клавиатурный шпион, встроенный в троянскую программу, записывал вводимые пользователем данные и передавал их на сервер злоумышленников. Собранные таким образом персональные данные использовались мошенниками для снятия денег со счетов доверчивых клиентов банка. Создателя этого троянца помог вычислить один из экспертов по безопасности компании Symantec. По заявлению автора троянской программы, haxdoor использовался и в атаках против австралийских и многих других банков.

27 января 2004 года началась эпидемия одной из самых известных вредоносных программ — червя Mydoom. Mydoom побил рекорды червя Sobig и стал причиной самой масштабной эпидемии в истории Интернета на сегодняшний день. Червь распространялся по электронной почте. Автор червя использовал самые разнообразные заголовки писем, чтобы заинтересовать пользователей с очень разными интересами. Червь провел атаку на сайт www.sco.com, из-за этого вышедший из строя на несколько месяцев, и оставлял на зараженном компьютере троянскую программу, которая использовалась для заражения другими версиями вируса, последовавшими за главной эпидемией. Однако мало кто знает, что наряду с функциональностью сетевого червя, бэкдора и организацией DoS-атаки на сайт www.sco.com, Mydoom содержал функции кейлоггера для сбора номеров кредитных карт.

В начале 2005 года лондонская полиция предотвратила одну из самых крупных попыток кражи банковской информации в Англии. С помощью атаки на банковскую систему злоумышленники планировали украсть 423 млн. долларов из лондонских офисов банка Sumitomo Mitsui. Главным компонентом троянской программы, созданной 32-летним израильтянином Иероном Болонди (Yeron Bolondi), является кейлоггер, позволяющий отслеживать все нажатия клавиш при работе с клиентской программой указанного банка.

В мае 2005 года в Лондоне израильская полиция арестовала супружескую пару по обвинению в разработке вредоносных программ, при помощи которых израильские компании шпионили за конкурентами. Поражают масштабы данного промышленного шпионажа: среди компаний, которые упоминались израильскими властями в материалах расследования, есть такие крупные компании, как операторы мобильной связи Cellcom и Pelephone, а также провайдер спутникового телевидения компания YES. Согласно материалам следствия, троянская программа была использована для шпионажа в отношении PR-агентства Rani Rahav, среди клиентов которого — второй в Израиле мобильный оператор Partner Communications и группа кабельного телевидения HOT. Израильская компания Mayer, которая занимается импортом автомобилей марки Volvo и Honda, подозревается в шпионаже против компании Champion Motors, которая занимается импортом автомобилей марки Audi и Volkswagen. Рут Эфрати, продававшая созданную ее мужем Майклом Эфрати (Michael и Ruth Efrati) троянскую программу с функциями клавиатурного шпиона, проведет в тюрьме 4 года, а сам Майкл — два.

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

Кейлоггеры активизировались в тот момент, когда пользователи заходили на web-страницы банковских систем, и скрытно отслеживали и позднее передавали злоумышленникам все вводимые на этих страницах данные. Общая сумма денег, которая была украдена подобным образом с 200 клиентских счетов в шести банках страны, составила 4,7 млн. долларов.

Почти в то же время была арестована аналогичная преступная группа, состоявшая из молодых (от 20 до 30 лет) россиян и украинцев. С конца 2004 года они рассылали клиентам банков Франции и ряда других стран почтовые сообщения, содержащие вложенную вредоносную программу — кейлоггер. Кроме того, эти же шпионские программы выкладывались на специально созданных web-сайтах, куда заманивались пользователи методами социальной инженерии. Далее события развивались как во всех описанных выше случаях: программа активировалась при заходе на сайты банковских систем, собирала все вводимые пользователем данные и пересылала их злоумышленникам. Таким образом за 11 месяцев было украдено более 1 млн. долларов.

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



Рост популярности кейлоггеров у злоумышленников

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

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


Источник: iDefense

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

В соответствии с расчетом, проведенным аналитиком института SANS Джоном Бамбенеком (John Bambenek), только на территории США к концу 2004 года около 10 млн. компьютеров были заражены одной из вредоносных программ, содержащих функции кейлоггера. На основе этого расчета сумма, которую американские пользователи электронных платежных систем рискуют потерять, составляет ни много ни мало 24,3 миллиарда долларов.

«Лаборатория Касперского» постоянно фиксирует появление новых вредоносных программ с функциями клавиатурных шпионов. Одно из первых вирусных предупреждений о вредоносной программе с функцией кейлоггера — троянской программе TROJ_LATINUS.SVR — было опубликовано «Лабораторией Касперского» 15 июня 2001 года. После этого стабильно появлялись новые версии кейлоггеров. В настоящий момент в антивирусных базах «Лаборатории Касперского» присутствует информация более чем о 300 семейств специализированных кейлоггеров. В эту цифру не входят кейлоггеры, включенные в сложные вредоносные программы, в которых функциональность клавиатурного шпиона не является главной.

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



Принципы построения кейлоггеров

Принципиальная идея кейлоггера состоит в том, чтобы внедриться между любыми двумя звеньями в цепи прохождения сигнала от нажатия пользователем клавиш на клавиатуре до появления символов на экране — это может быть видеонаблюдение, аппаратные «жучки» в самой клавиатуре, на проводе или в системном блоке компьютера, перехват запросов ввода-вывода, подмена системного драйвера клавиатуры, драйвер-фильтр в клавиатурном стеке, перехват функций ядра любым способом (подменой адресов в системных таблицах, сплайсингом кода функции и т.п.), перехват функций DLL в пользовательском режиме, наконец, опрос клавиатуры стандартным задокументированным способом.

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

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

Наиболее популярные технические подходы к построению программных кейлоггеров:

  • системная ловушка на сообщения о нажатии клавиш клавиатуры (устанавливается с помощью функции WinAPI SetWindowsHook, для того чтобы перехватить сообщения, посылаемые оконной процедуре, — чаще всего пишется на C);
  • циклический опрос клавиатуры (с помощью функции WinAPI Get(Async)KeyState, GetKeyboardState — чаще всего пишется на VisualBasic, реже на Borland Delphi);
  • драйвер-фильтр стека клавиатурных драйверов ОС Windows (требует специальных знаний, пишется на C).

Мы очень детально рассмотрим различные методы построения кейлоггеров во второй части нашей статьи. Пока же приведем немного статистики.

Примерное распределение указанных типов кейлоггеров показано на следующей диаграмме:


В последнее время отмечается тенденция использования в кейлоггерах методов сокрытия (маскировки) своих файлов — так, чтобы их нельзя было найти вручную или с помощью антивирусного сканера. Такие методы принято называть rootkit-технологиями. Можно выделить два основных типа технологий сокрытия, используемых кейллоггерами:

  • с использованием методов сокрытия пользовательского режима (UserMode);
  • с использованием методов сокрытия режима ядра операционной системы (KernelMode).

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




Способы распространения кейлоггеров

Способы распространения кейлоггеров в целом не отличаются от способов распространения других вредоносных программ. Можно выделить следующие методы распространения кейлоггеров (без учета случаев покупки и установки кейлоггера заботливым супругом(-ой) и использования кейллоггеров службами безопасности организаций):

  • при открытии файла, присоединенного к электронному письму;
  • при запуске файла из каталога, находящегося в общем доступе в peer-to-peer сети;
  • с помощью скрипта на веб-страницах, который использует особенности интернет-браузеров, позволяющие программам запускаться автоматически при заходе пользователя на данные страницы;
  • с помощью ранее установленной вредоносной программы, которая умеет скачивать и устанавливать в систему другие вредоносные программы.


Методы защиты от кейлоггеров

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

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

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

  1. использование одноразовых паролей / двухфакторная аутентификация,
  2. использование систем проактивной защиты, предназначенных для обнаружения программных кейлоггеров,
  3. использование виртуальных клавиатур.

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

Для получения одноразовых паролей могут использоваться специальные аппаратные устройства:

  1. в виде брелка (например, Aladdin eToken NG OTP):

  2. в виде «калькулятора» (например, RSA SecurID 900 Signing Token):

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

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

  1. пользователь подключается к Интернету и открывает диалоговое окно для ввода персональных данных;
  2. далее пользователь нажимает на кнопку ключа для генерации одноразового пароля, после этого пароль на 15 секунд появляется на ЖК-дисплее брелка;
  3. пользователь вводит в диалоговом окне свой логин, персональный PIN-код и сгенерированное значение одноразового пароля (обычно PIN-код и ключ вводятся последовательно в одно поле passcode);
  4. введенные значения проверяются на стороне сервера, после чего принимается решение о том, имеет ли право их владелец на работу с закрытыми данными.

При использовании устройства в виде калькулятора для генерации пароля пользователь набирает свой PIN-код на «клавиатуре» устройства и нажимает кнопку «>».

Генераторы одноразовых паролей широко применяются в банковской системе Европы, Азии, США и Австралии. Например, Lloyds TCB, один из самых крупных банков Великобритании, еще в ноябре 2005 года перешел на использование генераторов одноразовых паролей.

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

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


Пример срабатывания проактивной защиты Kaspersky Internet Security.

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

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

Идея экранной клавиатуры не нова: в ОС Windows содержится встроенная экранная клавиатура, вызываемая через меню Start > Programs > Accessories > Accessibility > On-Screen Keyboard.


Вид экранной клавиатуры, встроенной в ОС Windows.

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


Обработка клавиатурного ввода в OC Windows

Существует несколько базовых технологий перехвата нажатий клавиш и событий мыши, на основе которых создано множество кейлоггеров. Однако перед тем как рассматривать конкретные типы кейлоггеров, необходимо познакомиться со схемой обработки клавиатурного ввода, реализованной в ОС Windows. Для описания всей схемы — от нажатия клавиши на клавиатуре до срабатывания системного прерывания контроллера клавиатуры и получения активным окном сообщения WM_KEYDOWN — мы воспользуемся тремя источниками:

  1. Книгой «Аппаратное обеспечение IBM PC». Александр Фролов, Григорий Фролов, Том 2, книга 1, М.: Диалог-МИФИ, 1992. Глава 2 «Клавиатура» описывает принципы работы клавиатуры, используемые порты и аппаратное прерывание клавиатуры;
  2. Разделом Human Input Devices библиотеки MSDN Library, в котором описана низкоуровневая (драйверная) часть схемы обработки клавиатурного ввода;
  3. Книгой Джеффри Рихтера «Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows». В главе 27 «Модель аппаратного ввода и локальное состояние ввода» приведено описание высокоуровневой части схемы обработки клавиатурного ввода (реализованной в пользовательском режиме).


Принципы работы клавиатуры как физического устройства

В настоящее время большинство клавиатур выполнено в виде отдельного устройства, подключаемого к компьютеру с помощью одного из разъемов, чаще всего PS/2 или USB. Существуют два микроконтроллера, обеспечивающие процесс обработки клавиатурного ввода: один — на материнской плате ПК, второй — в самой клавиатуре. Таким образом, клавиатура персонального компьютера сама по себе является компьютерной системой. Она построена на основе микроконтроллера 8042, который постоянно сканирует нажатия клавиш на клавиатуре — независимо от активности на центральном процессоре x86.

За каждой клавишей клавиатуры закреплен определенный номер, однозначно связанный с распайкой клавиатурной матрицы и не зависящий напрямую от обозначений, нанесенных на поверхность клавиш. Этот номер называется скан-кодом (название подчеркивает тот факт, что компьютер сканирует клавиатуру для поиска нажатой клавиши). Скан-код — это случайное значение, выбранное IBM еще тогда, когда она создавала первую клавиатуру для ПК. Скан-код не соответствует ASCII-коду клавиши, одной и той же клавише могут соответствовать несколько значений ASCII-кода. Таблицу скан-кодов можно посмотреть, например, в двадцатой главе книги The Art of Assembly Language Programming.

На самом деле клавиатура генерирует два скан-кода для каждой клавиши — когда пользователь нажимает клавишу и когда отпускает. Наличие двух скан-кодов важно, так как некоторые клавиши имеют смысл только тогда, когда они нажаты (Shift, Control, Alt).


Рис. 1. Упрощенная схема клавиатуры

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

Второй микроконтроллер получает скан-код, производит преобразование скан-кода, делает его доступным на порту ввода-вывода 60h и затем генерирует аппаратное прерывание центрального процессора. После этого процедура обработки прерывания может получить скан-код из указанного порта ввода-вывода.

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



Низкоуровневое взаимодействие с клавиатурой через порты ввода-вывода

Взаимодействие с системным контроллером клавиатуры происходит через порт ввода-вывода 64h. Считав байт из этого порта, можно определить статус контроллера клавиатуры, записав байт — послать контроллеру команду.

Взаимодействие с микроконтроллером в самой клавиатуре происходит с помощью портов ввода-вывода 60h и 64h. Биты 0 и 1 в байте статуса (порт 64h в режиме чтения) предоставляют возможность управлять процедурой взаимодействия: перед записью данных в эти порты бит 0 порта 64h должен быть выставлен в 0. Когда данные доступны для чтения из порта 60h, бит 1 порта 64h равен 1. Биты включения/выключения клавиатуры в командном байте (порт 64h в режиме записи) определяют, является ли клавиатура активной, и будет ли контроллер клавиатуры вызывать прерывание в системе, когда пользователь нажмет клавишу.

Байты, записанные в порт 60h, посылаются контроллеру клавиатуры, а байты, записанные в порт 64h, посылаются системному контроллеру клавиатуры. Списки разрешенных команд, которые можно послать контроллеру клавиатуры, представлены, например, в документе «8042 Keyboard Controller IBM Technical Reference Manual» или в двадцатой главе книги The Art of Assembly Language Programming.

Байты, считываемые из порта 60h, приходят от клавиатуры. Порт 60h при чтении содержит скан-код последней нажатой клавиши, а в режиме записи он используется для расширенного управления клавиатурой. При использовании порта 60h на запись программа дополнительно получает следующие возможности:

  • установка времени ожидания перед переходом клавиатуры в режим автоповтора;
  • установка периода генерации скан-кода в режиме автоповтора;
  • управление светодиодами, расположенными на лицевой панели клавиатуры — Scroll Lock, Num Lock, Caps Lock.

Резюмируя, отметим, что для чтения данных, вводимых с клавиатуры, достаточно уметь считывать значения портов ввода-вывода 60h и 64h. Однако в ОС Windows приложениям пользовательского режима запрещено работать с портами, поэтому эту задачу выполняют драйвера операционной системы.



Архитектура «интерактивных устройств ввода»

Кто же обрабатывает аппаратное прерывание, которое генерируется при появлении в порту 60h данных, полученных от клавиатуры? Очевидно, тот, кто зарегистрировал процедуру обработки аппаратного прерывания клавиатуры IRQ 1. В ОС Windows эту обработку производит драйвер i8042prt.sys. В отличие от времен MS DOS, когда каждый системный компонент был как бы «сам по себе», в Windows все компоненты построены согласно четкой архитектуре и работают по строго определенным правилам, закрепленным программными интерфейсами. Поэтому перед тем как приступить к рассмотрению драйвера i8042prt, мы рассмотрим архитектуру интерактивных устройств ввода, в рамках которой функционируют все программные компоненты, связанные с обработкой клавиатурного (и «мышиного») ввода.

Устройства, используемые для прямого управления операциями на компьютере, в ОС Windows называются интерактивными устройствами ввода. Клавиатура является одним из таких устройств, наряду с манипулятором «мышь», джойстиками, трекболами, игровыми педалями, колесами, шлемами виртуальной реальности и др.

Архитектура управления интерактивными устройствами ввода базируется на стандарте USB Human Interface Device (HID), предложенном организацией USB Implementers Forum. Однако архитектура не ограничена только USB-устройствами и поддерживает другие типы устройств ввода, в частности, bluetooth-клавиатуру, клавиатуру и мышь, подключаемые по PS/2 порту, а также устройства, подключаемые по игровому порту (I/O port 201).

Далее мы рассмотрим принципы построения стека драйверов и стека устройств для PS/2-клавиатур, так как исторически они являются первый типом устройств. USB-клавиатуры используют ряд элементов, введенных при разработке программной поддержки PS/2-клавиатур.



Драйвера режима ядра для PS/2 клавиатуры 

Стек драйверов для системных устройств ввода

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

Соответствующий функциональный драйвер (драйвер порта) реализует зависимую от конкретного устройства поддержку выполнения операций ввода-вывода. В ОС Windows для x86-платформ реализован единый драйвер системной клавиатуры (i8042) и мыши.


Рис. 2. Драйверные стеки для системных устройств ввода: клавиатуры и мыши

Стек драйверов для Plug and Play PS/2-клавиатуры


Рис. 3. Стек драйверов для PS/2-клавиатуры

Стек драйверов содержит (сверху вниз):

  1. Kbdclass — верхнеуровневый фильтр-драйвер класса клавиатуры;
  2. опциональный верхнеуровневый фильтр-драйвер класса клавиатуры;
  3. i8042prt — функциональный драйвер клавиатуры;
  4. корневой драйвер шины.

В ОС Windows 2000 и старше драйвером класса клавиатуры является драйвер Kbdclass, основными задачами которого являются:

  • обеспечение общих и аппаратно-независимых операций класса устройств;
  • поддержка Plug and Play, поддержка управления питанием и Windows Management Instrumentation (WMI);
  • поддержка операций для legacy-устройств;
  • одновременное выполнение операций более чем одного устройства;
  • реализация class service callback routine, которая вызывается функциональным драйвером для передачи данных из входного буфера устройства в буфер данных драйвера класса устройств.

В ОС Windows 2000 и старше функциональным драйвером для устройств ввода, использующих PS/2-порт (клавиатуры и мыши), является драйвер i8042prt, основные функции которого следующие:

  • обеспечение аппаратно-зависимых одновременных операций PS/2-устройств ввода (клавиатуры и мыши разделяют общие порты ввода вывода, но используют разные прерывания, процедуры обработки прерываний (ISR) и процедуры завершения обработки прерываний);
  • поддержка Plug and Play, поддержка управления питанием и Windows Management Instrumentation (WMI);
  • поддержка операций для legacy-устройств;
  • вызов class service callback routine для классов клавиатуры и мыши для передачи данных из входного буфера данных i8042prt в буфер данных драйвера класса;
  • вызов набора функций обратного вызова, которые могут реализовать драйвера-фильтры высокого уровня для гибкого управления устройством.

Рис. 4. Список аппаратных ресурсов, используемых драйвером i8042prt

На рисунке показан список аппаратных ресурсов, используемых драйвером i8042prt. Их можно просмотреть, например, с помощью утилиты DeviceTree, разработанной компанией Open Systems Resources. Для тех, кто прочел разделы «Принципы работы клавиатуры как физического устройства» и «Низкоуровневое взаимодействие с клавиатурой через порты ввода-вывода», значения портов ввода-вывода (IO) 60h и 64h и аппаратного прерывания (IRQ) 1 не будут сюрпризом.

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

Стек устройств для Plug and Play PS/2-клавиатуры

Рассмотрим теперь стек устройств, которые создают указанные выше драйвера в драйверном стеке клавиатуры. Ниже на рисунке слева изображен стек устройств, приведенный в MSDN Library для PS/2-клавиатуры, справа — скриншот программы DeviceTree, показывающий реальную ситуацию на машине автора статьи.


Рис. 5. Конфигурация объектов устройств для Plug and Play PS/2-клавиатуры

В целом стек устройств (правильнее говорить о стеке объектов устройств) PS/2-клавиатуры состоит из:

  1. физического объекта устройства клавиатуры (PDO), созданного драйвером шины (в данном случае, шины PCI) – \Device\00000066;
  2. функционального объекта устройства клавиатуры (FDO), созданного и присоединенного к PDO драйвером i8042prt — неименованный объект (unnamed);
  3. опциональных фильтр-объектов устройства клавиатуры, создающихся фильтр-драйверами клавиатуры, разрабатываемыми сторонними разработчиками;
  4. верхнеуровневого фильтр-объекта устройства класса клавиатуры, созданного драйвером класса Kbdclass – \Device\KeyboardClass0.


Обработка клавиатурного ввода приложениями 

Поток необработанного ввода (получение данных от драйвера)

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

Подсистема Microsoft Win32 получает доступ к клавиатуре, используя поток необработанного ввода (Raw Input Thread, RIT), который является частью системного процесса csrss.exe. Операционная система при старте создает RIT и системную очередь аппаратного ввода (system hardware input queue, SHIQ).

RIT открывает объект «устройство» драйвера класса клавиатуры для эксклюзивного использования и с помощью функции ZwReadFile направляет ему запрос ввода-вывода (IRP) типа IRP_MJ_READ. Получив запрос, драйвер Kbdclass отмечает его как ожидающий завершения (pending), ставит в очередь и возвращает код возврата STATUS_PENDING. Потоку необработанного ввода приходится ждать завершения IRP, для чего используется вызов асинхронной процедуры (Asynchronous Procedure Call, APC).

Когда пользователь нажимает или отпускает одну из клавиш, системный контроллер клавиатуры вырабатывает аппаратное прерывание. Его обработчик вызывает специальную процедуру обработки прерывания IRQ 1 (interrupt service routine, ISR), зарегистрированную в системе драйвером i8042prt. Данная процедура считывает из внутренней очереди контроллера клавиатуры появившиеся данные. Обработка аппаратного прерывания должна быть максимально быстрой, поэтому ISR ставит в очередь вызов отложенной процедуры (Deferred Procedure Call, DPC) I8042KeyboardIsrDpc и завершает свою работу. Как только это станет возможно (IRQL понизится до DISPATCH_LEVEL), DPC будет вызвана системой. В этот момент будет вызвана процедура обратного вызова KeyboardClassServiceCallback, зарегистрированная драйвером Kbdclass у драйвера i8042prt. KeyboardClassServiceCallback извлечет из своей очереди ожидающий завершения запрос IRP, заполнит максимальное количество структур KEYBOARD_INPUT_DATA, несущих всю необходимую информацию о нажатиях/отпусканиях клавиш, и завершит IRP. Поток необработанного ввода пробуждается, обрабатывает полученную информацию и вновь посылает IRP типа IRP_MJ_READ драйверу класса, который опять ставится в очередь до следующего нажатия/отпускания клавиши. Таким образом, у стека клавиатуры всегда есть по крайней мере один ожидающий завершения IRP, и находится он в очереди драйвера Kbdclass.


Рис. 6. Последовательность запросов от RIT к драйверу клавиатуры

С помощью утилиты IrpTracker, разработанной упоминавшейся ранее компанией Open Systems Resources, можно отследить последовательность вызовов, происходящих при обработке клавиатурного ввода.


Рис. 7. Обработка клавиатурного ввода в пользовательском режиме

Как же RIT обрабатывает поступившую информацию? Все пришедшие клавиатурные события помещаются в системную очередь аппаратного ввода, после чего они последовательно преобразуются в сообщения Windows (типа WM_KEY*, WM_?BUTTON* или WM_MOUSEMOVE) и ставятся в конец очереди виртуального ввода (virtualized input queue, VIQ) активного потока. В сообщениях Windows скан-коды клавиш заменяются на коды виртуальных клавиш, соответствующие не расположению клавиши на клавиатуре, а действию, которое выполняет эта клавиша. Механизм преобразования кодов зависит от активной раскладки клавиатуры, одновременных нажатий других клавиш (например, SHIFT) и других факторов.

Когда пользователь входит в систему, процесс Windows Explorer порождает поток, который создает панель задач и рабочий стол (WinSta0_RIT). Этот поток привязывается к RIT. Если пользователь запускает MS Word, то его поток, создавший окно, немедленно подключится к RIT. После этого поток, принадлежащий Explorer, отключается от RIT, так как единовременно с RIT может быть связан только один поток. При нажатии клавиши в SHIQ появится соответствующий элемент, что приведет к тому, что RIT пробудится, преобразует событие аппаратного ввода в сообщение от клавиатуры и поместит его в VIQ потока приложения MS Word.

Обработка сообщений конкретным окном

Как же поток обрабатывает сообщения от клавиатуры, попавшие в его очередь сообщений?

Стандартный цикл обработки сообщений обычно выглядит следующим образом:

while(GetMessage(&msg, 0, 0, 0))
{
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}

С помощью функции GetMessage события от клавиатуры извлекаются из очереди и перенаправляются с помощью функции DispatchMessage оконной процедуре, которая производит обработку сообщений для окна, где в данный момент сосредоточен фокус ввода. Фокус ввода — атрибут, который может присваиваться окну, созданному приложением или Windows. Если окно имеет фокус ввода, соответствующая функция этого окна получает все клавиатурные сообщения из системной очереди. Приложение может передавать фокус ввода от одного окна другому, например, при переключении на другое приложение с помощью комбинации Alt+Tab.

Перед функцией DispatchMessage обычно вызывается функция TranslateMessage, которая на основе сообщений WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP создает «символьные» сообщения WM_CHAR, WM_SYSCHAR, WM_DEADCHAR и WM_SYSDEADCHAR. Образованные символьные сообщения помещаются в очередь сообщений приложения, причем оригинальные клавиатурные сообщения из этой очереди не удаляются.

Массивы состояния клавиш клавиатуры

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

Информация о том, какие клавиши нажаты, сохраняется в массиве синхронного состояния клавиш. Этот массив включается в переменные локального состояния ввода каждого потока. В то же время массив асинхронного состояния клавиш, в котором содержится аналогичная информация, — только один, и он разделяется всеми потоками. Массивы отражают состояние всех клавиш на данный момент, и функция GetAsyncKeyState позволяет определить, нажата ли сейчас заданная клавиша. GetAsyncKeyState всегда возвращает 0 (не нажата), если ее вызывает другой поток, а не тот, который создал окно, находящееся сейчас в фокусе ввода.

Функция GetKeyState отличается от GetAsyncKeyState тем, что возвращает состояние клавиатуры на тот момент, когда из очереди потока извлечено последнее сообщение от клавиатуры. Эту функцию можно вызвать в любой момент; для нее неважно, какое именно окно в фокусе.



Клавиатурные ловушки

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

Функции, получающие уведомления о событиях, называются фильтрующими функциями и различаются по типам перехватываемых ими событий. Для того чтобы Windows смогла вызывать функцию-фильтр, эта функция должна быть прикреплена к хуку (например, к клавиатурному хуку). Прикрепление одной или нескольких фильтрующих функций к какому-нибудь хуку называется установкой хука. Для установки и удаления фильтрующих функций приложения используют функции Win32 API SetWindowsHookEx и UnhookWindowsHookEx. Некоторые хуки можно устанавливать как для всей системы, так и для одного конкретного потока.

Если к одному хуку прикреплено несколько фильтрующих функций, Windows реализует очередь функций, причем функция, прикрепленная последней, оказывается в начале очереди, а самая первая функция — в ее конце. Очередь функций-фильтров (см. рисунок 8) поддерживается самой Windows, что позволяет упростить написание фильтрующих функций и улучшить производительность операционной системы.

Система поддерживает отдельные цепочки для каждого типа хуков. Цепочка хуков — это список указателей на фильтрующие функции (специальные функции обратного вызова, определяемые приложением). Когда происходит некоторое событие, связанное с конкретным типом хука, система последовательно передает сообщение каждой фильтрующей функции в цепочке хуков. Действие, которое может выполнить фильтрующая функция, зависит от типа ловушки: некоторые функции могут только отслеживать возникновение событий, другие могут модифицировать параметры сообщений или даже остановить обработку сообщений, заблокировав вызов следующей фильтрующей функции в цепочке хуков или функции обработки сообщений окна-назначения.


Рис. 8. Цепочка функций-фильтров в Windows

Когда к хуку прикреплена одна или более функций-фильтров и происходит событие, приводящее к срабатыванию хука, ОС Windows вызывает первую функцию из очереди функций-фильтров, и на этом ее ответственность заканчивается. Далее функция ответственна за то, чтобы вызвать следующую функцию в цепочке, для чего используется функция Win32 API CallNextHookEx.

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

Для автора кейлоггера могут представлять интерес хуки почти всех типов: WH_KEYBOARD, WH_KEYBOARD_LL (перехват клавиатурных событий при добавлении их в очередь событий потока), WH_JOURNALRECORD и WH_JOURNALPLAYBACK (запись и воспроизведение клавиатурных и «мышиных» событий), WH_CBT (перехват множества событий, включая удаление клавиатурных событий из системной очереди аппаратного ввода), WH_GETMESSAGE (перехват событий, получаемых из очереди событий потока).



Общая схема обработки

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

  1. Операционная система при старте создает в системной процессе csrss.exe поток необработанного ввода и системную очередь аппаратного ввода.
  2. Поток необработанного ввода в цикле посылает запросы чтения драйверу класса клавиатуры, которые остаются в состоянии ожидания до появления событий от клавиатуры.
  3. Когда пользователь нажимает или отпускает клавишу на клавиатуре, микроконтроллер клавиатуры фиксирует нажатие/отпускание клавиши и посылает в центральный компьютер скан-код нажатой клавиши и запрос на прерывание.
  4. Системный контроллер клавиатуры получает скан-код, производит преобразование скан-кода, делает его доступным на порту ввода-вывода 60h и генерирует аппаратное прерывание центрального процессора.
  5. Контроллер прерываний вызывает процедуру обработки прерывания IRQ 1, — ISR, зарегистрированную в системе функциональным драйвером клавиатуры i8042prt.
  6. Процедура ISR считывает из внутренней очереди контроллера клавиатуры появившиеся данные, переводит скан-коды в коды виртуальных клавиш (независимые значения, определенные системой) и ставит в очередь вызов отложенной процедуры I8042KeyboardIsrDpc.
  7. Как только это становится возможным, система вызывает DPC, которая в свою очередь вызывает процедуру обратного вызова KeyboardClassServiceCallback, зарегистрированную драйвером класса клавиатуры Kbdclass.
  8. Процедура KeyboardClassServiceCallback извлекает из своей очереди ожидающий завершения запрос от потока необработанного ввода и возвращает в нем информацию о нажатой клавише.
  9. Поток необработанного ввода сохраняет полученную информацию в системной очереди аппаратного ввода и формирует на ее основе базовые клавиатурные сообщения Windows WM_KEYDOWN, WM_KEYUP, которые ставятся в конец очереди виртуального ввода VIQ активного потока.
  10. Цикл обработки сообщений потока удаляет сообщение из очереди и передает его соответствующей оконной процедуре для обработки. При этом может быть вызвана системная функция TranslateMessage, которая на основе базовых клавиатурных сообщений создает дополнительные «символьные» сообщения WM_CHAR, WM_SYSCHAR, WM_DEADCHAR и WM_SYSDEADCHAR.

Модель прямого ввода (Raw Input)

Описанная выше модель клавиатурного ввода имеет ряд недостатков с точки зрения разработчиков приложений. Так, для получения ввода от нестандартного устройства приложение должно выполнить значительное число операций: открыть устройство, периодически его опрашивать, заботиться о возможности параллельного использования устройства другим приложением и т.д. Поэтому в последних версиях ОС Windows была предложена альтернативная модель ввода, названная моделью прямого ввода, упрощающая разработку приложений, использующих нестандартные устройства ввода (см. рисунок 3, приложения DirectInput).

Модель прямого ввода отличается от оригинальной модели ввода Windows. В обычной модели приложение получает устройство-независимый ввод в форме сообщений (таких как WM_CHAR), которые посылаются окнам приложения. В модели прямого ввода приложение должно зарегистрировать устройства, от которых оно хочет получать ввод. Далее приложение получает пользовательский ввод через сообщение WM_INPUT. Поддерживается два способа передачи данных — стандартный и буферизированный; для интерпретации введенных данных приложению нужно получить информацию о природе устройства ввода, что можно сделать с помощью функции GetRawInputDeviceInfo.



Варианты реализации кейлоггеров

Далее мы рассмотрим основные методы реализации кейлоггеров, основываясь на описанной выше модели обработки клавиатурного ввода в ОС Windows. Зная, как устроена эта модель, проще понять, какие механизмы могут быть использованы кейлоггерами.

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


Рис. 9. Общая схема обработки клавиатурного ввода в ОС Windows

В данном разделе мы не будем рассматривать аппаратные методы реализации кейлоггеров. Заметим лишь, что существуют три основных разновидности реализации аппаратных кейлоггеров: кейлоггер, встраиваемый в саму клавиатуру; кейлоггер, встраиваемый в разрыв кабеля, соединяющего клавиатуру и системный блок; кейлоггер, встраиваемый в системный блок компьютера. Самым распространенным является второй тип аппаратных кейлоггеров, один из самых известных примеров которых — KeyGhost USB Keylogger.

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


Кейлоггеры пользовательского режима

Кейлоггеры пользовательского режима — наиболее простые как для реализации, так и для обнаружения, поскольку для перехвата они используют вызовы известных и хорошо документированных функций программного интерфейса Win32 API.

Установка ловушки для клавиатурных сообщений

Пожалуй, это самый распространенный метод реализации кейлоггеров. Посредством вызова функции SetWindowsHookEx кейлоггер устанавливает глобальную ловушку на клавиатурные события для всех потоков в системе (см. раздел «Клавиатурные ловушки»). Фильтрующая функция ловушки в этом случае располагается в отдельной динамической библиотеке, которая внедряется во все процессы системы, занимающиеся обработкой сообщений. При выборке из очереди сообщений любого потока клавиатурного сообщения система вызовет установленную фильтрующую функцию.

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

Примером кейлоггеров, использующих данный метод реализации, являются AdvancedKeyLogger, KeyGhost, Absolute Keylogger, Actual Keylogger, Actual Spy, Family Key Logger, GHOST SPY, Haxdoor, MyDoom и другие.

Kaspersky Internet Security проактивно детектирует такого рода кейлоггеры как invader (loader) (должна быть включена опция «Внедрение оконных перехватчиков» подсистемы «Анализ активности приложений» модуля проактивной защиты).

Использование циклического опроса состояния клавиатуры

Является вторым по распространенности методом реализации кейлоггеров. Состояние всех клавиш с небольшим интервалом опрашивается с помощью функций GetAsynсKeyState или GetKeyState. Данные функции возвращают массивы асинхронного или синхронного состояния клавиш (см. раздел «Массив синхронного состояния клавиш»); анализируя их, можно понять, какие клавиши были нажаты или отпущены после последнего опроса.

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

Данный метод реализации используется в таких кейлоггерах, как Computer Monitor, Keyboard Guardian, PC Activity Monitor Pro, Power Spy, Powered Keylogger, Spytector, Stealth KeyLogger, Total Spy.

Kaspersky Internet Security проактивно детектирует подобные кейлоггеры как Keylogger (должна быть включена опция «Обнаружение клавиатурных перехватчиков» подсистемы «Анализ активности приложений» модуля проактивной защиты).

Внедрение в процесс и перехват функций обработки сообщений

Редко реализуемый метод реализации кейлоггера. Кейлоггер внедряется во все процессы и перехватывает в них функции GetMessage или PeekMessage (см. раздел «Обработка сообщений конкретным окном») из библиотеки user32.dll. Для этого могут быть использованы различные методы: сплайсинг (сплайсинг — метод, используемый для перехвата вызова API-функций; суть метода состоит в замене нескольких (обычно 5) первых байт функции инструкцией JMP, передающей управление коду-перехватчику), модификация таблицы адресов импортируемых функций IAT, перехват функции GetProcAddress, возвращающей адрес функции из загруженной динамической библиотеки. Кейлоггер может реализовываться в виде DLL или при помощи непосредственного внедрения кода в целевой процесс.

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

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

Недостатки: модификация таблицы IAT не гарантирует перехвата, т.к. адреса функций библиотеки user32.dll могут быть сохранены до того, как кейлоггер внедрился; сплайсинг имеет свои сложности, связанные, например, с необходимостью переписывать «на лету» тело функции.

Kaspersky Internet Security проактивно детектирует такие кейлоггеры как invader (должна быть включена опция «Внедрение в процесс (invaders)» подсистемы «Анализ активности приложений» модуля проактивной защиты).

Использование модели прямого ввода

В настоящий момент известен лишь один пример реализации данного метода — утилита тестирования защищенности системы от кейлоггеров. Суть метода заключается в использовании новой модели прямого ввода (см. раздел «Модель прямого ввода (Raw Input)»), для чего кейлоггер регистрирует клавиатуру в качестве устройства, от которого он хочет получать ввод. После этого кейлоггер начинает получать данные о нажатых и отпущенных клавишах через сообщение WM_INPUT.

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

Недостатки — простота обнаружения по причине необходимости специальной регистрации на получение приложением прямого ввода (по умолчанию ни один из процессов в системе его не получает).

Kaspersky Internet Security 7.0 будет проактивно детектировать такие кейлоггеры как Keylogger (должна быть включена опция «Обнаружение клавиатурных перехватчиков» подсистемы «Анализ активности приложений» модуля проактивной защиты).


Кейлоггеры режима ядра

Кейлоггеры режима ядра значительно более сложные, чем кейлоггеры пользовательского режима — как для реализации, так и в плане обнаружения. Они требуют специальных знаний для написания, но позволяют создавать кейлоггеры, абсолютно незаметные для всех приложений пользовательского режима. Для перехвата могут использоваться как документированные в Microsoft Driver Development Kit, так и недокументированные методы.

Использование драйвер-фильтра драйвера класса клавиатуры Kbdclass

Документированный в DDK способ перехвата (см. раздел «Стек драйверов для Plug and Play PS/2-клавиатуры»). Кейлоггеры, построенные на основе этого метода, перехватывают запросы к клавиатуре посредством установки фильтра поверх устройства «\Device\KeyboardClass0», созданного драйвером Kbdclass (см. раздел «Стек устройств для Plug and Play PS/2-клавиатуры»). Фильтруются только запросы типа IRP_MJ_READ, поскольку именно они позволяют получить коды нажатых и отпущенных клавиш.

Достоинства — гарантированный перехват всех нажатий, невозможность обнаружения без использования драйвера, благодаря чему не все антикейлоггеры их определяют. Недостатки — необходимость установки собственного драйвера.

Самыми известными кейлоггерами, использующими данный метод реализации, являются ELITE Keylogger и Invisible KeyLogger Stealth.

Kaspersky Internet Security проактивно детектирует такие кейлоггеры как Keylogger путем мониторинга клавиатурного стека устройств (должна быть включена опция «Обнаружение клавиатурных перехватчиков» подсистемы «Анализ активности приложений» модуля проактивной защиты).

Использование драйвер-фильтра функционального драйвера i8042prt

Документированный в DDK способ перехвата. Кейлоггеры, построенные на основе этого метода, перехватывают запросы к клавиатуре посредством установки фильтра поверх безымянного устройства, создаваемого драйвером i8042prt под устройством Device\KeyboardClass0 (см. раздел «Стек устройств для Plug and Play PS/2-клавиатуры»). Драйвер i8042prt предоставляет собой программный интерфейс для добавления дополнительной функции обработки прерывания IRQ1 (IsrRoutine), в которой можно произвести анализ полученных от клавиатуры данных.

Достоинства и недостатки аналогичны описанным для метода, в предыдущем пункте. Но есть и дополнительный недостаток — зависимость от типа клавиатуры: драйвер i8042prt обрабатывает запросы только от PS/2 клавиатуры, поэтому рассматриваемый метод не пригоден для перехвата данных, вводимых через USB или беспроводную клавиатуру.

Kaspersky Internet Security проактивно детектирует такие кейлоггеры как Keylogger путем мониторинга клавиатурного стека устройств (должна быть включена опция «Обнаружение клавиатурных перехватчиков» подсистемы «Анализ активности приложений» модуля проактивной защиты).

Модификация таблицы обработки системных запросов драйвера Kbdclass

Кейлоггеры, построенные на основе этого метода, перехватывают запросы к клавиатуре, подменяя точку входа IRP_MJ_READ в таблице обработки системных запросов (dispatch table) драйвера Kbdclass. Функционально похож на драйвер-фильтр драйвера Kbdclass (см. раздел «2.1. Драйвера-фильтры драйвера класса kbdclass»). Особенности те же. В другом варианте используется перехват иной функции обработчика запросов — IRP_MJ_DEVICECONTROL. В этом случае кейлоггер становится подобным драйверу-фильтру драйвера i8042 (см. раздел «2.2. Драйвера-фильтры функционального драйвера i8042prt»).

Kaspersky Internet Security проактивно детектирует такие кейлоггеры как Keylogger (должна быть включена опция «Обнаружение клавиатурных перехватчиков» подсистемы «Анализ активности приложений» модуля проактивной защиты).

Модификация таблицы системных сервисов KeServiceDescriptorTableShadow

Достаточно распространенный метод реализации кейлоггеров, функционально аналогичный методу реализации пользовательского режима, описанному в разделе «1.3. Внедрение в процесс и перехват функций GetMessage/PeekMessage». Кейлоггеры, построенные на основе этого метода, перехватывают запросы к клавиатуре посредством патчинга точки входа NtUserGetMessage/PeekMessage во второй таблице системных сервисов (KeServiceDescriptorTableShadow) драйвера win32k.sys. Информация о нажатии клавиши приходит в перехватчик, когда в каком-либо потоке завершается вызов функций GetMessage или PeekMessage.

Достоинством данного метода является сложность его обнаружения, недостатком — относительная сложность реализации (поиск самой таблицы KeServiceDescriptorTableShadow — непростая задача; помимо этого, другие драйвера могут ранее пропатчить точки входа в этой таблице) и необходимость установки отдельного драйвера.

Kaspersky Internet Security проактивно детектирует такие кейлоггеры как Keylogger (должна быть включена опция «Обнаружение клавиатурных перехватчиков» подсистемы «Анализ активности приложений» модуля проактивной защиты).

Модификация кода функций NtUserGetMessage или NtUserPeekMessage путем сплайсинга

Крайне редко встречаемый тип кейлоггера. Кейлоггеры, построенные на основе этого метода, перехватывают запросы к клавиатуре, модифицируя код функций NtUserGetMessage или NtUserPeekMessage методом сплайсинга. Данные функции реализованы в ядре системы в драйвере win32k.sys и вызываются из соответствующих функций библиотеки user32.dll. Как указано в разделе «1.3. Внедрение в процесс и перехват функций GetMessage/PeekMessage», эти функции позволяют фильтровать все получаемые приложениями сообщения и получать данные о нажатии и отпускании клавиш из клавиатурных сообщений.

Достоинством данного метода является сложность его обнаружения, недостатком — трудности реализации (необходимость переписывать тело функции «на лету», зависимость от версии операционной системы и установленного программного обеспечения), а также необходимость установки драйвера.

Подмена драйвера в клавиатурном стеке драйверов

Данный метод основан на подмене драйвера Kbdclass или одного из низкоуровневых драйверов клавиатуры драйвером собственной разработки. Явным недостатком данного метода является сложность реализации, так как заранее не известен тип применяемой пользователем клавиатуры, а потому подмену драйвера сравнительно просто обнаружить. Вследствие этого подобный метод практически не реализуется на практике.

Реализация собственного драйвера-обработчика прерывания IRQ 1

Метод заключается в написании своего драйвера режима ядра, перехватывающего прерывание от клавиатуры (IRQ 1) и напрямую обращающегося к ее портам ввода-вывода (60h, 64h). В связи со сложностью реализации и не совсем ясным способом взаимодействия с системным обработчиком прерывания IRQ 1 (драйвером i8042prt.sys) в настоящее время метод является сугубо теоретическим.



Выводы

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

  1. Рассмотренная схема клавиатурного ввода в ОС Windows достаточно сложна, и практически на любом ее этапе можно установить перехватчик. На некоторых шагах алгоритма перехватчики уже реализованы, на некоторых еще нет.
  2. Существует зависимость распространенности кейлоггера от сложности его реализации. Так, наиболее распространенные методы перехвата — установка ловушки на события ввода и циклический опрос состояния клавиатуры — являются в то же время самыми простыми в реализации. Написать кейлоггер, использующий данные методы, может даже человек, научившийся программировать неделю назад.
  3. Основная масса существующих в настоящее время кейлоггеров представляет собой достаточно простой в реализации инструмент, который можно легко использовать во вредоносных целях, в первую очередь для кражи вводимой с клавиатуры конфиденциальной информации.
  4. Антивирусным компаниям необходимо обеспечить пользователей защитой от угрозы, которую представляют используемые злоумышленниками кейлоггеры.

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