Obfuscation de code.


C’est un ensemble de techniques destinées à rendre un code source moins lisible, comme par exemple les scripts, mais aussi un programme en C ou le code source d’une page HTML :

Déjà un programme sans commentaires est plus difficile à comprendre, on peut aussi supprimer l’indentation, ce qui enlève de la lisibilité et estompe la structure du programme..

Onenlève les saut de lignes dans une page HTML , dans un javascript par exemple et on se retouve avec un « tas » presque inexploitable rapidement, pour détecter   une éventuelle vacherie de script dans ce gros tas.
Un exemple : le code source de la page de Google

Mais aussi remplacer le nom des variables symboliques qui laisse préfigurer la fonction de chacune, par des suites de caractères aléatoires, plus difficiles aussi à mémoriser.

Mais c’est également utilisé pour les binaires exécutables, non Open Source,  pour que l’on ne puisse pas deviner leurs secrets de fonctionnement avec du reverse engineering, en utilisant un désassembleur. ( c’est surtout vis à vis de la concurence qu’on peut avoir recours à l’obfuscation )

Le désassembleur va éplucher un par un les octets du binaire et lorsqu ‘un ou plusieurs octets correspondent à une instruction, il les remplace par le code mnémonique de l’instruction, plus aisé à comprendre pour l’humain.

Bien sur il ne mettra pas le nom symbolique des variables, utilisés par le programmeur et codé en binaire par l’assembleur, mais il mettra l’adresse.

Par contre au départ il ne sait pas s’il s’agit de données ou d’instructions.. ca amène des confusions et c’est à l’utilisateur du désassembleur d’interpréter le résultat…

Lorsque ça ne correspond pas il se contente d’afficher la valeur de l’octet et ne la décode pas.

Les instructions selon leur type peuvent occuper plus ou moins d’octets, c’est l’assembleur qui va organiser ça. Le désassembleur va suivre et tomber pile poil sur l’instruction suivante : deux ou trois ( ou plus ) octets plus loin.

Sur un programme normal , il va réussir à se caler et on va arriver à voir une suite logique d’instructions : c’est le programme.

Lorsqu ‘il sort un truc incompréhensible on lui demande d’attaquer le décodage un ou deux octets plus loin, jusqu ‘à ce qu ‘on ait qq chose de cohérent.

L’obfuscation de code consite à multiplier ces confusions entre données et instructions et à noyer le code parmi du faux code qui ne sert à rien ou des données aléatoires.

Si dans une zone du binaire on ajoute de fausses instructions, que le programme n’éxécutera pas exemple : une instruction codée sur deux octets suivi d’un troisième octet : n’importe quoi. place là volontairement, le désassembleur va se paumer dans les décalages et prendre ce n’importe quoi comme le début de l’instruction suivante..et le début de l’instruction suivante comme une adresse de variable, et ça devient impossible d ‘analyser le code sorti par le désassembleur..

Lorsque le code du programme est noyé dans du faux code ou des données aléatoires, on voit tout de même des instructions du type : JMP $ +7, on sait que que les six octets derrière peuvent être du faux code si on voit un paquet de JMP dans le programme , mais l’obsfucateur ( un humain ) peut faire plus vache avec des valeurs de saut contenus dans une variable, qui aura été initialisée en cours de programme.. il faudra trouver où …

Comment noyer son programme en assembleur.

En utilsant les étiquettes : telle étiquette = telle adresse mémoire par rapport au début. et on laisse des trous..

ou bien certains assembleurs ont des instructions DZS , ou TAB ( non exécutées par le processeur , mais par l’asembleur lors de la conversion en binaire ), qui réservent des zones libres et on va laisser des trous..

Trous qu’on pourra remplir ensuite dans le binaire livré au client , avec des données aléatoires, à l’aide d’un autre programme.

Si on a noyé une centaine d’instructions assembleur parmi 8 ko de données aléatoires, un désassembleur ne va jamais s’en sortir.

Pire une partie du programme peut être cryptée de façon simple avec des XOR avec une clé rangée dans des octets de donnée.

