lunes, 6 de mayo de 2013

Antivirus K.O. Cifrando un Malware a mano

En estos tiempos de liberación de feromonas primaverales, uno se da cuenta más que nunca del tiempo que se pierde preparando trabajos extra-laborales. Puedes encerrarte en tu cuarto y pensar la manera idónea de sacar un curso adelante, o sentarte en la terraza al sol, cerveza en mano y con un toque etílico estimularte. Yo como ya saben, soy más de lo segundo, inclusive podemos decir que medito con más soltura incluyendo en mi navegador, pestañas abiertas entre las que la temática, poco o nada tienen que ver con mi objetivo. Fuente de distracción para otros, para mí inspiración ante la a veces insufrible temática que nos ocupa.

Esta entrada surge como complemento a las anteriores sagas de Antivirus K.O., y más bien se trata de simular el funcionamiento de un crypter pero de una forma manual, insertando una rutina en un malware cifrado, que descifre en su ejecución el código en memoria.

Este método es útil para cifrar secciones completas, con lo que el primer paso sería identificar la sección o secciones de código ejecutable, normalmente conocida como la sección text, aunque dependiendo del lenguaje y compilación este nombre puede variar.

Se tratará el stub de un crypter público, llamado OP Crypter de Xash, el cual descargue su código fuente en Delphi de internet, lo compilé y empecé a trabajar sobre este. En la siguiente imagen, se muestra como mediante LordPE, aparecen todas las secciones.



Esta imagen será importante para identificar el tamaño de la sección CODE, pues será parte de esta la que cifraremos. La suma en hexadecimal de las direcciones contenidas en ROffset (El inicio de la sección) y RSize (El tamaño de la sección), coinciden con la del final de esta sección.

400 + 4200 = 4600

Es posible verlo a simple vista con el valor contenido en el ROffset de la siguiente sección DATA.
Contando con algo de suerte, entre el alineamiento de ambas secciones, es posible hacerse con un pequeño espacio para incluir nuestra rutina. Con lo que el siguiente paso, sería el de incluir el Flag de escritura a dicha sección. De nuevo abriremos LordPE y en la sección CODE, haremos botón derecho “Edit Section Header” y tildaremos el check.



Al guardar los cambios en el ejecutable, ya estará listo para acceder a debuggearlo y buscar el final de la sección CODE. Para realizar esta acción, se arrastrará el stub a Ollydbg, y sobre el código clic sobre “View – Executable file”. Al presionar Ctrl+G, se abrirá el buscador de Offsets e introduciremos 4600.



Si subimos hasta el final del código útil de la sección, será posible presionar el botón derecho para acceder al código desensamblado.



En este caso hemos tenido suerte, ya que tenemos espacio suficiente para introducir nuestra rutina. En caso de no tener hueco, podemos utilizar Topo v1.2, o añadir una sección nueva como hizo Francisco Oca en “Cifrando un ejecutable a mano” con netcat. Así que sustituiré parte del espacio libre por NOPs. Desde la dirección de memoria 100050A6 hasta 100050D5.



De tal manera, se dispondrá el espacio.


Para construir la rutina encargada del cifrado del ejecutable, serán necesarios algunos datos, los cuales es posible encontrar gracias a la primera imagen. Para convertir a partir de la posición del offset desde el cual empezará nuestro cifrado, en dirección virtual, es posible utilizar una simple fórmula matemática.

(Dirección física - ROffset) + VOffset + ImageBase = DirecciónVirtual
(400 – 400) + 1000 + 10000000 = 10001000

Otro dato importante será hacerse con la dirección donde finalizará el cifrado, en este caso he preferido incluir hasta cierta función perteneciente a la sección CODE, en vez de cifrar toda la sección.

El siguiente código será el que incluiremos para realizar el cifrado.

mov eax,10001000h ;Guardamos en eax la dirección de inicio del código a cifrar
xor byte ptr ds:[eax],0FF ;XOR FF a la dirección actual
inc eax ;Incrementamos el valor de eax
cmp eax,10003967h ;Comparamos si el valor de eax es igual a 10003967
JNZ SHORT 100050AB ;Saltamos de nuevo a la instrucción XOR (Bucle)
jmp 10004FACh ;Saltamos al Entry Point

Al incluir el código en el hueco, quedará de la siguiente manera:



Es ahora cuando necesitaremos que nuestra rutina se ejecute en primera instancia, con lo que la manera más sencilla es redireccionar el Entry Point a la primera instrucción de la misma, caso similar al que expliqué en “Moviendo el Entry Point”. Para eso, será útil LordPE y su opción de edición de este campo. 50A6 será el nuevo punto de entrada.



De esta manera estará todo preparado para que la rutina cifre la sección, con lo que introduciendo un BreakPoint en la última posición de nuestra rutina, se evitara el salto al Entry Point original, consiguiendo así, dejar la ejecución del stub parada justo al terminar la acción de cifrado.



Si vamos arriba del todo, encontraremos el inicio de la sección en la posición 10001000 completamente cifrada. La siguiente imagen muestra el antes y el después de pasar la rutina.



Una de las partes más importantes viene en este momento, pues necesitamos estar atentos para seleccionar y copiar todo el código cifrado al portapapeles. Con lo que será necesario arrastrar el ratón desde la posición 10003967 hasta la 10001000. Se realizará una copia binaria.



