Décompilation d'application flash

Le 28-07-2010

Les décompilateurs sont une préocuppation majeure des créateurs d'applications flash. En quelques minutes, il est possible de les explorer et d'en extraire le contenu. Votre propriété intellectuelle peut être volée en un clic ! C'est un grave problème pour les contenus de type image/audio/video, mais aussi pour la sécurité de l'ensemble de l'application.

Dans la suite de ce post, nous allons voir différents moyens de protection et d'attaque d'une application flash.

Explication de l'application flash

L'application créée pour l'occasion est rudimentaire : elle affiche un compte à rebours de 60 secondes, une fonctionnalité totalement révolutionnaire ! Elle a été conçue pour ne se lancer que pendant l'année 2009. Voilà la protection qu'il nous faudra contourner pour pouvoir utiliser cette merveilleuse application à loisir.

        public function init() : void
        {
            if (this.date.fullYear != 2009)
            {
                this.statusTextField.text = "Please buy me !";
                return;
            }
            this.myTimer.start();
            this.statusTextField.text = "You have " + this.delay * this.repeat / 1000 + " seconds to wait.";
            this.myTimer.addEventListener(TimerEvent.TIMER, this.timerHandler);
            this.myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, this.completeHandler);
            return;
        }// end function

Dès lors deux options s'offrent à nous : changer la date de notre machine ou supprimer la vérification de l'application. Dans un pur intérêt pédagogique, nous allons envisager la deuxième solution.

Le format de fichier