Lorsqu ‘on lance le programme, les octets suivants sont alors décryptés un par un avant dêtre éxécutés.

C’est la technique employée par les éditeurs de virus pour rendre impossible l’analyse du contenu par un antivirus. et cacher des appels système ou autres…

Mieux : ils arrivent à changer le cryptage à chaque exécution , ainsi le fichier du virus n’a jamais la même signature.

Le programme du virus une fois en mémoire détruit son fichier et en recrée un autre à partir de la mémoire , sous un autre nom aléatoire et avec une autre clé de cryptage. Toute une parie du programme est dédiée à ça.

Cependant il y a une autre façon de décoder un programme binaire obfusqué..

C’est d’utiliser un émulateur de processeur.

On ne trouve pas ça sous le sabot d’un cheval, mais ça existe pour la mise au point d’un programme de microprocesseur et son débogage sur un PC , sans avoir le processeur.

On peut utiliser des points d’arret faire dérouler le programme en pas à pas et utiliser le mode trace..ainsi on va voir où passe le Programme Counter, mises en surbrillance, les adresses de données qu ‘il utilise et voir le contenu des registres…

Même si le binaire exécutable était crypté avant son lancement, on va le voir se décrypter..

On va aussi voir les zones de faux code inutilisées.

L’obfuscation de code perd alors une bonne partie de son efficacité..

Mais ce genre d’outil est plus rare que le désassembleur.

C’est ce qu ‘on trouve dans les outils de debug des processeurs ARM.

Parce qu ‘un vrai p*** de bug vaut bien parfois un programme obfusqué. lorsqu ‘il y a une boucle infinie de programme qui finit par faire sauter le chien de garde, on identifie la boucle ( avec trace ) et ensuite on cherche l’erreur de programmation qui le fait tourner en boucle…. parfois la boucle ne se produit que dans certaines conditions ( selon les valeurs des entrées TOR ) qu ‘on a pas toujours pu tester en réel lors de la mise en service, et on a pas pu déceler le bug qui a échappé aussi à une relecture du code par plusieurs personnes.

Après avoir désactivé le chien de garde en bloquant l’horloge du calculo, on a relevé où se trouvait le pointeur du programme au bout d’une centaine de fois on a délimité deux zones entre lesquelles il se balladait. ( en pas à pas c’était bien trop long ) en cherchant sur le listing on a trouvé l’explication. ( erreur d’index , classique : 1 à 6 au lieu de 0 à 5 ) genre de bug qui plantait le calculo par le chien de garde dès qu ‘on mettait un organe en service, alors que tous les autres fonctionnaient, et on y a passé des mois avant d’employer les grands moyens.

Mais l’obfusquation de code peut servir à autre chose :

Autre chose de plus utile que de vouloir cacher le fonctionnement de son programme et empêcher le reverse engineering :

CACHER un MOT DE PASSE qui doit être en CLAIR

Certains se croient protégés en utilisant une clé à rallonge sur une clé USB pour verrouiller l’utilsation d’une appli

Voir le CWE Mitre hardcoded password

Or la clé est dans le binaire, sous la forme d’une chaine de caractères, visibles parmi des octets binaires avec un hexedit ou un édieur de texte, car rares sont les octets correspondant à un code ASCII et se suivant ainsi à la chaine.

Comme on trouve les messages d’erreur « chaine de caractère  » inclus dans un binaire.

Mais plus proche et plus courant : toutes les connections à la base de données des sites Web :

Exemple ( déjà donné dans l’article cryptage des mots de passe ) :

Voilà ce qui est fait dans la plupart des CMS pour la connection php à la base de données pour voir ce qu il ne faut pas faire et tout le monde sait ou les trouver dans les fichiers de configuration ( car tout le monde peut télécharger le CMS pour l’ étudier )

define(‘DB_SERVER’, ‘localhost’);
define(‘DB_SERVER_USERNAME’, ‘epicier‘);
define(‘DB_SERVER_PASSWORD’, ‘epicier‘);
define(‘DB_DATABASE’, ‘oscommerce‘);