Si llevamos los datos copiados a un editor hexadecimal como HxD, podremos crear un archivo nuevo con el código desde el cual copiar en este formato. Después se sustituirá desde el Offset 400 hasta el 2D66 en el cual finaliza el cifrado, sobre el ejecutable con la rutina insertada pero sin cifrar. Gracias a que XOR es un algoritmo reversible, al ejecutarse el stub, este se descifrará en memoria y evitará las anteriores firmas antivirus, por las cuales el malware era detectado.



¡De esta forma habríamos cifrado un Crypter! Nada mejor para llevar a cabo cifrados de otros malware con él mismo.

Es posible incluir rutinas más interesantes, basadas en otros operadores. Por ejemplo instrucciones de rotación ROR/ROL o sumas y restas con ADD/SUB. La siguiente imagen muestra un servidor de Poison Ivy en su versión privada 2.1.4, siendo el mismo que utilizó [Zero] de elhacker.net con rutinas de cifrado y descifrado ampliadas.



Cifrado:
mov eax,401000h
xor byte ptr ds:[eax],0FF
inc eax
add byte ptr ds:[eax],020
inc eax
xor byte ptr ds:[eax],077
inc eax
ror byte ptr ds:[eax],002
inc eax
cmp eax,402690h
JNZ SHORT 0040269F        
jmp 402104h


Descifrado:
mov eax,401000h
xor byte ptr ds:[eax],0FF
inc eax
sub byte ptr ds:[eax],020
inc eax
xor byte ptr ds:[eax],077
inc eax
rol byte ptr ds:[eax],002
inc eax
cmp eax,402690h
JNZ SHORT 00402695
jmp 402104h

Saludos 4n4les! ;)

14 comentarios:

  1. excelente articulo bro una pregunta , lo puedo hacer con todas las secciones?

    el resultado ...es fud?

    ResponderEliminar
    Respuestas
    1. Solo en secciones ejecutables, con cuidado de no romper la posible IAT.

      El resultado es fud dependiendo de donde caigan las firmas, de esta manera quitarás la gran mayoría... aunque es posible que aparezcan nuevas dependiendo de la rutina que insertes, para eso revisa el post de firmas condicionales.

      Saludos! :)

      Eliminar
  2. Para cuando el siguiente curso? ;-)

    ResponderEliminar
  3. Yo lo tengo el lunes... eres alumn@ anonin@? Jejej

    ResponderEliminar
  4. Me he elido todo el post esperando ver el resultado. Pero , me has dejado con la miel en los labios, y ¡ahora me lo debes! ¿Qué tal las firmas? ¿Hay cambios? ¿Suben? ¿Bajan? ¿Cambian? (En alguna prueba de este estilo que he realizado, suelen o bien cambiar relativamente poco, o inclusive subir) Debido a que detectan el método y ya están pasados de vuelta ;).

    Un abrazo hermano. PD: ¡Me debes una cervecita!

    ResponderEliminar
    Respuestas
    1. Winsock!!!! pues no me vas a creer si te digo que no lo subí a Virustotal ni nada parecido.

      La verdad, como tenía pensado mostrar el método en un curso con los mismos ejemplos, no quería que las casas antivirus apuntasen los binarios a su catálogo de firmas jeje

      De todas formas, cifrando toda la sección e introduciendo una rutina relativamente modificada, seguro que bajan... =D

      Tenemos que quedar para unas cañitas!

      Eliminar
  5. Excelente el articulo, Gracias.

    ResponderEliminar
  6. Seria bueno que publicaras el archivo de ejemplo

    ResponderEliminar
  7. estoy aprendiendo mucho con usted maestro este articulo me ayudo

    ResponderEliminar
  8. Hola,
    He intentado hacer el tutorial que describes, aunque (soy novato) pero intento fijarme al maximo en todo para ir pasando pantallas.

    Me he bajado el crypter de Delphibasic, lo he compilado el Stub.exe me pesa 21 Kb. Te indico esto por lo que indico a continuacion, he abierto el LordPe y me quedo atascado aqui porque veo que ROffset y RSize no me coinciden con tu tutorial. Estoy haciendo algo mal ?

    te adjunto imagen
    https://postimg.org/image/ir3qne2l7/

    Tambien quisiera solicitar si es posible, algun video de tus tutoriales porque almenos en mi caso que estoy empezando me cuesta bastante seguirte debido que mis conocimientos son desde 0 absoluto de ASM no se nada, de Delphi estoy ahora mismo empezando y LordPe muy basico si pudieras hacer el tutorial mas abierto a personas de nivel basico seria mejor para ir siguiendo todo y aprender. Gracias por tu ayuda y tiempo en exponer tus conocimientos a los demas.

    ResponderEliminar
    Respuestas
    1. Vaya has llegado unos años tarde no? jeje

      No sé si estás utilizando Delphi 7 para compilar el Stub, posiblemente las configuraciones de compilado que estés utilizando dejen el código de diferente manera. No obstante no es un problema, tan solo tienes que mirar si tienes espacio suficiente al final de la sección de código ejecutable. En caso de no tenerlo puedes hacer un injerto de código como propuse en este artículo:

      http://www.enelpc.com/2014/04/injerto-de-una-shellcode-en-el-stub-de.html

      O utilizar Topo para redireccionar el Entry point a un nuevo hueco ejecutable, pero le quita un poco gracia ya que lo harías de manera automatizada y no te enterarías de lo que está sucediendo por detrás.

      Suerte, un saludo!

      Eliminar
  9. Si es Delphi 7.

    Entiendo, voy a intentarlo. Una pregunta este metodo y lo demas son funcionales? o las proactivas del AV los bloquean?

    saludos

    ResponderEliminar