Plan du site  
pixel
pixel

Articles - Étudiants SUPINFO

Qu'est-ce que l'obfuscation de code ?

Par Valentin BUSSEUIL Publié le 15/10/2015 à 22:18:58 Noter cet article:
(0 votes)
Avis favorable du comité de lecture

Introduction

Cet article est destiné à tous les développeurs souhaitant aborder certaines notions de sécurités en terme de développement informatique. Dans un premier temps, nous détaillerons l'obfuscation de manière bidirectionnelle (attaquant/défenseur). Ensuite, cet article présentera certains cas pratiques élaborés sur différentes méthodes d'obfuscation.

Une protection contre qui, quoi ?

Tout d'abord, pourquoi parler d'obfuscation ? En quoi cela consiste ? Dans quel but l'utilisons-nous et pourquoi ?

En tant que développeur, vous n'êtes pas sans savoir que vos codes sources peuvent être à votre insu, dérobé par un petit malin munis d'un décompilateur voulant s'approprier le fruit de votre travail ! En effet, le décompilateur a pour ambition de reconstituer, de manière totale ou partielle, le code source d’un programme exécutable. De quoi vous rendre fou lorsqu'un tiers a le moyen de s'attribuer votre mérite en un vulgair copier/coller.

Qu'est-ce que l'obfuscation ?

L'obfuscation de code est une discipline de développement ayant pour objectif de protéger vos codes sources en les rendant inintelligibles aussi bien pour un être humain qu’un décompilateur, tout en le préservant de son parfait fonctionnement lors de la compilation. Le procédé d'obfuscation a pour finalité de donner un code dit impénétrable. Cette technique favorise la confidentialité de toutes propriétés intellectuelles contre la rétro-ingénierie. Pourquoi parler de propriété intellectuelles ?

L'exemple le plus explicite que je peux vous donner s'appuie sur cette notion de propriété intellectuelle. En effet, un éditeur de logiciels à plutôt intérêt à promouvoir la confidentialité et la sécurité de ses produits. En définitive, ces deux qualités sont vitales pour la pérennité et la diffusion d'une application.

L'obfuscation, un avantage ?

L'obfuscation délivre plusieurs attributs non négligeables :

  • Protection de code

  • Performance

  • Camouflage

  • Peu onéreuse en terme de coût pour les entreprises

  • Transparence intégrale pour les développeurs et utilisateurs

Il est évident que cette technologie délivre un vrai avantage si vous voulez assurer un cycle de vie convenable à votre application, de plus la confidentialité restera mot d'ordre dans toutes entreprises.

Qu'est-ce que la rétro-ingénierie ?

La rétro-ingénierie, appelée plus couramment par son équivalence anglophone "reverse engineering", est une technique permettant de déterminer le fonctionnement interne d'une application en la désassemblant à partir de son état compilé. Autrement dit, de générer les codes sources à partir d'un programme exécutable. En outre, certaines ressources protégés comme les données de connexions aux bases de données peuvent être décelées et peuvent alors engendrer des dommages irréversibles dans certaines organisations. Il existe plusieurs techniques permettant de faire face à la rétro-ingienerie comme le chiffrement ou encore l'éxécution de code distant, hors ici nous étudieront uniquement la notion d'obfuscation.

Une approche plus technique

Mais concrètement, l'obfuscation ressemble à quoi ?

// Code 1 
alert("Hello SUPINFO")
// Code 2
$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:
({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])
+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$
($.$$+"\""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.__+"(\\\"\\"+$.__$+$.__$+$.___+$.$$$_+(![]+"")[$._$_]+(![]+"")[$._$_]+$._$+"\\"
+$.$__+$.___+"\\"+$.__$+$._$_+$._$$+"\\"+$.__$+$._$_+$.$_$+"\\"+$.__$+$._$_+$.___+"\\"+$.__$+$.__$+$.__$+"\\"+$.__$+$.__$+$.$$_+"\\"+$.__$+$.___
+$.$$_+"\\"+$.__$+$.__$+$.$$$+"\\\")"+"\"")())();

D'après vous, quelle différence y a-t-il entre ces deux codes ? Aucune ! Ces scripts font exactement le même travail, excepté le fait que le deuxième soit passé par une phase d'obfuscation. Cet exemple a pour but de vous montrer à titre indicatif l'apparence d'un code source obfusqué, ici, le deuxième code produit exactement la même alerte JavaScript que son prédécesseur.

Les notions d'obfuscation

Nous allons maintenant aborder une liste de notions d'obfuscations. Elle n'aura pas pour but d'être exhaustive, mais je citerais principalement les notions les plus importantes et les plus utilisées.

  • Attribution de nouveaux noms d'identifieurs

  • Réduction du code

  • Le pruning

  • Suppression du style algorithmique

La suite de cet article aura pour objectif de passer en revue ces notions accompagnées d'un exemple explicite.

Attribution de nouveaux noms aux identifieurs

Ce principe vise tous les identifieurs d'un programme donné : variables, méthodes, attributs, classes, constantes. Rappellons que le but de l'obfuscation est de rendre le code source incompréhensible, c'est pourquoi nous changeons le nom de tous les identifeurs en leur générant une chaine de caractère aléatoire afin de les rendre absurde et complètement incompréhensible.

