inicio mail me! sindicaci;ón

DoS remoto en Windows Vista

El último bombazo: provocar una Blue Screen of Death (BSOD) en Windows Vista, Windows 7 RC o Windows 2008 Server (<R2)

La noticia original (con su exploit en python): Windows Vista/7: SMB2.0 NEGOTIATE PROTOCOL REQUEST Remote B.S.O.D. (con fecha de 7 de septiembre).

Esta mañana la he probado en un portátil con Windows Vista:

  1. He activado la compartición de archivos: en Panel de control hay una opción que dice algo así como Opciones de red y de compartir recursos, y ahí dentro hay varias opciones para elegir qué se comparte. Esto es necesario para activar la pila Samba del kernel de Windows.
  2. Si hubiera un firewall que cubriera el puerto 445 habría que desactivarlo. No era el caso.
  3. Utilizando el exploit de Laurent Gaffié y sabiendo la IP del portátil lo tiré abajo sin más que cortar el exploit, pegarlo en un fichero y ejecutarlo contra el portátil.

El funcionamiento

El exploit simplemente se conecta al puerto 445 de la víctima, envía un mensaje de sesión SMB y se desconecta.

En tal mensaje de sesión, en su cabecera, hay un atributo que se llama Process ID High, de 16 bits. Normalmente suele ser 0, pero lo que descubrió Laurent es que si en vez de ser 0 era 0×26 (lo que viene siendo un &), conseguía obtener un bonito fallo de página (error PAGE_FAULT_IN_NONPAGED_AREA).

Es decir, que manipulando ese atributo provocaba que algún puntero en algún lado apuntara hacia alguna zona de memoria que no pertenecía a nadie. Para más inri, el código del SMB2.0 está en el kernel, por lo que este fallo de página se lanzaba en modo kernel, con el consecuente reinicio de la máquina.

Hasta aquí lo que tenemos en un ataque remoto de denegación de servicio.

Lo que posteriormente ha descubierto Rubén Santamarta, de 48bits, es que se puede (con ciertas limitaciones) manipular la dirección a la que salta el kernel según el valor de ese atributo de la cabecera, pudiendo dar lugar a una inyección de código.

Tal y como explica en su artículo:

.text:000156B3                 movzx   eax, word ptr [esi+0Ch]; packet-&gt;SBM_Header-&gt;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) ;

Inicialmente partimos de que ESI apunta a una parte de la cabecera SMB del paquete recibido. ESI+0x0C es un puntero al atributo Process ID High de tal cabecera, por lo que

movzx   eax, word ptr [esi+0Ch]

Nos deja en EAX, los 16 bits de más peso a 0 (siempre) y los 16 de menor peso con el contenido de tal atributo copiado literalmente (ver movzx). Por ejemplo, si el Process ID High fuera 10,  EAX tendría el valor 0x0000000A,

La siguiente instrucción

mov     eax, _ValidateRoutines[eax*4]

va a la tabla (de punteros a función) _ValidateRoutines, y según el valor de EAX, escoge una entrada u otra (cada una ocupa 4 bytes).

Siguiendo con el ejemplo, esto cogería la undécima entrada de la tabla (en la dirección _ValidateRoutines + 0×28) y la copiaría en EAX, con lo que tendríamos en EAX la dirección de memoria de la función a ejecutar.

A continuación se comprueba si tal puntero no es nulo. De ser nulo, en EAX se guarda el valor 0x0C0000002 y se sigue con la ejecución en otra parte.

test    eax, eax
jnz     short loc_156C9
mov     eax, 0C0000002h
jmp     short loc_156CC

Por el contrario, si efectivamente no es nulo, se guarda EBX en la pila y se salta a tal función:

loc_156C9:
push    ebx
call    eax

Conclusión: según pongamos un valor N en el atributo Process ID High, podemos conseguir que el kernel salte a la posición de memoria indicada en la entrada (N+1)-ésima de la tabla _ValidateRoutines.

¿Y si la tabla tiene menos entradas que N+1? Pues la dirección de memoria la tomará de lo que venga después de esa tabla. Si pudiésemos controlar el contenido de esos datos que están después, se podría hacer que el kernel saltara a una posición a voluntad. Y por eso es que Rubén habla de cierta posibilidad de ejecución de código remoto.

Address changed – Reset device now

He adquirido un Bluetooth USB Adapter, es decir, un cacharro USB para conectarme por Bluetooth a otros chismes. Andaba tiempo detrás de uno, desde que empezó todo el tema del bluehacking.

Ayer tarde, cuando llegué con mi flamante Adapter de 17 euros –Conceptronic CBTU2, funciona perfecto en Linux hasta donde he probado– me puse a probarlo y a enredar con él. Al final acabé a las dos de la mañana habiendo leído la mitad del proyecto fin de carrera Seguridad en Bluetooth, de Alberto Moreno.

Uno de los ataques que se describen (dicho sea de paso, en la actualidad muy pocos de ellos son practicables) consiste en suplantar la identidad de otro dispositivo mediante el cambio de la MAC de nuestro adaptador Bluetooth.

