Forums d'entraide informatique - Astuces - Conseils
Des experts à votre écoute pour tous vos dysfonctionnements
Vous n'êtes pas identifié.
Pages: 1
- Accueil forums
- » Programmation
- » Analyse différentielle Application à la recherche de vulnérabilité
#1 31-08-2008 22:49:10
- Admin
- Administrateur
- Date d'inscription: 30-07-2008
- Messages: 683
Analyse différentielle Application à la recherche de vulnérabilité
L'analyse des différences et des similarités de binaires est une problématique complexe en pleine expansion qui trouve de nombreux usages. Les applicatifs uniquement disponibles sous forme compilée tiennent une place considérable dans l'informatique actuelle : que ce soit le système d'exploitation le plus répandu au monde, les systèmes de messagerie ou de gestion de base de données les plus robustes ou simplement les vers et virus variés en perpétuelle propagation.
Dans ce contexte, des interrogations émergent quant aux modifications apportées par un éditeur ou constructeur à son produit lors de mises à jour (correctifs de sécurité comme nouvelles versions), niais aussi au niveau de l'utilisation de certaines portions de code (violation de la propriété intellectuelle, degré de ressemblance). Autant une réponse immédiate peut être fournie lorsque les sources des applicatifs sont disponibles, autant c'est délicat dans le cas contraire. Un recoupement octet à octet est inexploitable, une comparaison textuelle des lignes désassemblées ne prend pas en compte la logique du programme, bref, il fallait introduire un niveau d'abstraction supplémentaire.
La solution réside dans la représentation d'un binaire sous forme de graphes, facilitant à la fois l'analyse et l'interprétation des résultats : le problème de comparaison de binaires s'apparente alors à un sous-ensemble très restreint de celui de l'isomorphisme de graphes. Nous abordons dans cet article les méthodes actuelles d'analyse différentielle de binaires et les principes sur lesquels elles se fondent. Nous montrons ensuite l'application possible de ces procédés à la recherche de vulnérabilités, point des plus passionnants.
Pourquoi ne pas appliquer une comparaison textuelle ?
Comparer des variantes différentes du même objet exécutable (ou juste deux objets exécutables arbitraires partageant une certaine quantité de similarités) conduit à opposer des représentations peut-être complètement dissemblables au niveau assembleur. Il existe cependant un certain nombre de changements communs qui se produisent entre deux versions d'un objet exécutable
MM L'allocation de registres différents
En fonction des paramètres d'optimisation du compilateur et des changements du code, des registres différents seront assignés à des instructions identiques ;
La réorganisation d'instructions
Compte tenu du modelage effectué par le compilateur pour le pipelining du CPU, certaines instructions individuelles seront réorganisées ;
/1111 L'inversion des branchements
Dans plusieurs cas, le compilateur essaie d'optimiser l'alignement
des blocs basiques (que l'on définira comme étant une suite d'instructions consécutives exécutées linéairement, prenant généralement fin avec une instruction de branchement ou un retour d'appel) par une inversion de la condition d'un branchement et par un échange des deux blocs basiques auxquels ce branchement peut mener.
Évidement un nombre important de changements majeurs peut se produire. L'observation principale sur laquelle se fondent certaines méthodes présentées ici, est que le graphe d'appels (défini par la suite) d'un objet exécutable reste en majeure partie identique, même lorsqu'il est compilé avec un compilateur différent et pour une architecture différente. Au lieu de se cantonner aux instructions assembleur obtenues par désassemblage, une approche est de se concentrer sur les propriétés structurelles de l'objet exécutable, surtout sur l'abstraction essentielle des fonctions, des blocs basiques et aussi sur leurs relations.
ueiweo„.,. neetr:',0
Représentation des binaires sous forme de graphes
Généralement, on peut considérer un applicatif comme un graphe de graphes. Tout d'abord, un exécutable peut être vu comme un grand graphe dont les sommets sont les fonctions du logiciel. Si une fonction du binaire 'foo• fait un appel à une fonction 'bar', un arc du sommet 'foo' rejoindra le sommet 'bar' dans ce graphe. Nous appelons ce graphe « le graphe d'appels » (aussi appelé callgraph par la suite). Nous pouvons ensuite aussi envisager chaque fonction du logiciel comme un graphe — que nous appellerons le fiowchart du code de la fonction. Dans le flowchart, les sommets sont les blocs basiques, et les arcs sont les relations entre les blocs basiques, induites par les instructions de branchement, conditionnel ou non.
L'idée d'une comparaison fondée sur les graphes d'un logiciel vient dune observation simple, selon laquelle presque toutes les modifications appliquées au logiciel produisent des changements au niveau du callgraph ou du flowchart, parmi lesquels figurent :
MI L'ajout d'un contrôle de gamme
L'ajout d'un contrôle de gamme implique sur presque toutes les plateformes une comparaison supplémentaire, ainsi qu'une instruction de branchement en plus. Ces changements modifient le nombre de sommets et le nombre d'arcs dans le flowchart d'une fonction ;
MM Le remplacement d'un appel par un autre
Changer un appel à une fonction dangereuse (comme strcpyO) dans une fonction 'foo' en un appel à une fonction différente (comme strncpy 0) produit un changement dans le callgraph : un arc de 'foo' à 'strcpy' disparaît, et en même temps un arc de 'foo' à 'strncpy' apparaît.
Parallèlement, les changements d'optimisation du compilateur n'altèrent pas la structure essentielle du programme (avec quelques exceptions, voir ci-dessous) : remplacer des instructions par d'autres, inverser des branchements et réorganiser des instructions sont des opérations qui laissent les graphes du binaire invariants.
Il est évident qu'une comparaison fondée sur la structure du programme a bon nombre d'avantages : si on pouvait comparer les graphes des deux binaires, on pourrait voir les changements logiques du programme en s'affranchissant des changements introduits par le compilateur.
Le désavantage de cette approche est qu'on est aveugle aux petites transformations comme l'ajout d'une instruction pour initialiser une variable locale, laquelle peut impacter la sécurité de l'applicatif.
Isomorphisme de graphes
Décider si deux graphes donnés sont isomorphes (semblables) est, dans le cas général, un problème non résolu. On ne sait si le problème est NP difficile, mais personne n'a encore trouvé
un algorithme de complexité polynomiale pour le solutionner. Heureusement, nous n'avons pas besoin de résoudre le problème général de l'isomorphisme de graphes : les logiciels consistent en des graphes orientés avec une structure claire et prédictible.
En plus, nous savons que les graphes ont changé et nous voulons simplement trouver l'emplacement exact où les graphes ne sont plus identiques, ce qui restreint le champ d'étude de façon conséquente.
Précisément, nous voulons construire un isomorphisme optimal de sous-ensembles de ces deux graphes. Cela signifie que nous voulons associer toutes les fonctions et blocs basiques qui n'ont pas changé.
Points fixes
L'algorithme que nous utilisons est un algorithme itératif pour construire une approximation d'isomorphisme nous commençons avec les callgraphs. Dans ce graphe, il y a quelques sommets que nous pouvons aisément associer :
MI Les deux sommets d'entrée du logiciel ;
MI Les sommets des fonctions importées (comme GetWindow, etc.).
Nous allons appeler une paire de sommets que nous avons associés fixed point, ou point fixe de l'isomorphisme. En pratique, le nombre de sommets que nous pouvons initialement associer n'est pas suffisamment grand. Il nous faut d'autres méthodes pour associer plus de sommets.
Signatures structurelles des fonctions
Dans le callgraph, nous avons l'avantage d'avoir des informations additionnelles sur les sommets : la taille et la structure de la fonction qui est représentée par le sommet dans ce graphe.
Pour l'utiliser, on assigne une signature structurelle à toutes les fonctions qui consiste en trois nombres entiers : le nombre de blocs basiques dans la fonction, le nombre d'arcs vers le graphe de la fonction, et le nombre de fonctions qui sont
Ces signatures structurelles ne sont clairement pas uniques pour toutes les fonctions — il n'existe pas beaucoup de possibilités différentes pour organiser une fonction avec seulement 4 ou 5 blocs basiques.
Néanmoins, on gagne pas mal de points fixes : pour les fonctions de taille importante, la probabilité d'avoir plus d'une fonction dans chaque binaire avec la même signature est beaucoup moins grande.
On peut associer de cette façon entre 20% et 30% des fonctions s'il n'existe qu'une fonction dans chacun des binaires avec une signature unique, nous pouvons les associer. Dans l'exemple suivant, les sommets en vert ont été associés parce que leur signature était unique dans chaque binaire.. (fig. 3)
Algorithme de propagation
N'avoir que 20% ou 30% d'associations ne suffit pas pour une analyse en profondeur : nous avons besoin d'un algorithme pour résoudre le problème de plusieurs fonctions avec une même signature. Nous avons cependant déjà un isomorphisme initial qui peut nous aider : en connaissant quelques points fixes, nous pouvons appliquer ces résultats, issus d'une analyse « globale » du logiciel, à une analyse « locale ».
Nous commençons avec un point fixe : c'est essentiellement juste une paire de fonctions (fi, fi') qui sont déjà associées. Dans notre exemple, nous commençons avec le point fixe des deux fonctions possédant la signature (10, 23, 6). Maintenant, nous ne regardons plus le binaire dans sa globalité, mais nous faisons une analyse locale : si on néglige tous les sommets qui ne sont pas voisins de nos fonctions associées, les graphes qu'il faut analyser sont beaucoup moins grands, et logiquement l'ambiguïté sera moindre. En se restreignant au graphe réduit, nous sommes capables d'associer deux sommets en plus dans le graphe global. A chaque itération, nous pouvons associer de plus en plus des sommets, jusqu'à finaliser l'analyse. (fig 4 & 5)
Distance Euclidienne
Nous désirons aussi être capable d'associer deux fonctions, même si elles ont changé, c'est-à-dire si leur signature n'est plus exactement identique. Dans l'exemple, nous pouvons voir que la fonction avec la signature (8, 12, 2) va être associée avec la fonction dont la signature est (10, 14, 2) : lorsque l'on regarde la fonction (15, 5, 4) et ses voisines, il est clair qu'après avoir associé les fonctions dont les signatures sont identiques, il n'y a plus d'autre choix !
Parfois la situation est beaucoup plus obscure, par exemple si deux sous-fonctions d'une fonction sont modifiées dans le même patch. Que devon-nous faire dans ce cas-là ? Il nous faut une mesure pour décider pour une fonction A donnée dans un exécutable laquelle, de BI et B2 dans un autre, lui est le plus similaire. La solution est assez facile. Parce que les signatures peuvent être envisagées comme des points dans un espace de vecteurs, nous pouvons calculer leur distance euclidienne : si BI est plus proche de A que B2, nous la préférerons.
Signatures structurelles des blocs basiques
Quand on est arrivé à construire l'isomorphisme entre les fonctions d'un logiciel, on a encore besoin de construire un isomorphisme entre les blocs basiques de chaque fonction. Le problème est similaire au problème de la construction de l'isomorphisme entre les callgraphs, mais malheureusement nous n'avons plus de signature structurelle évidente.
Puisque nous sommes paresseux (ou élégants selon le point de vue), nous voulons réutiliser notre algorithme de propagation. Comment pouvons-nous associer un triplet de nombres entiers à chaque bloc basique ?
En général, pour une fonction, nous avons un sommet d'entrée unique, et chaque sommet a soit un soit deux fils directs. A cause de cela, nous allons choisir une signature qui ne dépend plus de la position des sommets dans le graphe.
On associe à chaque bloc basique dans une fonction le triplet de nombres « nombre minimal d'arcs à suivre pour arriver à l'entrée de la fonction », « nombre d'arcs à suivre pour arriver à la fin de la fonction » et « nombre de sous-fonctions appelées ». Avec cette signature, nous pouvons plus ou moins réutiliser le même algorithme de propagation que précédemment.
Un inconvénient de notre signature est qu'elle est moins stable : l'insertion de quelques blocs basiques dans la fonction peut changer la signature d'autres blocs. Pour stabiliser la signature, nous utilisons d'autres informations pour la génération de points fixes :
Ma Références communes aux chaînes de caractères ;
Milà Références communes à des sous-fonctions ;
MM Même SPP (voir ci-dessous)
Small primes product (SPP)
Le changement que le compilateur introduit le plus souvent est le réarrangement des instructions. Pour être capable d'associer deux blocs basiques qui sont identiques mais ont leurs instructions réarrangées. nous avons besoin d'une signature concise, qui peut identifier une séquence d'instructions, tout en étant invariante aux permutations d'instructions.
Quand la théorie des codes (comme la construction du code ISBN) essaie de construire un code qui détecte les changements, comme la permutation d'éléments, nous voulons construire un code simple qui détecte des changements de la séquence, mais pas les permutations ![]()
La solution est une fois de plus relativement immédiate : on assigne un petit nombre premier unique à chaque instruction assembleur. Pour calculer la signature d'un bloc basique, on calcule le produit
de toutes les instructions dans ce bloc basique. Parce que la multiplication est commutative (ab ba) et la factorisation en nombres premiers unique, cette signature représente la séquence des instructions dans n'importe dans quel ordre.
On peut faire quelques autres améliorations sur ce code si on désire créer des affectations de nombres uniques par CPU. Si nous assignons le même nombre aux instructions 'jnz' et 'jz', nous pouvons alors ignorer cette inversion de branchements; si nous assignons ''_' à l'instruction 'nop', nous pouvons ignorer l'insertion de nops, etc.
En pratique, l'utilisation de bibliothèques de grands nombres entiers est impossible. En utilisant l'arithmétique de la CPU (cela signifie l'arithmétique modulo 21'64) nous n'avons plus la preuve que la factorisation est unique, mais nous gagnons beaucoup en vitesse (et la probabilité de trouver deux séquences de code valides avec la même signature n'est pas grande).
D'un point de vue algorithmique, il y a beaucoup plus de petites astuces que l'on peut utiliser pour obtenir un isomorphisme plus important, mais il n'y a pas assez d'espace ici pour les détailler. Pour un traitement plus profond du sujet, référez-vous à [BDDIMVA], [BDSSTIC].
Un mot sur les signatures conjoncturelles
Contrairement aux signatures structurelles, qui utilisent essentiellement les caractéristiques d'un graphe, les signatures conjoncturelles dépendent fortement de leur contenu, dans notre cas, le code désassemblé des fonctions des binaires étudiés.
Bien évidemment, calculer une signature (51-1A-I, MD5 ou même CRC32) de la séquence d'octets derrière un bloc basique ne vous mènera pas loin : le code regorge de références relatives ou absolues à des emplacements en mémoire qui seront bien évidemment déplacés suite à recompilation du source modifié. Cette méthode ne résistera pas davantage aux réarrangements des registres, aux inversions des instructions de branchement.
L'alternative réside dans un traitement plus réfléchi du code assembleur. Il sera avisé de prendre en considération les mnémoniques assembleur, la taille des opérandes de ces derniers (8, 16, 32 ou 64 bits), leur type (registre, valeur immédiate, phrase, etc.) tout en vous affranchissant de détails plus précis, tels les valeurs exactes, le nom du registre, l'adresse des sauts et appels.
Il ne vous restera plus qu'à calculer votre signature sur la séquence d'octets obtenus, comme le montre l'extrait d'un plugin IDA cité dans [ODAYS]. Cependant, ces seuls éléments, même s'ils sont passables, seront insuffisants à l'encontre de binaires plus complexes.
Parmi ce qu'il est nécessaire de prendre en compte lors du calcul de signatures dites « conjoncturelles », sur un bloc basique ou une fonction, figurent :
11111 L'inversion de deux instructions, l'une prenant la place de l'autre et vice versa. Le procédé de calcul de signature pourra donc être indépendant de l'ordre des instructions.
Le remplacement de certaines instructions par des instructions équivalentes. Comme tout langage de programmation, l'assembleur permet d'effectuer des
actions comparables sous bien des formes différentes, par exemple :
X0r eax,
mov eax,
push g & pop eax
auront tous pour effet de mettre le registre eax à 0. Les compilateurs savent jouer de ces subtilités pour optimiser l'exécution du code qu'ils génèrent, en vitesse d'exécution ou en taille de code machine généré.
Les modifications des branchements. Certains blocs basiques peuvent être scindés en plusieurs morceaux par des sauts inconditionnels situation qui ne change en rien la logique du bloc en question, mais est susceptible d'influer sur la signature. Bien souvent, les sauts conditionnels sont aussi réorganisés, la condition inversée. Attention ! La modification d'un saut signé en non signé peut cacher une faille.
Les corrections de constantes. Souvent mises de côté lors du calcul de la signature, les constantes peuvent cependant cacher un correctif de sécurité : taille d'un buffer passée à une fonction d'allocation mémoire, taille de l'espace réservé sur la pile, comparaison, sont autant de facteurs potentiels de déclenchement de débordement.
Le figures ci-dessous montrent une différence d'une seule instruction dans un bloc basique de deux binaires découverte grâce à une signature conjoncturelle reposant sur une CRC32. Cette modification implique de potentielles répercussions sur la sécurité de l'application.
Au final, la signature conjoncturelle peut donner de très bons résultats tout en fonctionnant à un niveau de granularité élevé, ce qui permet de détecter des modifications au niveau de
l'instruction assembleur et non du graphe. Sa dépendance au langage assembleur utilisé la rend difficilement portable à un grand nombre d'architectures. Enfin, elle est relativement mal adaptée dans le cas où deux binaires diffèrent grandement.
Applications à la recherche de vulnérabilités
La possibilité de mettre en exergue les différences entre deux binaires est de nos jours un atout majeur pour tout chercheur de vulnérabilités ou tout expert technique désirant qualifier la portée d'un correctif et la gravité des failles qu'il corrige.
Les bulletins sont rarement explicites d'un point de vue technique (avec le vain espoir de complexifier le processus d'exploitation) et déterminer l'impact réel d'une vulnérabilité relève du tour de force, notamment lorsqu'il s'agit d'éclaircir les points suivants : la facilité d'exploitation, sa fiabilité, sa dépendance à la régionalisation du système, à la version du système.
Si bien souvent le correctif apporte un nombre limité de changements aux binaires analysés, ce n'est pas le cas des service packs, qui non seulement sont des cumuls de mises à jour de sécurité mais ajoutent aussi de nouvelles fonctionnalités et de nombreuses améliorations. Un bon outil permettra cependant d'y détecter les rustines réparant des trous de sécurité.
À partir d'un correctif
Nous allons vous conter une histoire amusante à propos d'un patch particulier : MSO4-001. En 2003, l'organisation NISCC utilisait un fuzzer ASN.1 et H.323 pour faire l'analyse de certaines implémentations du protocole H.323. Ils trouvèrent pas mal de bogues différents dans des implémentations variées, de Cisco à Microsoft.
Microsoft en particulier était affecté dans le serveur ISA 2000, un produit qui peut être décrit comme la solution de pare-feu de Microsoft. Après avoir reçu les deux binaires du produit avant et après patch, nous les avons chargés dans le désassembleur IDA qui, au bout de quelques minutes, a produit le code désassemblé des applicatifs.
Nous avons alors pu utiliser les algorithmes décrits dans cet article pour construire un isomorphisme entre les deux binaires. Notre algorithme nous donne 6 fonctions associées avec des fonctions de signature différente — cela signifie qu'il nous signale 6 fonctions modifiées.
Nous regardons la première fonction changée, et voyons que Microsoft a introduit un contrôle de gamme dans le bloc basique à l'adresse 0x4ledle. La fonction en question prenait simplement une valeur N non signée de 32 bits, retournée par un appel à la fonction ASN1PerDecU32Va1() et accessoirement contrôlable par un attaquant.
Elle copiait ensuite 2 N valeurs non signées de 16 bits dans un buffer de taille fixe, celles-ci provenant d'appels répétés à ASNlPerDecUlfValU et étant également contrôlées par l'attaquant. Ce dernier est alors en mesure de choisir une valeur trop grande de N et provoquer un débordement puis de l'exécution de code arbitraire grâce à des données qu'il
Ce patch apporta aussi d'autres changements moins didactiques : il introduisit quelques contrôles de gamme devant tous les appels à une fonction du système d'exploitation, ASN1PERDecZeroTabl eCr arStringNalloc.
Cette information était d'une grande valeur, car indiquait l'absence de contrôles sur quelques paramètres de cette fonction. Cela se révéla bien utile pour trouver des failles 0-day dans d'autres applications l'utilisant, comme NetMeeting ! L'analyse a été menée avec [BDIFF] et a pris moins de deux heures.
Indépendance de l'architecture
En général, les algorithmes que nous avons abordés ici sont plus ou moins indépendants de l'architecture ou système d'exploitation — on peut sans modifications les utiliser sur des systèmes x86 embarqués (si on peut avoir un désassemblage propre dans IDA) ou même des systèmes non-x86.
Par exemple, il est trivial de differ deux variantes du Cisco PIX ou d'autres systèmes embarqués. Le code suivant vient d'un diff de Cisco PIX entre les versions 6.34 et 6.33. Ici, les développeurs ont juste introduit une comparaison pour ne pas avoir de division par zéro.
Mais au total, il y a plus de 200 fonctions corrigées dans la mise à jour, et il bien possible qu'on puisse y trouver des changements plus enrichissants. (fig. 9)
Parce que nous n'avons pas restreint les algorithmes, qui sont indépendants de l'assembleur, nous avons aussi la capacité d'examiner les différences sur des plateformes non-x86.
La seule chose que nous devrons adapter pour chaque CPU est le code de génération des graphes. Voici un exemple de deux
Entre versions majeures
Il est de notoriété publique que bien des éditeurs et constructeurs profitent des nouvelles versions de leurs produits pour y corriger en toute discrétion quelques vulnérabilités. En cherchant à déterminer les modifications apportées dans celles-ci, nous pouvons mettre au jour des altérations corrigeant des failles de sécurité.
Nous profitons alors du travail de sécurisation mené par l'éditeur, non divulgué, pour découvrir de nouveaux vecteurs de compromission possibles.
Si pour de simples correctifs le nombre de changements occasionnés est limité, il est généralement plus important dans la situation qui nous préoccupe maintenant.
Certains éléments bouleverseront fondamentalement les binaires, mais ne nous intéresseront que peu nouvelles fonctionnalités, changement de compilateur ou d'options de compilation, correction de bogues sans rapport avec la sécurité, nouvelles protections génériques. L'analyse différentielle n'en sera que plus complexe.
Windows XP SP1 vs Windows XP SP2
Microsoft ne fait pas exception et l'effort de sécurisation de Windows XP avec son SP2 nous fournira un terrain d'exploration convenable.
Outre les fonctionnalités de sécurisation variées (protection de la pile, du tas, centre de sécurité, fonctionnalités distantes restreintes par défaut), le Service Pack 2 de XP a corrigé silencieusement bon nombre de failles.
Bureau à distance
Implémenté sous forme de driver système dans Windows XP (rdpwd.sys entre autres), le bureau à distance a été lourdement modifié avec la publication du Service Pack 2 de Windows XP. Plusieurs de ces modifications visaient à corriger, silencieusement, des problèmes de sécurité.
Lors de l'édition du correctif Remote Desktop Protocof [MS05- 041] qui concernait un tout autre problème, Microsoft en a profité pour rétro-appliquer quelques-uns des changements apportés dans le SP2. L'analyse différentielle du binaire concerné a pu révéler à certaines personnes ces failles bien avant qu'elles ne fassent l'objet d'une mise à jour publique.
Dans les graphes ci-contre, les noeuds ayant un fond blanc sont inchangés (dans un sens relativement large) d'une version à l'autre, les noeuds gris sont de nouveaux noeuds, et ceux de couleur correspondent à des noeuds modifiés à mettre en correspondance avec le noeud d'une couleur similaire dans l'autre graphe.
Vous noterez les quelques modifications mineures induites par le compilateur : modification du cadre de pile, réarrangement
•
de l'organisation des blocs de code, utilisation différente des registres. Une modification majeure réside cependant dans la vérification effectuée sur la taille passée en paramètre à la fonction COM_ria 1 1 o c ). Cette comparaison permet de mettre rapidement en évidence une vulnérabilité de type débordement d'entier.
Le contenu du registre eax passé à la fonction est issu de la requête et donc contrôlé par le client, qui peut provoquer l'allocation de la quantité de mémoire qu'il souhaite et mener à une condition de déni de service sur le serveur.
Si Oxfff-Ffff9 <= eax <= Oxffffffff, alors 0 <= eax + 7 <= 6 et la taille de la mémoire allouée sera insuffisante pour la quantité (eax) de données copiée dans la foulée, provoquant un débordement type heap overPow en mode noyau (rirg0).
Le résultat à attendre : un écran bleu (l'exécution de code est très improbable). Un patch de quelques lignes du logiciel rdesktop [RDESKTOP] permettait de déclencher le débordement à distance avant authentification du client, problème résolu avec le correctif cité précédemment.
Conclusion
Malgré ce que peuvent penser éditeurs et constructeurs, les correctifs binaires sont souvent aussi explicites que des diff de code source, pourvu que l'on ait les bons outils, et des compétences suffisantes en assembleur. Il en résulte que l'implémentation d'un exploit, dans les milieux autorisés, est une question d'heures : nous pouvons vérifier cela régulièrement grâce à des entreprises telles que Irnmunity, Inc. [PARTNERS]. Comprenez bien que la mise à dIsposition de correctifs au public rapidement est loin de refléter la réalité d'une situation bien sombre : leur déploiement dans un système d'information d'envergure sera toujours trop tardive. La qualité des exploits publics est bien en deçà de ce qu'il est possible de faire : les résultats des analyses différentielles restent souvent privés, de même que les outils d'exploitation qui en résultent. Trouver des nouvelles failles, dites « Odays », dans d'autres applications grâce à des bogues similaires à ceux corrigés est commun
Cordialement
L'équipe Parisdepannage.fr
Hors ligne
Pages: 1
- Accueil forums
- » Programmation
- » Analyse différentielle Application à la recherche de vulnérabilité
2008 Parisdepannage |Plan du site|Forums |Blog|Lexique ![]()