Il existe trois méthodes permettant d'attribuer de nouveaux noms aux identifieurs : La méthode aléatoire,l’overload inductionet l’invisibilité.

  • La méthode aléatoire fournit un identifiant aléatoire à chaque identifieur.

  • l’overload induction fournit à un maximum d'identifieurs à la même chaine de caractère (exemple : int count devient int a, getCount() devient a()). Ce procédé tente de renommer autant d'identifieurs que possible avec exactement le même nom. L'overload induction a plusieurs avantages comme la réduction de la taille du code, le gain d'espace sur les entrées de tas de chaînes.

  • La méthode d'invisibilité fournit des caractères spéciaux interdits par le langage à chaque identifieur.

//Code C# non obfusqué

     public int fibonacci(int n) 
     {
        if (n <= 2)
           return n;
        else
           return fibonacci(n-1) + fibonacci(n-2);
     }
//Code C# obfusqué par la notion de méthode aléatoire
    
     public int 27u857i7ut83j9yn9kdt(int 79ahuh5f7vg76339vi4u) 
     {
        if (79ahuh5f7vg76339vi4u <= 2)
           return 79ahuh5f7vg76339vi4u;
        else
           return 27u857i7ut83j9yn9kdt(79ahuh5f7vg76339vi4u-1) + 27u857i7ut83j9yn9kdt(79ahuh5f7vg76339vi4u-2);
     }
//Code C# obfusqué par la notion d'overload induction

     public int a(int a) 
     {
        if (a <= 2)
           return a;
        else
           return (a-1) + a(a-2);
     }
//Code C# obfusqué par la notion d'invisibilité

     public int 5~@(int #a$) 
     {
        if (#a$ <= 2)
           return #a$;
        else
           return 5~@(#a$-1) + 5~@(#a$-2);
     }
Pruning (élagage des déclarations d'API non utilisées)

Un projet de développement utilise obligatoirement des API qui lui permettent de faire appel à des classes, méthodes etc. En effet, l'élagage des déclarations consiste à minimiser au maximum l'appel des bibliothèques non utilisées, afin de fournir un minimum d'indices sur l'algorithme employé.

// Code Java avec de nombreux imports

import com.jogamp.newt.*
import com.jogamp.opengl.*
import javax.swing.*
// Code Java avec des imports minimisés

import com.jogamp.newt.awt.applet
import com.jogamp.opengl.awt
import javax.swing.border

Suppression des commentaires

Tout développement logiciel de qualité se doit d'être commenté, un programme correctement commenté est de constitué de plus de 50% de commentaires. Ici, nous allons faire impasse sur cette règle, car rappelons-le, l'objectif est de fournir le minimum d'indice sur le code source. Vous l'aurez donc compris, nous supprimons l'intégralité des commentaires de notre programme.

// Code C# commenté

        public bool Listen()
        {
            //Console.WriteLine("Launching.");
            if (!_exitLoop)
            {
                //Console.WriteLine("Listener running already");
                return false;
            }
            _exitLoop = false;

            try
            {
                _listener = new TcpListener(IPAddress.Parse(IpAddress), Port);
                _listener.Start();
                Loop();

                return true;
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
            return false; // Return exception
        } // End
// Code C# non commenté

        public bool Listen()
        {
            if (!_exitLoop)
            {
                return false;
            }
            _exitLoop = false;

            try
            {
                _listener = new TcpListener(IPAddress.Parse(IpAddress), Port);
                _listener.Start();
                Loop();

                return true;
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
            return false;
        } 
Suppression du style algorithmique

Le style algorithmique d'une application permet de définir une lisibilité du code intuitive pour ainsi, de manière logique, en déduire son fonctionnement. Le code de base suivant les conventions de codage sera alors minifié afin d'apporter la lisibilité la plus maigre possible.

// Code C# stylisé

        public void Send(int sock, byte[] b)
        {
            try
            {
                MemoryStream m = new MemoryStream();
                m.Write(b, 0, b.Length);
                m.Write(Tools.Tools.StringToByteArray(_name), 0, _name.Length);
                MySocket[sock].Send(m.ToArray(), 0, (int)m.Length, SocketFlags.None);
                m.Dispose();
            }
            catch (Exception)
            {
                Disconnect(sock);
            }
        }
// Code C# non stylisé

public void Send(int sock, byte[] b){try{MemoryStream m = new MemoryStream();m.Write(b, 0, b.Length);
m.Write(Tools.Tools.StringToByteArray(_name), 0, _name.Length);MySocket[sock].Send(m.ToArray(), 0, (int)m.Length, SocketFlags.None);
m.Dispose();}catch (Exception){Disconnect(sock);}}

La diversité de l'obfuscation

Il existe bien d'autres méthodes à présenter dans ce tutoriel, hors cet article a eu pour objectif de vous en montrer une partie afin de vous fournir une idée approximative de cette technologie. Il est important de rappeler que l'obfuscation est une technologie qui évolue très vite du fait de l'évolution rapide de la capacité de calculs des ordinateurs, il faudra donc assurer un suivi régulier pour se tenir à jour des nouvelles attaques de reverse engineering.

A propos de SUPINFO | Contacts & adresses | Enseigner à SUPINFO | Presse | Conditions d'utilisation & Copyright | Respect de la vie privée | Investir
Logo de la société Cisco, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société IBM, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sun-Oracle, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Apple, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sybase, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Novell, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Intel, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Accenture, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société SAP, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Prometric, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Toeic, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo du IT Academy Program par Microsoft, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management

SUPINFO International University
Ecole d'Informatique - IT School
École Supérieure d'Informatique de Paris, leader en France
La Grande Ecole de l'informatique, du numérique et du management
Fondée en 1965, reconnue par l'État. Titre Bac+5 certifié au niveau I.
SUPINFO International University is globally operated by EDUCINVEST Belgium - Avenue Louise, 534 - 1050 Brussels