Post Explotation Backdooring I

Hace unos meses estuve en un curso de postexplotación impartido por mi ex compañero de trabajo OscarAkaElvis (creador de la herramienta para auditar redes wifi Airgeddon, la cual te recomiendo que pruebes). De él aprendí todo lo que te voy a mostrar a continuación, así que todo el mérito de este post y de los siguientes de esta serie es suyo.

También quiero avisar de que esta es una técnica avanzada y necesitas tener conocimientos básicos de ensamblador y reversing. Si no los tienes, te recomiendo los cursos de Pentester Academy «x86 Assembly Language and Shellcoding on Linux» y «Reverse Engineering Win32 Applications«.

En esta entrada te voy a mostrar como es posible convertir un exe en un troyano, modificando su código para que ejecute una terminal remota. Para ello empezaremos por la forma más sencilla de hacerlo, pero también la más detectable por los antivirus: el método «Code Cave«.

El proceso que voy a seguir es el siguiente: en primer lugar, cogeré un programa ejecutable benigno. A continuación, aumentaré el espacio que ocupa el programa para crear una «cueva de código» vacía. Después, insertaré código en ensamblador que ejecuta una shell reversa en esta nueva sección. Por último, haré que el código del programa pase por esta nueva sección cuando se ejecute, y después continúe su flujo normal. De esa forma consigo una reverse shell sin que el usuario note nada raro.

Crear la cueva de código

Antes de empezar, lo primero es desactivar el antivirus. Te recomiendo que crees una máquina virtual como entorno de trabajo con un windows 7, por ejemplo, o con alguna versión de windows 10 algo antigua, puesto que a partir de la actualización 1809 windows da problemas al crear el archivo.

Lo primero es elegir un archivo sobre el que haremos la modificación. Éste método solo funciona en archivos de 32 bits. También te tienes que asegurar de que los archivos no tengan protección DEP (Data Execution Prevention) ni ASLR (Address Space Layout Randomisation). Esto es porque son medidas de seguridad que previenen que la aplicación ejecute instrucciones en zonas de la memoria no permitidas y que introducen aleatoriedad en las direcciones de memoria. Podemos comprobar si un programa tiene estas medidas de seguridad con la herramienta de PowerShell PESecurity.

 Para este ejemplo voy a utilizar el ejecutable de la herramienta 7zip, 7zfm.exe, descargado de la página oficial.

Abre el exe con un editor de ejecutables. En mi caso he utilizado LordPe. Pulsa en PE Editor y selecciona el ejecutable. Esto es válido solo para ejecutables de 32 bits.

Post Explotation Backdooring I

Pulsa en Sections. Click derecho, «Add Section Header» Le pones un nombre, por ejemplo .lethani (acuérdate de que nombre le pones, lo necesitarás saber más adelante) y le añades una cueva de código suficiente para que nos quepa la shell. Con 1000 bytes nos valdrá, lo indicamos en «Virtual Size» y en «Raw Size».

Si lo probamos ahora, el programa no se abre, puesto que le estamos diciendo que tiene 1000 bytes más de los que tiene en realidad. Hemos aumentado su tamaño indicándoselo en la cabecera, pero ahora tenemos que aumentar su tamaño realmente. Para ello he utilizado la herramienta HxD. Abre el archivo, haz Ctrl + Fin para ir al final del mismo, y allí pulsa en Edicion -> insertar bytes. Tenemos que insertar 1000 bytes, los insertamos con valor 00.

Insertar la Reverse Shell

Si pruebas a abrir el ejecutable, se abrirá sin problemas y seguirá el flujo normal del programa. Ahora vamos a utilizar este nuevo espacio que hemos creado para insertar el payload. Para ello puedes utilizar la herramienta Immunity Debugger. Desde este programa, abre el ejecutable 7zip.exe. Tienes que buscar la cueva de código que has credo. Pulsa la m para abrir el memory map, y fijate en la posición de memoria que tiene la cueva de código que has creado, que en este caso se llama .lethani.

Apúntate la dirección de memoria de esta sección. En mi caso está en la 0047E000. Ahora pulsa el botón de Run program (►), y te llevará a la primera línea de código del programa. Copia en un txt las primeras instrucciones del programa, porque vamos a modificarlas y después necesitarás saber cuáles eran.

004538D8 >/$ 55             PUSH EBP

004538D9  |. 8BEC           MOV EBP,ESP

004538DB  |. 6A FF          PUSH -1

004538DD  |. 68 280D4600    PUSH 7zFM.00460D28

004538E2  |. 68 D2384500    PUSH <JMP.&MSVCRT._except_handler3>      ;  SE handler installation

004538E7  |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]

La primera instrucción es la primera que va a ejecutar el programa, por eso vamos a modificarla. En vez de hacer un push ebp, voy a hacer un salto (jmp) a la dirección de código de nuestra code cave. Para ello sitúate sobre la instrucción y pulsa espacio. Escribe JMP 0047E000, y lo primero que hará el programa es saltar a la cueva de código. Sin embargo, al insertar esta instrucción, es posible que las instrucciones de abajo también se hayan modificado:

