Wednesday, April 28, 2010

Microsoft et les bugs

Au hasard de mes peregrinations au sein de Windows j'ai ete confronte a une situation qui m'a laisse songeur. N'ayant pas tous les elements en main, si quelqu'un en sait davantage, n'hesitez pas a me corriger.

Dans des extensions FrontPage pour IIS 6, se trouve un morceau de code parsant les images GIF. Jusque la rien d'extraordinaire. Un rapide coup d'oeil aux symboles et l'on trouve les fonctions suivantes:

  • VgdImageGifDecoder::Decode
  • ReadOK
  • VgdImageGifDecoder::LWZReadByte
  • VgdImageGifDecoder::ReadColorMap
  • VgdImageGifDecoder::DoExtension
  • etc.
Un peu de Googling m'apprendra que LWZReadByte() est aussi present dans libgd et SDL_image. Au vu du nom des fonctions, on pourra supposer que Microsoft a pris le code de libgd pour decoder ses GIF. L'analyze du code assembleur revele du moins que les codes ont une source similaire.

Toujours est-il qu'une vulnerabilite a ete decouverte dans LWZReadByte il y a un moment, et a touche aussi bien libgd que SDL_image:
Le code original semble provenir de 1990 par un certain David Koblas, mais je n'ai pas trouve de signalement du bug datant d'avant 2006.

Maintenant, regardons le code present dans Windows 2003 SP0 (sorti le 24 Avril 2003 d'apres Wikipedia):
.text:32E274FF ; private: int __thiscall VgdImageGifDecoder::LWZReadByte(class Vistream *, int, int)
.text:32E274FF ?LWZReadByte@VgdImageGifDecoder@@AAEHPAVVistream@@HH@Z proc near
.text:32E274FF ; CODE XREF: VgdImageGifDecoder::ReadImage(VgdImage *,Vistream *,int,int,uchar (*)[256],int,int)+8Ep
.text:32E274FF ; VgdImageGifDecoder::ReadImage(VgdImage *,Vistream *,int,int,uchar (*)[256],int,int):loc_32E278F2p ...
.text:32E274FF
.text:32E274FF var_104 = byte ptr -104h
.text:32E274FF arg_0 = dword ptr 8
.text:32E274FF arg_4 = dword ptr 0Ch
.text:32E274FF arg_8 = dword ptr 10h
.text:32E274FF
.text:32E274FF push ebp
.text:32E27500 mov ebp, esp
.text:32E27502 sub esp, 104h
.text:32E27508 push ebx
.text:32E27509 xor ebx, ebx
.text:32E2750B cmp [ebp+arg_4], ebx
.text:32E2750E push esi
.text:32E2750F push edi
.text:32E27510 mov esi, ecx
.text:32E27512 jz loc_32E275CE
.text:32E27518 mov ecx, [ebp+arg_8]
.text:32E2751B cmp ecx, 0Ch
.text:32E2751E jg loc_32E2782B

On voit ici que le 3e argument de la fonction est bien compare a MAX_LWZ_BITS (12), et si la taille du code est superieure, on sort. Donc Microsoft etait au courant de ce bug au minimum 3 ans avant qu'il ne soit corrige dans les bibliotheques publiques - et bien entendu la vulnerabilite n'a pas ete reporte par Microsoft. Notez que je ne blame personne, je me contente de constater :) Responsible Disclosure, tout ca.

Encore une fois je ne dispose pas de tous les elements, donc si quelqu'un a quelque chose a ajouter, feel free!

Et pour finir une entree marrante d'un blog de Microsoft qui n'a rien a voir avec le sujet precedent:

EDIT: le fix est aussi present dans FP4 pour Windows 2000, donc les 3ans se transforment d'un coup en beaucoup plus.

2 comments:

Nicolas said...

J'ai rencontré récemment exactement le même problème chez un autre éditeur commercial.

Des libs OpenSource embarquées, où une analyse (du code) des libs permet d'identifier une vulnérabilité non publique ...

Sauf que cette vulnérabilité est déjà corrigée (silencieusement) par l'éditeur dans sa propre version des libs ... et qu'il ne l'a (afaik) pas signalé au mainteneur au cours de ces dernières années :-(

newsoft said...

Ne voyons pas le mal partout. Il est possible que:

1/ un développeur fatigué copie/colle du code open source en prenant bien soin de supprimer tous les commentaires (dont la licence).

2/ un relecteur de code tombe sur un bogue trivial et le corrige.

Et hop !