Acerca del BSOD de srv2.sys
Hola qué tal.
Bueno hoy nos hemos levantado con la noticia del BSOD que Laurent Gaffié ha publicado.
Tras analizar el código vulnerable y probarlo, tengo que avisaros que al contrario de lo que dice el autor y se está reproduciendo en otras páginas, esta vulnerabilidad SÍ PERMITE la ejecución de código remótamente, al igual que abre la posibilidad para escalar privilegios en local. Hay que aclarar que por el momento la ejecución de código dista mucho de ser reliable al igual que la escalada de privilegios. Pero no hay que considerar como un mero DoS esta vulnerabilidad porque tiene el potencial de convertirse en ejecución de código controlado.
Y ahora os explicaré el porqué basándonos en razones técnicas, en esto de las vulnerabilidades el publicar un advisory méramente empírico no es de recibo, teniendo en cuenta que es un 0day
Veamos dónde se produce el fallo.
módulo: srv2.sys
; int __stdcall Smb2ValidateProviderCallback(PVOID DestinationBuffer)
_Smb2ValidateProviderCallback@4 proc near
…
…
.text:000156B3 loc_156B3: ; CODE XREF: Smb2ValidateProviderCallback(x)+4D5j
.text:000156B3 ; Smb2ValidateProviderCallback(x)+4DEj
.text:000156B3 movzx eax, word ptr [esi+0Ch]; packet->SBM_Header->Process_ID_High
.text:000156B7 mov eax, _ValidateRoutines[eax*4]; FALLO – out-of-bounds dereference.
.text:000156BE test eax, eax
.text:000156C0 jnz short loc_156C9
.text:000156C2 mov eax, 0C0000002h
.text:000156C7 jmp short loc_156CC
.text:000156C9 ; —————————————————————————
.text:000156C9
.text:000156C9 loc_156C9: ; CODE XREF: Smb2ValidateProviderCallback(x)+4F3j
.text:000156C9 push ebx
.text:000156CA call eax ; Smb2ValidateNegotiate(x) ; Smb2ValidateNegotiate(x) – KABOOOM!!
Como véis lo que está haciendo es usar el campo de 16 bits de la cabecera SMB 2.0 ProcessIDHigh como indice en una tabla de funciones sin comprobar previamente el tamaño de la tabla. Cagada de libro. De esta manera podemos dereferenciar un puntero arbitrario que si no es nulo nos dará la direccion a la que saltará la ejecución.
Empíricamente el exploit que ha liberado el fulano puede funcionar o no, ya que lo que produce el BSOD es que el indice es demasiado alto y apunta una página no paginada. Pero en algunos sistemas podría darse el caso que sí estuviera paginada y no fallara o fallara en otro punto, de hecho lo he comprobado en varios sistemas Vista x86.
Por lo tanto, la ejecución de codigo remoto es posible ya que ESI apunta a nuestro paquete de datos. [ESI+C] que es el indice es un campo que nosotros controlamos de 16 bits. Lo que hace falta es encontrar un puntero adecuado que nos permita controlar la ejecución en base a estos datos. Dado que la sección PAGE del driver esta en direcciones más altas que la sección .DATA donde está la tabla de funciones, esto mejora la situación.
La ejecución de código a nivel local para elevar privilegios, vendría dada por el mismo tipo de explotación, lo único es que todas las rutinas del srv2.sys en este tipo de peticiones se manejan en el contexto del SYSTEM no del proceso que envía el socket, si no la elevación de privilegios sería trivial ( ver valores fixed al final de la table de funciones , a partir del indice 0x13 tendríamos user-mode addresses ).
Los sistemas vulnerables son Vista, Windows 7 RC y Server 2008.
Pues eso, a filtrar paquetes en el 445 y 139 etc… ojito ahí fuera.