exemple pour un test , à ne pas suivre pour les mdp, mais me s’il est à rallonge, il n’est pas crypté et peut être volé .

<?php
if (!defined(‘DBSECURE’))
{
$sql_host = « localhost »; //Adresse serveur MySQL – MySQL server address
$sql_login = « machin »; //Login
$sql_pass = « truc »; //Mot de passe – Password
$sql_base = « phpboost »; //Nom de la base de donnes – Database name
define(‘PREFIX’ , ‘phpboost_’); //Prfixe des tables – Tables prefix
define(‘DBSECURE’, true);
define(‘PHPBOOST_INSTALLED’, true);

ou dans les requetes.:lol: lol

Là c’est pour PostgreSQL

<?php

$dbh = new PDO(‘mysql:host=localhost;dbname=mydb’, ‘mydbuser’, ‘nDUdfyE29k4rpPXV’);

Pourquoi est ce fait comme ça ?

Réponse de Madame Lapalisse, parce qu ‘on ne peut pas faire autrement ( sur un hébergement mutualisé.)

Une technique d’obfuscation de code, pourrait être efficace pour dissimuler le mot de passe , en cas d’intrusion réussie.

Ca ne devrait jamais arriver , hélas tous les ans il sort une nouvelle technique d’intrusion.. et sur un hébergement mutualisé on ne maîtrise que dalle ( les autres sites ) ; mais voilà on fait comme si..

C’est du niveau : la clé est sous le paillasson, ou dans le pot de fleur.

Ne riez pas les sites de e-commerce ont toutes nos coordonnées, parfois nos coordonnées bancaires et ne sont pas plus protégés.

Une bonne technique , serait de planquer les caractères du mot de passe dans un binaire ( rempli de caractères aléatoires ) de manière dispersée et que le décalage aléatoire ( positif ou négatif ) entre chaque caractère soit intégré dans ce binaire à la suite de chaque caractère..

un peu à la manière utilisée pour retrouver les morceaux des fichiers fragmentés dans les file systems.. Un prog en binaire irait chercher le premier caractère calé qq part , et le décalage pour trouver le caractère suivant.

Pour retrouver les identifiants noyés parmi 4 K caractères ????

Il serait possible de refaire ce fichier de temps en temps avec un utilitaire . tout en gardant le même mdp , celui fixé à la création de la base, avec de nouveaux décalages et de nouveaux caractères aléatoires d’obfuscation..

Peu importe que tout le monde ait le source de l’utilitaire puisqu ‘on utiliserait un élément aléatoire..comme un SALT pour initier les décalages.

On peut encore améliorer, avec un double décalage : cad que le décalage de position d u caractère suivant , ne serait pas immédiatement après, mais N mots plus loin ou plus en avant. N étant ussi aléatoire

Pour éviter le chevauchement : emplacement déjà occupé : commencer par une table avec des zéros, puis à la fin remplir les trous avec des caractères aléatoires..

Je ne sais pas ce que ça vaut, mais je cogite pour améliorer ce qui est fait usuellement dans les CMS, parce que franchement c’est nul au point de vue sécurité..

Pas terrible, il suffirait de mettre le fichier et le script sur son propre serveur, pour trouver le mécanisme de fonctionnement.

Peut être utiliser une clé cachée, une variable d’environnement, bref un truc , sur le serveur qui l’empêche de tourner normalement sur une autre bécane et qu ‘il se plante dans les décalages… Pas le bloquer avec un saut sur place, sinon ce sera vite trouvé, le leurre est préférable

Possible aussi de disséminer le code dans les caractères aléatoires. et d’utiliser des jump.

Deviner l’emplacement et l’ordre des caractères d’un mdp de 24 caractères, noyés dans un binaire de 4 ko qui comprend aussi le programme de décodage, noyés dans des données aléatoires , qui peuvent être interprétées par un désassembleur comme du code, me semble assez pénible…

Publicités
Cet article a été publié dans Authentification. Ajoutez ce permalien à vos favoris.

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s