Selon le fichier de spécifications du format de fichier SWF version 10 (http://www.adobe.com/devnet/swf/pdf/swf_file_format_spec_v10.pdf), un fichier swf est composé d'un entête contenant des informations générales et plusieurs blocs de données identifiés par des tags.

Format de fichier SWF

L'entête est défini comme ci dessous :

Nom du champ Type Commentaire
Signature Entier non signé sur 8 bits C indique que le fichier est compressé
F indique que le fichier est décompressé (SWF 6 et ultérieur)
Signature Entier non signé sur 8 bits Toujours le caractère 'W'
Signature Entier non signé sur 8 bits Toujours le caractère 'S'
Version Entier non signé sur 8 bits Version flash supportée
FileLenght Entier non signé sur 32 bits Taille du fichier
FrameSize RECT (voir fichier de spécification) Dimensions des frames
FrameRate Entier non signé sur 16 bits Vitesse des frames
FrameCount Entier non signé sur 16 bits Nombre de frame

Le champ signature est soit CWS (0x43 0x57 0x53) soit FWS (0x46 0x57 0x53). CWS indique que les données hormis l'entête sont compressées grâce au standard ZLIB. Cette compression permet un téléchargement des applications flash plus rapide.

Ensuite viennent les blocs de données qui contiennent les images, les sons mais aussi les instructions qui seront exécutées. Ces instructions appelées bytecode sont générées à la compilation à partir du code source. Le bytecode sera ensuite interprété par une machine virtuelle nommée ActionScript Virtual Machine 2 dont voici les spécifications (http://www.adobe.com/devnet/actionscript/articles/avm2overview.pdf).

Décompilation

Grâce à un des nombreux outils de décompilation tel que Flash Decompiler Trillix (http://www.flash-decompiler.com), Sothink Swf Decompiler (http://www.sothink.com/product/flashdecompiler/index.htm), etc... il est possible d'accéder aux codes sources de l'application originelle. Rien de magique ! Comme vu précédemment les codes sources ne sont pas embarqués dans l'application flash, le décompileur va les reconstituer grâce au bytecode !

Données binaires : ... 0x24 0x02 0x24 0x03 0xa0 0x73 0xd5 ...
ByteCode 0x24 0x02 0x24 0x03 0x0a 0x73 0xd5
ByteCode (human readable) pushbyte 2 pushbyte 3 add convert_i setlocal1
Code source __loc1__ = (int) 2 + 3;

Le décompilateur reconstitue l'ensemble du code source de la même manière. Nemo440 (http://www.docsultant.com/nemo440/) est un très bon outil pour visualiser le bytecode d'une application flash.

Nemo440 un bon outil de décompilation SWF

Obfuscation

L'obfuscation est un processus permettant de complexifier la décompilation d'une application. Elle repose sur plusieurs techniques dont les plus célèbres sont :

  • la génération de code poubelle; un code superflu est ajouté pour rendre la lisibilité difficile
  • le cryptage des chaînes de caractère; les chaînes de caractères nécessitent un processus de décryptage pour retrouver leur forme originelle
  • le changement de nom des variables et nom de fonction; Exemple : null.this(ddd-a(); au lieu de voiture.accelere();

De nombreux logiciels d'obfuscation sont disponibles offrant des niveaux de protection très variables. Nous avons utilisé SecureSwf de KindiSoft (http://www.kindisoft.com/) pour protéger notre application. Le code source obtenu après une nouvelle décompilation est plutôt surprenant. On peine à croire qu'une chose pareille puisse s'exécuter.

        public function init() : void
        {
            var _loc_1:Boolean = true;
            ;
            var _loc_2:* = ((null & false) + 1 in null) % NaN;
            do
            {

                return;
                if (false)
                {

                    this.default.addEventListener(TimerEvent.TIMER_COMPLETE, this.completeHandler);
                }while (true)

                this.default.addEventListener(TimerEvent.TIMER, this.timerHandler);
                if (!(_loc_2 && this))
                {
                    ;
                    do
                    {

                        this._20else.text = "You have " + this.break * this.repeat / 1000 + " seconds to wait.";
                    }
                    if (_loc_1)
                    {
                        do
                        {

                            this.default.start();
                        }while (true)

                        return;
                    }while (true)
                    break;
                    if ((!(-(_loc_3 in this))).case20.fullYear == 2009) goto 135;
                    this._20else.text = "Please buy me !";
                }
                ;
            }
            return;
        }// end function

Effectivement le code source obtenu est très endommagé. On voit nettement le résultat des processus de renommage de variables "this._else20.text" et d'ajout de code poubelle "do { return;". Un tel code est impossible à recompiler notamment à cause de l'emploi de mots clefs réservés dans le nommage des variables (Ex: this.break).

Attaque

Le code source obtenu n'est pas sans utilité. Il nous permet avant tout de localiser l'endroit du test de protection : la fonction init(). Une fois cette information connue, nous pouvons lancer nemo440 pour afficher le bytecode de la fonction ciblée.

Extrait de bytecode de la protection

On identifie rapidement qu'une protection sur la valeur de l'année en cours a lieu lors de l'initialisation de cette application grâce aux bytecodes :

164     getproperty       private::case
166     getproperty       fullYear
168     pushshort         2009
171     ifeq              L14

175     getlocal0
176     getproperty        else
178     pushstring        "Please buy me !"
181     setproperty       text

Le test d'égalité est effectué grâce à l'opérateur ifeq (0x13) entre l'entier court "2009" et fullYear qui est un attribut de la classe Date. On pourrait utiliser l'application si l'opérateur ifeq était remplacé par l'opérateur ifne (0x14), si l'entier court était "2010", etc...

Rien de plus simple ! Il nous suffit de rechercher la suite hexadécimale "ifeq getlocal0 getproperty" (0x13 0xd0 0x66) avec un bon éditeur hexadécimal après avoir décompresser l'application (SWF Compressor Decompressor sur http://www.dcomsoft.com/). Une fois cette séquence trouvée, nous changeons la valeur 0x13 par 0x14 et nous recompressons le tout.

L'application est maintenant utilisable pour l'éternité !

Ce post est une démonstration des difficultés à protéger une application flash. L'obfuscation du code source ne suffit pas à protéger votre application et encore moins votre système entier.

On vous rappelle ?

Indiquez votre numéro de téléphone

ainsi que la tranche horaire où vous êtes disponible. Nous vous appellerons dans les plus brefs délais

 

Actualités

  • 30-07-2010 Sécurité de Typo3 & entropie de rand()
  • 28-07-2010 Décompilation d'application flash
  • 06-04-2010 Les 9 objections à la sécurité des sites internet - Développement externalisé