lunes, 21 de noviembre de 2011

Patch Bindiffing (II)

La semana pasada nos quedamos en un anterior post con que habíamos analizado un parche y habíamos descubierto que ficheros del sistema habían sido añadidos o actualizados.

Ahora nos quedaba la segunda parte, que es... ¿qué modificaciones se han hecho sobre estos binarios?
Para hacer esto tendremos que coger las dos versiones del binario, librería, o en este caso driver, y emplear alguna de las herramientas que existen para hacer este análisis diferencial.

Para este caso concreto he usado una extensión de IDA, desarrollada por Tenable, llamada patchdiff2, y que os podeis descargar de forma completamente gratuita aquí.

Hay otras extensiones para IDA que realizan estas mismas acciones. Vierito5 publicó hace tiempo en su blog una lista de extensiones recomendadas para IDA en las que, además de otras muchas extensiones de todo tipo, podemos encontrar varias opciones para realizar bindiffing.

Para añadir uno de estas extensiones únicamente hay que buscar el directorio "plugins" dentro del directorio de IDA. Lo reconoceremos porque veremos que tiene dentro ficheros con extensión "*.pmc", que son exactamente como los que nos vendrán en el zip del patchdiff2. Dejamos los "pmc" del patchdiff2 en este directorio y ya tendremos completamente disponible la extensión la próxima vez que arranquemos IDA.

Para poder utilizar el bindiffing es necesario que este se haga a partir de los ficheros "*.idb" de IDA, que es un formato propio de esta herramienta en el que podemos guardar el análisis que realiza la herramienta sobre un binario concreto. Para ello, abrimos el primero de los binarios (tcpip-old.sys) y dejamos que IDA lo pre-procese, y cuando acabe de hacerlo cerramos y elegimos guardar la base de datos, con lo que se nos generará un fichero tcpip-old.idb, que usaremos a continuación.

Ahora abrimos de nuevo IDA pero esta vez elegimos analizar tcpip-new.sys, y dejamos de nuevo que IDA lo pre-procese. Una vez que acabe nos vamos al menú "Edit" y a "Plugins", y elegimos el plugin "PatchDiff2", con lo que se nos abrirá una ventana para elegir con que otro fichero "*.idb" lo queremos comparar. Elegimos tcpip-old.idb y lo dejamos que realice el bindiffing.

Al hacer esto, veremos que nos salen tres pestañas nuevas:

  • Identical Functions: Son aquellas que han sido detectadas como idénticas en ambos binarios, es decir, no han cambiado al hacer el bindiffing.
  • Unmatched Functions: Son aquellas de las que, teóricamente, no se ha podido encontrar una función equivalente en el otro binario. Generalmente suele tratarse de funciones nuevas, aunque es muy común que nos encontremos muchas funciones idénticas pero que por algún motivo no se han hecho match. La columna CRC nos puede dar una pista sobre esto.
  • Matched Functions: Son aquellas que han sido detectadas como que son las mismas, pero que han sufrido alguna modificación

Sabiendo esto, y dado que nos estamos centrando en un bindiffing, podemos asumir que las funciones que han hecho match completo no nos interesan, y que las unmatched que tengan un CRC idéntico o que sean completamente nuevas, tampoco nos interesan (a priori, si notamos que nos falta información volveremos atrás), ya que las funciones nuevas tienen que ser llamadas desde ningún sitio, así que su "origen" lo vamos a tener pillado a través de las funciones "matched".


En este caso, tenemos cinco funciones que parecen haber sido modificadas por el parche, así que alguna de ellas tiene que haber sido la que corrige la vulnerabilidad, o quizá una combinación de varias de ellas.

Para poder ver los cambios exactos introducidos en cada una de ellas, deberemos seleccionar la función y pulsar con el botón secundario del ratón para que nos salga el menú, y elegiremos la opción "Display Graphs".


Una vez que vemos gráficamente la función, vemos de una forma muy clara las modificaciones realizada, ya que el código se encuentra separado en bloques con un código de colores que nos proporciona información sobre estos cambios:

  • Blanco: Bloques idénticos, es decir, no se ha producido ningún cambio en ellos.
  • Gris: Bloques "unmatched", generalmente trozos nuevos de código que serán llamados desde algún otro bloque modificado.
  • Rojo: Bloques "matched", es decir, que han sufrido algún tipo de modificación.

No os puedo remitir a la documentación de PatchDiff2 para más información, ya que al menos yo no he encontrado ninguna fuente oficial, pero podeis encontrar información buscando en Google, o sencillamente jugando un poco con ella, ya que permite hacer correcciones sobre el análisis automático que hace, es decir, podeis pasar de "unmatched" a "matched" una función, y cosas así.

En el próximo post, veremos cada una de estas funciones, a ver que cambios concretos ha realizado el parche, a ver si conseguimos averiguar en que consiste la vulnerabilidad que parchea.

7 comentarios :

Anónimo dijo...

muy bueno, esperando la tercera parte...

Mario dijo...

Muy bueno el post :)

Una idea para un post futuro: hay otra herramienta similar pero mas nueva que se llama TurboDiff, estaria muy interesante una comparativa con el Patchdiff. Como lo ves?

Saludos!

Jose Selvi dijo...

Gracias @Anónimo y @Mario,

Hay varias herramientas que hacen cosas similares, y sin duda sería interesante una comparación de ellas.

Me parece una buena idea, pero ahora mismo estoy bastante liado con un par de proyectos y no creo que pueda escribir nada que no sea sobre los temas con los que estoy ahora mismo o sobre cosas que tenga que hacer en algún proyecto en el trabajo.

De todos modos, tomo nota, el lío que tengo ahora mismo no durará siempre, espero ;)

Jose Selvi dijo...

De momento aún tengo que sacar tiempo para escribir la última entrada de la serie xD

Anónimo dijo...

Muchas gracias José, muy bueno tu artículo, en espera de la tercera parte..

WiNSoCk dijo...

Que conste, que es un comentario de buen rollo eh? Pero a los visitantes, nos debes el último post de la serie ;) -o quizá, no fui capaz de encontrarlo-

Jose Selvi dijo...

Lo debo, lo debo ;)
No se me olvida.