Tuesday, May 25, 2010

Question du Jour

Trouve dans une DLL d'un systeme d'exploitation bien connu:

lea eax, [ebp+var_44]
push eax ; hMem
call ds:__imp__LocalFree@4 ; LocalFree(x)

Quelqu'un peut-il me dire:
  1. Pourquoi c'est "mal"?
  2. Quelle est l'erreur du programmeur qui a mene a ce code?
  3. Comment exploiter cela?
Par une operation du Saint Esprit, le code n'est pas atteignable dans la DLL en question. C'est moche.

Wednesday, May 19, 2010

Exception Culturelle

La derniere fois que je suis tombe sur du code promouvant l'exception culturelle Francaise, il s'agissait de cles DES specifiees en dur dans le Protected Storage. Cette fois-ci, on va regarder SChannel.

Un utilisateur averti pourra se demander pourquoi dans SChannel v5.1.2600.5834 (XP SP3 US plus ou moins a jour) on trouve la fonction IsSchEncryptionPermitted(), qui contient:

call ds:__imp__GetSystemDefaultLCID@0 ; GetSystemDefaultLCID()
cmp ax, 40Ch
jz short loc_767F41A7
push 0Ah ; cchData
lea ecx, [ebp+LCData]
push ecx ; lpLCData
push 5 ; LCType
push eax ; Locale
call ds:__imp__GetLocaleInfoA@16 ; GetLocaleInfoA(x,x,x,x)
test eax, eax
jz short loc_767F41A7
lea eax, [ebp+LCData]
push eax
call _MyStrToL@4 ; MyStrToL(x)
cmp eax, 21h
jnz short loc_767F41B8
loc_767F41A7: ; CODE XREF: IsSchEncryptionPermitted()+1Aj
; IsSchEncryptionPermitted()+2Dj 
and _g_ProtEnabled, 0FFFFFFFCh
mov _g_fFranceLocale, 1

Sauf que cette fois ci, le resultat n'est pas le meme. Si le Windows est francophone, on enleve les deux bits de poids faible de _g_ProtEnabled et on met a 1 une variable obscure.

Dans le code de SslReadRegOptions(), si _g_fFranceLocale est non 0, on ne prend pas en compte l'activation ou desactivation des protocoles specifies dans la base de registre, decrit dans la KB187498, si les bits de poids faible sont presents.

Les bits utilises pour l'activation des protocoles sont:
  • "Multi-Protocol Unified Hello\\Client": 80000000h
  • "Multi-Protocol Unified Hello\\Server": 40000000h
  • "PCT 1.0\\Client": 2
  • "PCT 1.0\\Server": 1
  • "SSL 2.0\\Client": 8
  • "SSL 2.0\\Server": 4
  • "SSL 3.0\\Client": 20h
  • "SSL 3.0\\Server": 10h
  • "TLS 1.0\\Client": 80h
  • "TLS 1.0\\Server": 40h

En conclusion, si je ne me suis pas plante, pas de drame - a part qu'un Windows francophone ne puisse pas faire de PCT du tout (client ou serveur). Ca m'aurait ete utile de savoir ca en 2004 pour l'exploit PCT Handshake...

Si quelqu'un veut confirmer, amusez-vous, je testerai sans doute dans la semaine pour verifier et mettrai a jour le post. Je n'ai pas d'explication au bannissement de PCT en France.

Et joyeux anniversaire a ma soeur!

Exploiter un double free() sous Windows

Un soir, une discussion avec Ronald et Sean nous a mene sur le sujet des doubles free() sous Unix, et je me suis rendu compte que je n'avais jamais exploite un double free() sous Windows. Bien que la problematique ne soit pas extremement complexe, il semblerait qu'il n'y ait pas des masses de documentation sur le sujet, a part une entree de sh0ck qui se retrouve massacree un peu partout.

