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:
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-4484 pour libgd
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-6697 pour SDL_image
- http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1373 pour un bug similaire dans CUPS, bien que la fonction ne soit pas la meme
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):
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.
.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.