Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
vbSparkle — Désovfuscateur source-à-source pour VBScript et VBA avec évaluation partielle | Kitploit
Outils/GitHubGitHub/airbus-cert/vbsparkle
Outils DéfensifsAnalyse Statique de Code (SAST)Analyse de CodeRétro-ingénierieAnalyse de Malware
GitHubairbus-cert/vbsparkle

vbSparkle

Désovfuscateur source-à-source pour VBScript et VBA avec évaluation partielle

Voir le dépôt
8213il y a 2 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

.NET NuGet NuGet Download

Qu'est-ce que vbSparkle ?

vbSparkle est un désobfuscateur Visual Basic multi-plateforme, de source à source, basé sur l'évaluation partielle et principalement dédié à l'analyse de code malveillant écrit en VBScript et en VBA (macro Office).

Il est écrit en C# natif et fournit une bibliothèque .Net Standard; il fonctionne sur Windows, Linux, macOS, etc.

L'analyse de Visual Basic Script et de VBA est effectuée grâce à la grammaire et aux analyseurs lexicaux d'ANTLR.

Installation

Gestionnaire de packages

Install-Package vbSparkle

.Net CLI

dotnet add package vbSparkle

Comment l'utiliser ?

En tant que bibliothèque

Une fois que vous avez ajouté la bibliothèque vbSparkle à votre projet, il vous suffit d'appeler la fonction PrettifyEncoded de la classe statique VbPartialEvaluator :

root@kitploit:~
string obfuscatedVB = "msgbox(chr(65)&chr(66)&(chr(67))"
string deobfuscated = VbPartialEvaluator.PrettifyEncoded(obfuscatedVB);

... retournera MsgBox("ABC").

En tant que CLI

Le projet joint vbSparkle.CLI est un exemple d'utilisation de vbSparkle en tant que CLI. L'exemple actuel prend soit un chemin en argument, soit un binaire complet dans StdIn, et renvoie le résultat désobfusqué. Diagramme ferroviaire

Interface Web

Le projet joint vbSparkle.Web est un exemple d'utilisation de vbSparkle dans une interface Web. Diagramme ferroviaire

Pourquoi écrire un désobfuscateur VBScript basé sur l'évaluation partielle ?

L'obfuscation de code VBScript et VBA est populaire parmi les attaquants et permet de contourner les mesures de détection, les antivirus, les pare-feu, les EDR, et rend l'analyse des malwares plus difficile.

Ainsi, il est courant de voir du VBScript obfusqué dès le tout premier stade d'une compromission de machine.

Une technique typique d'obfuscation de code VBScript consiste à encapsuler le script dans une chaîne obfusquée et à l'exécuter via la fonction Execute("...code..." function) après qu'elle a été décodée / évaluée.

Voyons un exemple :

root@kitploit:~
Execute(chr( 456127/3833 ) & chr( 817650/7110 ) & chr( 759429/7671 ) & chr( 834138/7317 ) & chr( 57960/552 ) & chr( 2549-2437 ) & chr( 1078568/9298 ) & chr( 5143-5097 ) & chr( -8682+8783 ) & chr( 529-430 ) & chr( 673088/6472 ) & chr( 761682/6862 ) & chr( 302336/9448 ) & chr( 9427-9393 ) & chr( 410176/3944 ) & chr( -5271+5372 ) & chr( 796608/7376 ) & chr( 2896-2788 ) & chr( 318792/2872 ) & chr( 1076-1042 ) &  vbcrlf  ) 

Ici, l'attaquant a utilisé :

  • la fonction chr(CHAR_CODE) pour évaluer un caractère de chaîne (par ex. chr(65) = "A")
  • des opérations arithmétiques (par ex. 456127/3833) pour évaluer la valeur du caractère
  • la concaténation de chaînes & pour assembler tous les caractères décodés
  • l'appel à la fonction Execute(..) pour exécuter le script décodé.