Bien entendu, de nombreux elements entrent en compte:
  • Y a-t-il ecriture des donnees entrent les deux free()?
  • Le Heap en question a-t-il un Lookaside?
  • Est-ce que le Lookaside a atteint sa profondeur maximale avant le 1er free()? Apres?
  • Le Chunk libere est-il VirtualAllloc()'ed?
Quelques inexactitudes sur le sujet:

Tout d'abord: le free() d'un chunk deja marque comme libere (Chunk.Flag & 1 == 0) n'a aucun effet. Donc contrairement a ce qu'affirment des papiers comme Towards Automatically Generating Double-Free Vulnerability Signatures Using Petri Nets (1), meme s'il y a possibilite d'ecriture dans la partie data du chunk entre les deux free(), il ne se passera rien. S'il y a liberation, ecriture puis allocation, c'est une histoire differente (unlink sur un LIST_ENTRY maitrise qui donne un Write4) et ce n'est pas un double free().

Ensuite, si le chunk est VirtualAlloc'ed() - c'est usuellement le cas si la taille/8 est > 0xfe00 qui est le seuil par defaut - le 1er free() va retourner la page au gestionnaire de memoire de Windows qui va decommit la zone rapidement. Cela entrainera une violation d'acces lors du second free().

Nous sommes donc restreints aux cas ou le chunk est libere vers la Lookaside puisque dans ce cas la le chunk est toujours marque comme occupe. Donc:
  1. Le Heap en question doit avoir un Lookaside
  2. Le free() doit etre sur un chunk dont la taille est < 1024
  3. L'entree correspondante du Lookaside doit avoir au moins 1 place disponible (la profondeur par defaut est 4 la plupart du temps) sinon il sera libere vers la FreeList[]
Apres, il existe plusieurs possibilites, que l'on trouvera decrites dans une entree du blog de Symantec par Matt Connover.
  • Premier free() vers le Lookaside qui se retrouve plein entrainera un second free dans la FreeList[] (et potentiel coallesce) avec ecrasement du LIST_ENTRY apres premiere allocation, et une entree de Lookaside pointant vers le chunk libre (de la FreeList[]) suivant.
  • Premier et second free() vers le Lookaside, qui entrainera une primitive WriteN lors de la troisieme allocation d'un chunk de la taille en question.

Au final, un double free() ca s'exploite relativement bien dans XP et 2003, mais pas comme le decrivent certains.

Edit: petite correction dans le 1er cas.

(1): "After it has been freed, the programmer mistakenly uses temp and writes X in the first 4 bytes and Y in the second 4 bytes of temp. Then the programmer frees temp again. The system will then try to insert temp into the free list for a second time right before where it is already inserted."

Thursday, May 6, 2010

Supernaturel

Ce soir, Sam & Dean rencontrent le 3e Cavalier de l'Apocalypse: Mort. Cela faisait un moment que je n'avais pas autant accroche a une serie TV - mais Supernatural semble combler le manque. Voici le trailer de l'episode en attendant la diffusion dans une heure!



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.

Wednesday, April 21, 2010

FIRST Conference 2010: In Miami, Bitch

La 22e conference du FIRST se deroulera du 13 au 18 Juin 2010 a Miami. Le programme est disponible ici. Je n'ai pas trop prete attention au deroulement de ces conferences depuis que j'ai quitte le "milieu", mais bon cette annee c'est special vu que ca se deroule pas loin de mon WHQ - et Dave presentera une keynote! Je serai dans les environs, histoire de dire bonjour aux anciennes connaissances - ou me faire cracher dessus.

Si vous comptez vous deplacer pour l'occasion, qu'il n'y a pas de gros nuage volcanique, etc., envoyez moi un mail et je tacherai de vous faire decouvrir Miami et Miami Beach!

Wednesday, March 10, 2010

Ultra Music Festival 2010


Gros line-up comme d'habitude pour l'UMF cette annee. Miami va etre relativement penible a vivre pendant la semaine de la Winter Music Conference, mais bon on va tacher de faire avec.