Los interfaces Bluetooth tienen asociada una dirección unívoca cada uno de ellos. Bluetooth, de hecho, es el estándar IEEE 802.15 (ethernet es el 802.3, y wireless es el 802.11), por lo que las direcciones de Bluetooth son exactamente iguales que las Ethernet. Se trata de 48 bits, divididos en 24 superiores para indicar el OUI (identificador del fabricante del adaptador), y en 24 bits inferiores, para identificar el dispositivo fabricado por una determinada empresa. El espacio de direcciones se reparte por tanto, entre todas las normas 802.x que requieren direcciones MAC, por lo que no encontraremos un dispositivo Bluetooth con las misma MAC que una tarjeta inalámbrica o una ethernet.

El ataque llamado Blue MAC Spoofing se basa en los niveles de confianza en que se organiza el acceso a los servicios Bluetooth. Según sea el servicio, se podrá acceder tan sólo estando autorizado, o también estando autenticado.

Por estar autorizado se entiende que la MAC de tu adaptador Bluetooth está en la lista de MACs permitidas del receptor. La autenticación implica además el conocimiento de una clave compartida de 128 bits y una clave de sesión (un desafío de 128 bits). A partir de la dirección MAC propia, y esas dos claves se genera una respuesta de autenticación de 32 bits, que sirve para autenticarse ante el otro dispositivo.

Como hay servicios que tan sólo estando autorizados podemos utilizar, podemos dejar que sea otro dispositivo el que pase a ser autorizado, y luego suplantando su identidad, alcanzar su mismo nivel de privilegios. Supongamos un escenario donde una persona (A) le transfiere a otra conocida (B) un fichero (una fotografía, p.ej.). Si para poder hacer esta transferencia se necesita estar autorizado, al comenzar el móvil de B alertará y pedirá permiso para empezar a recibir la transmisión de A. Una vez que se le ha permitido la recepción (A y B son conocidos, y confían entre sí) la MAC de A pasa a la lista de autorizados de B. Si posteriormente cambiamos la MAC de nuestro dispositivo por la de A podremos hacernos pasar por A, heredando sus permisos.

El cambio de MAC se hace con la aplicación bdaddr, y no sé si funciona con todos los adaptadores (con el Conceptronic CBTU2 sí). Esta aplicación pareceser que viene en el paquete bluez-utils, aunque ahora mismo estoy con Debian SID actualizado y el paquete bluez-utils no cuenta con esa aplicación. Me he bajado el fuente de otro lado (aquí y acá) y he montado un .tar.bz2 con (casi) todo lo necesario para que compile el programa. Hay que tener instaladas las cabeceras en /usr/include/bluetooth/, y eso se consigue instalando el paquete libbluetooth-dev. Una vez bajado el bdaddr.tar.bz2, se descomprime y se compila:

pablo@golgi:~$ tar xvjf bdaddr.tar.bz2
pablo@golgi:~$ cd bdaddr/
pablo@golgi:~/bdaddr$ make

Y se ejecuta:

pablo@golgi:~/bdaddr$ ./bdaddr
Manufacturer: Cambridge Silicon Radio (10)
Device address: 00:80:5A:xx:xx:xx

O para cambiar la MAC, como root:

pablo@golgi:~/bdaddr$ sudo ./bdaddr -i hci0 00:80:5a:yy:yy:yy
Manufacturer: Cambridge Silicon Radio (10)
Device address: 00:80:5A:xx:xx:xx
New BD address: 00:80:5A:yy:yy:yy
Address changed – Reset device now
pablo@golgi:~/bdaddr$

Lo de reset device hay que tomárselo al pie de la letra: he tenido que desenchufar y volver a enchufar el adaptador, la orden hciconfig hci0 reset no funcionó.

En principio con eso hemos cambiado la MAC (si hacéis un hciconfig hci0 veréis que ha cambiado). Pero, ¿cómo saber la MAC del dispositivo autorizado? Aún estoy en ello, pero me figuro que a base de hcidump se podrá sniffar el tráfico de la red y determinar qué MACs están autorizadas.

Más interesante aún sería automatizar todo esto de forma que permanentemente se esté analizando el tráfico del entorno, y se determine qué MACs establecen conexiones y son autorizadas.

Update (2007-12-29): Efectivamente con hcidump se puede esnifar el tráfico, pero el tráfico dirigido hacia ti. En Bluetooth no hay nada parecido al modo promiscuo de las tarjetas ethernet. Las tramas de bluetooth van saltando de canal en canal de forma seudoaleatoria. Predecir ese salto son palabras mayores (por lo menos para mí), y disponer de hardware que pueda seguir los saltos también. Lo explican en este hilo de la lista de desarrollo de Bluez. Desde luego esa idea de averiguar qué MACs se comunican con qué MACs es nada factible ahora mismo. De alguna forma hay que conseguir que la víctima se conecte con tú dispositivo bluetooth para hallar su MAC.