Si nous suivons l'exécution du script :

  • 456127/3833 => 119
  • chr(119) => "w"
  • 817650/7110 => 115
  • chr(115) => "s"
  • "w" & "s" => "ws"
  • Execute("ws.....

Voici le script original : wscript.echo "hello"

Une désobfuscation manuelle devient très difficile et chronophage sur de grands scripts. Une technique de désobfuscation courante avec VBScript consiste simplement à remplacer la fonction Execute() par WScript.Echo(, puis à exécuter le script pour obtenir la sortie.

Cette dernière technique est simple mais présente quelques inconvénients :

  • nécessite au moins une machine virtuelle / un sandbox pour exécuter le script en toute sécurité ;
  • l'automatisation de cette technique est dangereuse et aléatoire ;
  • elle ne permet pas de comprendre l'intégralité du code et ses effets de bord ;
  • certaines tâches conditionnelles peuvent être manquées, selon l'environnement d'exécution ;

Et, au moment où ce projet a démarré, il n'existait aucune alternative à ces deux techniques.

Écrire un évaluateur partiel Visual Basic

L'évaluation partielle n'est pas un concept nouveau ; elle est surtout utilisée par les compilateurs pour l'optimisation de code dans les processus de pré-compilation (par ex. https://en.wikipedia.org/wiki/Partial_evaluation).

Un évaluateur partiel lit un programme (appelé le programme sujet) ainsi que certaines des entrées de ce programme, et n'évalue que les parties du programme qui dépendent des entrées fournies. Une fois toutes ces parties évaluées, le programme restant (appelé le programme résiduel) est émis en sortie.

Par exemple, un processus de pré-compilation transformerait le code sujet suivant :

root@kitploit:~
var1 = 3*3 
var2 = sin(arg1)
var3 = var1 + func_xx(2 * var1 + var2)

en le code résiduel suivant :

root@kitploit:~
var2 = sin(arg1)
var3 = 9 + func_xx(18 + var2)

Le code a été partiellement évalué avant la compilation, afin d'optimiser les performances.

On voit que ce processus simplifie le code et élimine les opérations inutiles. C'est intéressant car l'obfuscation masque le code en ajoutant du code et des opérations inutiles pour l'exécution du code.

Si nous inspectons notre échantillon initial, étape par étape :

  • les opérations arithmétiques comme : 456127/3833 peuvent être partiellement évaluées : aucun effet de bord
  • chr(119) peut être partiellement évaluée : 119 est une constante, et c'est une fonction native, aucun effet de bord
  • "w" & "s" peut être partiellement évalué : c'est une concaténation de caractères constants, aucun effet de bord
  • Execute( a un effet de bord connu (exécution de script), elle ne sera pas évaluée, sauf si les effets de bord des fonctions peuvent être gérés / émulés

Une évaluation partielle de cet échantillon donnerait : Execute("wscript.echo ""hello""" & vbCrLf)

Et devinez quoi ? Nous venons de désobfusquer notre échantillon.

La théorie, c'est bien, mais en pratique ?

Eh bien, en pratique, c'est bien plus compliqué :

  • Pour réaliser un évaluateur partiel, vous avez besoin d'un analyseur syntaxique (parser).
  • Pour obtenir un analyseur syntaxique, vous avez besoin d'un analyseur lexical (lexer) et d'une grammaire.

Heureusement, ANTLR est un puissant générateur d'analyseurs syntaxiques pour lire, traiter, exécuter ou traduire du texte structuré ou des fichiers binaires. Il est connu pour être largement utilisé afin de construire des langages, des outils et des frameworks. À partir d'une grammaire, ANTLR génère un analyseur syntaxique capable de construire des arbres d'analyse et génère également une interface d'écoute (listener) (ou un visiteur) qui facilite la réponse à la reconnaissance des expressions d'intérêt.

ANTLR peut générer des analyseurs lexicaux, des analyseurs syntaxiques, des analyseurs d'arbres et des analyseurs combinés lexeur-parseur. Les analyseurs syntaxiques peuvent générer automatiquement des arbres d'analyse ou des arbres de syntaxe abstraite qui peuvent ensuite être traités avec des analyseurs d'arbres. ANTLR fournit une notation unique et cohérente pour spécifier les analyseurs lexicaux, les analyseurs syntaxiques et les analyseurs d'arbres.

Par défaut, ANTLR lit une grammaire et génère un reconnaisseur pour le langage défini par la grammaire (c'est-à-dire un programme qui lit un flux d'entrée et génère une erreur si le flux d'entrée n'est pas conforme à la syntaxe spécifiée par la grammaire).

Afin de faire quelque chose d'utile avec le langage, des actions peuvent être attachées aux éléments de la grammaire. Ces actions sont écrites dans le langage de programmation dans lequel le reconnaisseur est généré. Lorsque le reconnaisseur est généré, les actions sont intégrées dans le code source du reconnaisseur aux points appropriés.

Comment cela fonctionne, en gros

Grâce à ANTLR, il a été rapide et facile de générer une première version de l'AST, de l'analyseur lexical et de l'analyseur syntaxique grâce à la grammaire existante écrite par Ulrich Wolffgang.

Exemple de diagramme ferroviaire de la grammaire VB : Diagramme ferroviaire

Cette grammaire ne fonctionnait pas parfaitement avec certaines syntaxes Visual Basic spécifiques (code en ligne, certains problèmes d'opérateurs) et quelques modifications ont été nécessaires pour fournir une grammaire entièrement compatible VBS et VBA. La grammaire modifiée est disponible ici : Visual Basic Grammar

Voici un exemple d'arbre d'analyse visuel du morceau de code suivant :

root@kitploit:~
Msgbox("Hello world " & Chr(33), vbCritical, "The Title")

Exemple d'arbre d'analyse

Une fois l'analyseur syntaxique et l'AST générés, nous pouvons commencer à les utiliser et explorer notre code :

root@kitploit:~
using Antlr4.Runtime;
using System.Linq;

namespace vbSparkle
{
    public class PartialEvaluator
    {
        public static string Prettify(string script)
        {
            var inputStream = new AntlrInputStream(script);

            // Create the lexer
            var lexer = new VBScriptLexer(inputStream);

            // Instanciate of common token from lexer
            var commonTokenStream = new CommonTokenStream(lexer);

            // Create the parser
            var parser = new VBScriptParser(commonTokenStream);

            // Get the start rule (root element of our AST) 
            VBScriptParser.StartRuleContext stContext = parser.startRule();

            // Instanciate the visitor
            VbAnalyser analyser = new VbAnalyser();

            // Visit the AST
            analyser.Visit(stContext);

            // Root AST element of a vbScript being a "Module", we get it
            var module = analyser.Modules.FirstOrDefault();

            // Then we partially evaluate our module
            string result = module.Prettify(partialEvaluation: true);
            return result;
        }
    }
}

Un visiteur est chargé de parcourir l'AST et de créer pour chaque nœud un évaluateur partiel / embellisseur. Ces derniers seront chargés d'évaluer récursivement : Flux de travail

Par exemple, voici notre visiteur, qui instancie un évaluateur VbModule :

root@kitploit:~
    public class VbAnalyser
    {
        public List<VbModule> Modules { get; set; } = new List<VbModule>();

        internal void Visit(VBScriptParser.StartRuleContext stContext)
        {
            var moduleContext = stContext.module();

            VbModule module = new VbModule(this, moduleContext);
            Modules.Add(module);
        }
    }

Voici un exemple de nœud avec la fonction Prettify :

root@kitploit:~
    public class VbOnGotoStatement : VbStatement<VBScriptParser.OnGoToStmtContext>
    {
        public VBValueStatement OnValue { get; set; }
        public VBValueStatement[] GotoValues { get; set; }

        public VbOnGotoStatement(IVBScopeObject context, VBScriptParser.OnGoToStmtContext bloc)
            : base(context, bloc)
        {
            OnValue = VBValueStatement.Get(context, bloc.valueStmt().First());
            GotoValues = bloc.valueStmt().Skip(1).Select(v => VBValueStatement.Get(context, v)).ToArray();
        }

        public override DExpression Prettify(bool partialEvaluation = false)
        {
            return new DCodeBlock($"On {OnValue.Prettify(partialEvaluation)} Goto {string.Join(", ", GotoValues.Select(v=> v.Prettify(partialEvaluation)))}");
        }
    }

Lorsque le nœud est visité grâce au constructeur VbOnGotoStatement(, il visite récursivement les sous-nœuds et crée des instances de leurs propres visiteurs. Ensuite, lorsque la méthode Prettify est appelée, les sous-éléments sont embellis avec le même niveau d'évaluation partielle.

Crédits

Ce projet est sous copyright de l'Airbus CERT et distribué sous la licence Apache 2.0.

Télécharger l’outil