#Spider
##Introduction
Le principe du Spider
est de créer un système de keylogging distribué. Un nombre arbitraire de Client
connecté à un Server
qui enregistre les différents inputs de l'utilisateur.
##Protocole
###Terminologie
Terme | Définition | Unité Protobuf
Message | Un Message
correspond à l'unité envoyé sur le réseau. | Non
Enveloppe | Une Enveloppe
est le contenu d'un Message
. Elle contient aussi |
| l'identité de l'expéditeur du message ou de sa destination. | Oui
Payload | Un Payload
correspond à la charge utile d'une Enveloppe
. |
| Il contient l'information que le Client
/Serveur
souhaite |
| transmettre. | Oui
###Protocol Buffer
Les Client
et Serveur
s'exécutant dans des environnement hétérogènes, il est nécessaire de sérialiser les donnée à envoyer pour prévenir des incompatibilités d'architectures. Par exemple les Endianness.
Protocol Buffer
de Google, à été retenu pour ses performances, sa fiabilité et sa documentation extrêmement fournie et soignée.
En quelque mots : Protocol Buffer
permet de créer des objets C++
sérialisable et dé-sérialisable. Il fonctionne à partir de data-contract,
sous forme .proto
qui représentent les données. Ces fichiers sont ensuite compilé en classe natives C++
. Ensuite, il est très simple de sérialiser/désérialiser ces objets.
Un
Message
est composé d'un identifiant et d'uneEnveloppe
. UneEnveloppe
est un conteneur pour le résultat de la sérialisation d'un message viaProtoBuf
.
###Identification
Chaque Client de vra être uniquement identifiable sur le réseau. En outre, le serveur devra pouvoir distinguer un client d'un autre et faire persister les donnée qui concernent un Client en particulier.
Chaque Client
devra générer un UUID de 16 bytes et l'incluera dans toutes les enveloppes qu'il enverra sur le réseau. En l'absence d'identification valide, le serveur rejettera la demande/connexion.
###Authentification
Les Clients et le Serveur implémente TLS
via la librairie Curves
. Chaque Client devra effectuer le handshake et l'échange de clé publique décris dans le RFC de la lib curves.
Le serveur ignorera toute connection manquant à ce principes.
###Persitence
Le serveur utilise une base de donnée pour persister les données de Keylog. Ainsi, une CLI
peut acceder aux donnée alors même qu'un client n'est pas connecté sur le réseau de keylogging.
Toute les requêtes via CLI se base sur le UUID d'un client. Cf. CLI.
Une Enveloppe
est le résultat de la sérialisation d'un contrat Protobuf
de type SpiderEnveloppe
.
Une enveloppe se définit via le contrat .proto
suivant :
message SpiderEnveloppe {
required string ClientID = 1;
required string PayloadType = 2;
required google.protobuf.Any Payload = 3;
}
Element | Type | Requis | Commentaire
ClientID | string
| Oui | Si le Message
est envoyé par le Serveur
, alors
| | | ClientID
contient l'ID du Client
destinataire. Sinon
| | | ClientID
contient l'ID du Client
émetteur.
PayloadType | string
| Oui | Content une string représentant le type final du Payload
| | | contenu par l'enveloppe. C++
n'ayant pas de réflexion,
| | | ceci est nécessaire pour dé-sérialiser le payload dans le bon format.
Payload | Any
| Oui | La charge utile de l'enveloppe, contenant la donnée que le
| | | Client
/Serveur
souhaite partager avec le Serveur
/Client
.
##Payloads
###Payloads envoyé par le Client
message SpiderKeyLoggingPayload {
message SpiderKeyLoggingContextPayload {
required string ProcessName = 1;
required string WindowsName = 2;
}
required string PlaintextKeylog = 1;
SpiderKeyLoggingContextPayload Context = 2;
}
SpiderKeyLoggingPayload
:
Element | Type | Requis | Commentaire
PlaintextKeylog | string
| Oui | Représente le keylog de l'utilisateur. La longueur de
| | | la string est arbitraire. Les touches spéciales sont
| | | formaté via la forme "[KEY]". Exemple :
| | | "Hippolyte est le meilleur [CRTL] C"
.
Context | SpiderKeyLoggingContextPayload
| Non | Représente se contexte dans lequel le keylog a été capturé.
SpiderKeyLoggingContextPayload
:
Element | Type | Requis | Commentaire
ProcessName | string
| Oui | Contient le nom du processus courant dans lequel l'input à été capturé.
WindowsName | string
| Oui | Contient le nom de la fenêtre du processus dans lequel le keylog à été capturé.
####SpiderMouseEvent
message SpiderMouseEvent {
enum MouseEventType {
RBUTTON_CLICK = 0;
LBUTTON_CLICK = 1;
MBUTTON_CLICK = 4;
MBUTTON_UP = 2;
MBUTTON_DOWN = 3;
}
MouseEventType type = 1;
uint32 X = 2;
uint32 Y = 3;
}
Element | Type | Requis | Commentaire
type | MouseEventType
| Oui | Contient l'événement de la souris qui à été capturé.
X | string
| Oui | Coordonnées X de la souris
Y | string
| Oui | Coordonnées Y de la souris
Demande au Client
de commencer son écoute des interactions utilisateur.
message SpiderStartKeylogCommandPayload {
}
Demande au Client
de stopper son écoute des interactions utilisateur.
message SpiderStopKeylogCommandPayload {
}
##Exemple de code
SpiderKeyLoggingPayload payload;
payload.set_PlaintextKeylog("Ceci est un KeyLog [ALT][TAB]");
SpiderKeyLoggingPayload::SpiderKeyLoggingContextPayload context;
context.set_ProcessName("notepad.exe");
context.set_WindowsName("Sans titre - Bloc-notes");
payload.set_Context(&context);
SpiderEnveloppe enveloppe;
enveloppe.set_ClientID("6Uy9ZRdd1W9qnKuM");
enveloppe.set_PayloadType("SpiderKeyLoggingPayload");
enveloppe.set_Payload(&payload);
std::string enveloppe_data;
enveloppe.SerializeToString(&enveloppe_data);
//enveloppe_data contient maintenant notre enveloppe. Il suffit de rajouter l'identification en début de string pour obtenir un `Message` prêt à être envoyé sur le socket.
###Reception et parsing d'un Message
de keylog sur le Serveur
std::string enveloppe_data; //Ici on part du principe que le message à été reçus sur un socket.
SpiderEnveloppe enveloppe;
enveloppe.ParseFromString(enveloppe_data);
if (enveloppe.PayloadType() == "SpiderKeyLoggingPayload" && enveloppe.Payload().Is<SpiderKeyLoggingPayload>()) {
SpiderKeyLoggingPayload payload;
enveloppe.Payload().UnpackTo(&payload);
cout << "Client keylogged \"" + payload.PlaintextKeylog() + "\"."
//Ici je ne dé-sérialize pas `SpiderKeyLoggingContextPayload`, je pense que vous avez compris le principe...
}
else {...}