viernes, 12 de agosto de 2011

Cifrando un ejecutable en C, problemas


Cifrando un ejecutable en C

El código que se mostró en la anterior entrada para cifrar un ejecutable haciendo XOR sobre toda su sección de código no funciona con todos los ejecutables. Vamos a ver algunas de las posibles situaciones en las que se me ocurre que puede fallar.

En el ejecutable del netcat la IT, Import Table, estaba en la sección .rdata. Para ver en que sección está la IT se puede mirar en la cabecera PE, en el directorio de datos, la VirtualAddress del directorio de importaciones.

image

Y mirar en que sección cae esta dirección. Claro que es mucho mas fácil abrir el ejecutable con OllyDbg y ver el mapa de memoria:

image

En el caso del netcat el crypter no tocaba en ningún momento la IT. Pero hay muchos ejecutables, por ejemplo la calculadora de windows, en el que la IT está en la sección de código:

image

¿Qué sucede en estos casos?

Que nuestro crypter cifra toda la sección de código incluida la IT. Y cuando Windows carga el ejecutable, y el loader trata de recorrer la IT para rellenar la IAT, Import Address Table, se encuentra con una tabla sin sentido, con punteros a zonas de memoria que no existen y BOOM!! Explota:

image

Deberíamos o bien, omitir a la hora de cifrar la zona donde está la IT y la IAT. O bien, invalidar la IT en el directorio de datos y cargarla desde la rutina que hemos añadido después de descifrar la sección.


Otra de las cosas que puede fallar es cuando la IT u otra tabla de datos se encuentra en la cabecera PE, aprovechando el espacio libre que surge de alinear el tamaño de la cabecera, este espacio está justo después de la tabla de secciones. Volviendo a la calculadora de nuevo, podemos observar como la tabla “BoundImportDirectory” está dentro de la cabecera en la posición 260h:

image

Está tabla es usada para cargar mas rápidamente un ejecutable, ya que digamos que tiene precargada toda la IAT para una determinada versión de librerias, DLLs, ahorrandose así el tiempo de recorrer toda la IT e ir buscando la dirección de cada función para compeltar la IT. Si ya conoce al versión de DLL que se va a cargar ya sabe exactamente en que dirección se va a encontrar la función.

El caso es que esta tabla está en la posición 260h, justo despues de la tabla de secciones:

image

Y cuando nuestro crypter de la anterior entrada añade una sección sobrescribe parte de está tabla dejándola con datos erróneos.

Al añadir una sección deberíamos tener cuidado de no sobrescribir ninguna tabla, y si es necesario relocalizar la tabla en otro lugar.


Otro problema, es que nuestra rutina de descifrado usa el registro EAX, el cual deja con el valor del Original Entry Point, así cuando se ejecuta el código original no está todo como debería estar si no se hubiese cifrado el ejecutable, ya que aunque la pila contiene exactamente lo mismo y la mayoría de los registros están sin cambiar, el registro EAX, que suele inicializarse a 0, en nuestro caso tendría otro valor. Esto puede dar problemas en muy raras ocasiones en las que se presuponga que inicialmente EAX vale 0 y el programa no se encargue de inicializar el registro. Pero si he visto código en ensamblador que usa el valor inicial de EBX, ya que el loader de Windows lo inicializa con la dirección del Process Enviroment Block, PEB, y es una forma mas cómoda de acceder al PEB, sin pasar antes por el TIB (fs:30).

Conclusión, el crypter debería dejar los valores de los registros y de la pila intactos tras ejecutar su rutina de descifrado. Para ello es muy habitual hacer uso de las instrucciones PUSHAD y POPAD que guardan y restablecen respectivamente todos los registros.

Y esto es lo que de momento se me ocurre que podría fallar, seguro que van surgiendo mas fallos según vaya probándolo.

Ahora toca mejorar el código del crypter para que tenga en cuenta estas cosas.

Saludos!

6 comentarios:

  1. Wao THOR, te has lucido con todo estos últimos artículos, aunque voy a serte bien sincero, me interesaría mucho asimilar completamente esto, y pues para eso me faltan 2 asuntillos:

    Aprender C
    Editores Hexadecimales

    Me gustaría saber si es C, C++, C++ VS.NET, y de paso si me recomiendas algún buen manual para empezar con ese lenguaje, no quiero hacerme viejo sin haberle cogido el gustillo.

    ResponderEliminar
  2. Por todo lo demás estos últimos artículos te han quedado bestia, aún a pesar de mis dificultades, voy a tomarme unos días para analizarlo todo con detalle.

    Gracias, un abrazo.

    ResponderEliminar
  3. @Digit0 Manuales hay muchos y no hay diferencia entre ellos, la diferencia la ponemos en nuestro subconciente, que por su fuente creemos que es mejor. Busca, en su mayoria son buenos y se enfocan en lo mismo.
    @Thor, que bien ver tan buenos post, ahora es mejor si se cifrase todo el cuerpo del ejecutable y se cargara la IAT a mano. Lo único que no se podría cargar sería los TLS.

    Un saludo y gracias,

    ResponderEliminar
  4. The Swash a título personal estas 100% equivocado, los manuales son hechos por distintos tipos de personas alguna con sentido de integridad y criterio, y otro solo con sentido superfluo y vano, el resultado nunca es el mismo, todo esto lo digo considerando que en la mayoría de veces mi conocimiento ha sido tomado por cuenta propia.

    El esfuerzo, empeño e integridad en el desarrollo de material educativo se percibe de manera clara.

    ResponderEliminar
  5. Disculpa el retraso, blogspot no me aviso de los nuevos comentarios. No te puedo recomendar ningún manual, yo lo aprendí en al universidad.

    Lo que si te recomendaría en seguir un libro de C por ejemplo este:
    http://www.amazon.com/Introducci%C3%B3n-programaci%C3%B3n-algoritmos-Spanish-ebook/dp/B00280LZCC

    Ya que los manuales que se suelen encontrar por foros y tal, suelen ser muy breves y a veces contienen imprecisiones.

    Y como todo es muy importante practicar mucho según se va aprendiendo.

    Suerte y un saludo!

    ResponderEliminar
  6. Gracias Thor, estoy hojeando el libro ahora, ese era el detalle mío, que C, C++ son lenguajes un antiguos y les comentaré que por mi localidad ya nadie los enseña, se enseña NET, JAVA, ASP y toda esa nota, me gusta NET, pero muchas veces en varias ezines se sigue tomando al poderoso C++ y ASM, Gracias Thor por vuestros aportes.

    Y muchas felicidades por la trayectoria que va tomando la FOCA. ;)

    ResponderEliminar