Depuis Visual Studio 2003, une sécurité a été implémentée pour protéger la pile des dépassements de tampon, elle
consistait à intégrer un canari, c'est-à-dire un cookie qui prenait une certaine valeur avant l'appel d'une fonction,
dans la pile de la fonction, celui-ci étant confronté à sa valeur initiale à lors de l'épilogue de la fonction de façon à
détecter tout dépassement de capacité. Ce mécanisme a donc été utilisé pour les applications userland compilées
avec les nouvelles versions de Visual Studio. Beaucoup d'articles sur cette option de compilation – flag /GS – sont
disponibles sur le Net.
En ce qui concerne les drivers – kernel-land -, ceux-ci sont compilés avec le DDK (Driver Development Kit)
distribué par Microsoft pour développer ses drivers. Mais les drivers aussi sont sujets à risque concernant les
buffer overflow, de même que les applications userland. Un mécanisme très similaire à celui du Visual Studio a
donc été également instauré dans le compilateur du DDK : lors de la compilation du driver, un mécanisme de
cookie est implémenté à l'épilogue de chaque fonction, on peut l'analyser en désassemblant un driver compilé.
[...] En effet, la variable __security_cookie possède une valeur pré-définie (ici 0x0BB40), de là GsDriverEntry va vérifier si sa valeur est nulle (même si à la base elle est non-nulle), puis vérifie qu'elle est égale à 0x0BB40 (encore une fois sa valeur initiale). Dans tous les cas, GsDriverEntry générera une nouvelle valeur pour le canary, sauf si la valeur de __security_cookie est déjà différente de celle stockée dans EDX. Puis une dernière vérification est effectuée après l'initialisation du cookie : s'il se trouve qu'il est nul, on lui affecte sa valeur auparavant prédéfinie (0x0BB40), ce qui est peu probable. De là, on exécute l'épilogue de GsDriverEntry qui nous fera sauter directement sur l'entrée du driver : jmp DriverEntry. [...]
[...] On peut donc deviner que la fonction __security_check_cookie mettrait un terme radical à l'exécution du driver en cas de cookie altéré, afin de ne pas voir le flux d'exécution détourné. ww.oboulo.com On désassemble cette fonction de vérification : __security_check_cookie proc near cmp ecx, __security_cookie jnz short loc_105BB ; on appelle __report_gsfailure si le cookie est falsifié test ecx, 0FFFF0000h jnz short loc_105BB retn ; canary valide loc_105BB: jmp __report_gsfailure __security_check_cookie endp ; on appelle la fonction report On comprend que __security_check_cookie opère une comparaison entre EDX (contenant la valeur du cookie de la pile) et __security_cookie, si le résultat est faux (le cookie a été altéré), on saute sur __report_gsfailure. [...]
[...] Dans le cas de Visual Studio, les applications qui détectent un dépassement de tampon font appel aux gestionnaires d'exception SEH, qui termineront de façon assez propre l'exécution du programme avant qu'un quelconque code arbitraire ne soit exécuté par le processus vulnérable. Dans le cas des drivers, la réponse à cette détection est plus radicale : un BSOD est affichée avec les informations qui vont avec. Ceci néanmoins reste contraignant, car un driver vulnérable à distance (pour exemple) pourrait permettre des attaques DoS (Denial Of Service) très efficaces de la part de potentiels attaquants. [...]
[...] Finalement, on analyse le code du jump __report_gsfailure : __report_gsfailure: mov edi, edi push ebp mov ebp, esp push ecx mov ecx push 0 push __security_cookie_complement push __security_cookie ; valeur originale du cookie push dword ptr [ebp-4] ; valeur à priori altérée du cookie push 0F7h call ds:__imp__KeBugCheckEx@20 ; KeBugCheckEx(x,x,x,x,x) Ici, on empile les arguments nécéssaires à la fonction KeBugCheckEx (exportée par ntoskrnl.exe) : entre autres la valeur originale du cookie (__security_cookie) et celle du cookie de la pile (stockée toujours dans ECX), puis on appelle cette fonction, qui sera chargée de vous afficher un BSOD comme il se doit. Conclusion : En ce qui concerne les drivers développés avec DDK, ceux-ci se voient aussi équipés du mécanisme de protection par les cookies, comme c'était le cas avec le flag /GS de Visual Studio pour des applications utilisateur. On a remarqué que l'initialisation du canary s'effectuait dans la fonction GsDriverEntry, avec un mécanisme un peu différent de celui du flag il n'en reste pas moins assez aléatoire utilisation de KeTickCount). [...]
[...] Un mécanisme très similaire à celui du Visual Studio a donc été également instauré dans le compilateur du DDK : lors de la compilation du driver, un mécanisme de cookie est implémenté à l'épilogue de chaque fonction, on peut l'analyser en désassemblant un driver compilé. On peut pour l'exemple faire appel à une fonction foo() à partir de DriverEntry du driver ; je l'ai compilé pour l'exemple avec le DDK build 3790.1830 sous Windows XP. La partie importante de ce mécanisme est l'initialisation du canary, il doit posséder une valeur aléatoire. En comparant ce mécanisme d'initialisation pour les drivers aux applications compilées avec VS, vous remarquerez qu'elles sont bien différentes. Quand est-ce que le canary est initialisé ? [...]
Source aux normes APA
Pour votre bibliographieLecture en ligne
avec notre liseuse dédiée !Contenu vérifié
par notre comité de lecture