Reversing de Virtual VCR Max para un bug tipo Stack Buffer Overflow

Viendo un post al azar en (ExploitDB) de una vulnerabilidad de tipo Denegación de servicio para el binario Virtual VCR Max, donde el uso básico de esta herramienta es tomar video y capturas de pantalla en windows.

Ahora mi idea fue ver porque sucede el crash o el bloqueo de del binario cuando se ingresan ciertos valores o caracteres (bytes) demasiado largos.

Entonces para iniciar el análisis hay que empezar por el principio 😅 que es ejecutar el binario después de eso queda en ejecución y se puede observar su icono en la barra de abajo, este despliega varias opciones la cuales tenemos un Load Profile… donde podemos cargar un archivo de configuración con extensión *.vcr y dentro del archivo existe una variable llamada CaptureFile que es la que produce el bloqueo. Bueno al cargar este archivo no hay problema el binario sigue en ejecución pero cuando tratamos de ir a la opción de Settings… es aquí donde ya no abre y eso porque? lo veremos mas adelante 😎.

Menu
Form Settings…

Aquí ya empezamos a renombrar funciones 👽, el primero que vemos lo llame open_file_form con un argumento tamaño de 0x104 (260), el cual lo único que hace es mostrar la ventana para cargar el archivo de configuración *.vcr usando GetOpenFileName.

Después de cargar el archivo se hace la llamada a get_settings donde verifica si se cargo un archivo y toma cada valor de las variables seteadas, y se observa cuando se hace la lectura de del parámetro que activa el bloqueo. Ya con la información cargada en memoria seguimos con el siguiente paso que es ver la configuración, esto activara el bug pero antes veremos como seria una ejecución normal (sin bloqueo).

get_settings

Este seria el archivo de configuración a cargar o también se puede copiar el string y pegar en el input Capture File Name en settings .

file config *.vcr
String a probar (254 bytes): “AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDEEEEEEEEEEFFFFFFFFFFGGGGGGGGGGHHHHHHHHHHIIIIIIIIIIJJJJJJJJJJKKKKKKKKKKLLLLLLLLLLMMMMMMMMMMNNNNNNNNNNOOOOOOOOOOPPPPPPPPPPQQQQQQQQQQRRRRRRRRRRSSSSSSSSSSTTTTTTTTTTUUUUUUUUUUVVVVVVVVVVWWWWWWWWWWXXXXXXXXXXYYYYYYYYYYZZZZ

Después de cargar la data, abrir el menú Settings y pasar por una serie de comprobaciones llegamos a a la función sub_410260 donde aquí nos encontramos con una sorpresa.

En sub_410260 vemos una llamada a PropertySheetA donde nos concentraremos para ver que esta pasando por ahí… Seguido de algunas rutinas conseguimos una llamada a sub_4105D0 es aquí la cereza del pastel.

función vulnerable

La rutina tiene un wsprintfA(Buffer, %s, string) donde tomar el nombre ingresado (data) para luego almacenar en un buffer de 0x100 (256).

int WINAPIV wsprintfA(
 LPSTR ,
 LPCSTR ,
 … 
);

Mas sobre: wsprintfA()

Se observa en Rojo la dirección del buffer luego tenemos en Amarillo el offset_data dirección base hacia el nombre ingresado y en Verde que es offset_data+8 puntero al inicio del nombre.

copia data en buffer

Después de copiar el nombre en el buffer con wsprintfA() nos encontramos con la sorpresa 🙀 esto no tiene un control de tamaño para la entrada de un usuario, así que nos permite enviar mas data de lo esperado por el binario siendo de un largo de 0x102 (258) máximo y el buffer solo espera 0x100 (256) bytes upss!. Esto quiere decir que pisamos el retorno por eso se produce el bloqueo.

Stack buffer

Ya solo queda una llamada mas a SetDlgItemTextA(hDlg, 1000, buffer) que se pasa como argumento el buffer, este su utiliza para establecer el título o texto de un control en un cuadro de diálogo.

BOOL SetDlgItemTextA(
 HWND hDlg,
 int nIDDlgItem,
 LPCSTR lpString
);

Mas sobre: SetDlgItemTextA()

También un add esp, 0x100 que supuestamente se posiciona el final del buffer (data enviada), pero eso nos dejaria en los 3 últimos bytes enviados.

desplazamiento de stack

Se puede observar como el retorno tomara una dirección 0x005A5A5A que seria las 3 ultimas ‘Z’ del strings enviado y se agrega el 0x00 en el byte alto.

retorno

Control del registro de retorno.

mensaje corrupción

De manera que se puede ocupar la dirección base del binario para hacer un bypass del byte null, ahora el problema es que solo hay una dirección de prueba eso quiere decir que tenemos 4 bytes para poner una dirección valida que alinea ESP para caer en direcciones controladas.

relative address
gadget

Visita: www.exploiting.cl

By3…