Si nos fijamos bien, vemos que la instrucción de JMP no solo ha modificado la instrucción PUSH EBP, sino que también ha eliminado las instrucciones MOV EBP, ESP y PUSH -1. Esto se debe a que la instrucción de salto ocupa más espacio y las ha sobreescrito. Más tarde arreglaremos esto. Ahora vamos a ir a nuestra cueva de código. Pero antes, guarda lo que has hecho seleccionando la instrucción del JMP y haciendo clic derecho, copy to executable, y se te abrirá una ventana donde tendrás que seleccionar el ejecutable.  

Para saltar a la cueva de código, pulsa CTRL + G y ve a la dirección de memoria 0047E000Lo primero que hay que hacer en la code cave es guardar el valor de los registros. Esto lo conseguimos añadiendo las instrucciones PUSHAD y PUSHFD. Para escribir una instrucción te sitúas en la dirección de memoria deseada y pulsas espacio.

Llega el momento de generar la shell. Para ello utilizaré msfvenom:

Este es un payload para windows encodeado en hexadecimal que cuando se ejecute lanzará una reverse shell a la ip atacante (en este caso 192.168.1.156) al puerto 1234. Cópialo en el portapapeles.  Para pegarlo en Immunity Debugger, tenemos que seleccionar un buen conjunto de instrucciones de nuestra cueva de código,  bajo los dos push que hemos hecho, hacermos click derecho y pulsamos binary -> binary paste.

Al final nos quedará algo así:

Sin embargo, este payload no es válido tal y como está. Hay dos problemas que debemos solucionar. En primer lugar el último CALL EBP hace que el programa se termine tras ejecutar la reverse shell. Queremos que el programa continúe, para que el usuario no se de cuenta. Por ello, eliminamos CALL EBP y ponemos en su lugar un NOP, la instrucción en ensamblador que no hace nada 

En segundo lugar, el payload de la shell en un momento dado toma un parámetro, y espera ese tiempo en milisegundos antes de iniciar otro hilo en el proceso. Pero el parámetro que está recibiendo es -1, lo que equivale a esperar infinitos segundos. Para solucionar esto, ponemos dos NOP en las instrucciones DEC ESI y PUSH ESI:

Ahora tenemos que alinear la pila, es decir, ver que valores tiene antes de que ejecute el código malicioso y poner los mismos después, para que quede todo intacto. Para ello tenemos que debuggear el programa poniendo breakpoints para ver que valor tiene el ESP antes y después de la shell, y hacer la resta para saber cuánto ha variado la pila y volver a dejarla como estaba. En primer lugar, pon tu máquina atacante a la escucha con el comando nc -lvnp 1234, para que la shell se pueda conectar y el programa no se rompa. A continuación, ve a la primera y última instrucción de la shell («CLD» y el «NOP» que pusimos, respectivamente)y pon breakpoints con F2. Haz caso omiso del warning que aparece. Le damos al play y cogemos el valor del ESP en ese momento (lo puedes encontrar a la derecha). 

Después, volvemos a darle al play y, si hemos creado todo bien, se nos habrá creado una shell. Hacemos un exit en la shell, y el programa se parará en el siguiente breakpoint. Cogemos el valor del ESP al final. 

En mi caso el valor inicial es de 0019FF60 y el valor final 0019FD60La diferencia de la resta es 200 (lo podemos calcular con cualquier calculadora hexadecimal).Por tanto, añadimos justo debajo del NOP la instrucción «ADD ESP, 200«. 

Lo siguiente es volver a dejar como estaban los valores del registro, con «POPFD» y «POPAD». 

Después añadimos las instrucciones que se rompieron al pegar el JMP, que en mi caso son «PUSH EBP», «MOV EBP, ESP» y «PUSH -1». Las apuntamos en un txt en los primeros pasos. 

Y por último, hay que hacer un salto al código principal del programa, a la siguiente dirección tras el JMP, que en mi caso es la dirección 004538DD.

Así es como quedaría la parte final de la code cave:

Listo. Volvemos a seleccionar todo el código para guardar los cambios, clic derecho, copy to executable, clic derecho de nuevo, save file.

Si ejecutamos el exe, se abrirá una shell en la máquina atacante.

No obstante, este método es muy provocativo, y lo detectan muchos antivirus. Es raro que haya un salto a otra parte del código en el inicio del programa (si en un programa real se necesita desde el principio saltar a otra parte del código, por que no empezar directamente en ese otro lado?), y haber añadido una nueva sección al programa también es muy llamativo para los antivirus.

Estos problemas se solucionarán en el próximo post, que puedes consultar aquí.

Lethani.

4.3/5 - (129 votos)

1 comentario en «Post Explotation Backdooring I»

Deja un comentario