SharpPick o cómo ejecutar código de PowerShell a través de ensamblados .NET

Algunas veces entramos en un sistema y nos encontramos con la siguiente sorpresita:

Si, el dichoso AppLocker nos bloquea el acceso a powershell.exe... 

Pero no decaigas amigo atacante, todavía hay formas de ejecutar comandos en PowerShell. ¿Cómo? Pues simplemente creando un ejecutable que implemente funciones de System.Management.Automation.dll.

Empezamos con el viejo SharpPick, que podemos encontrar en el proyecto PowerShellEmpire, y que con sólo unas pocas líneas de código nos permite ejecutar powershell a través de .NET assemblies.

Si echáis un vistazo a la función RunPS es superbásico pero eficaz. Primero inicializa un RunspaceInvoker y un Pipeline, como se muestra a continuación:

Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
Luego agrega la entrada del usuario como argumento, llama al método Invoke y guarda la salida en una colección PSObject:
pipeline.Commands.AddScript(cmd);
pipeline.Commands.Add("Out-String");
Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
Finalmente, la función itera a través de la colección PSObject, agrega los resultados a un objeto StringBuilder y devuelve la cadena resultante:
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
   stringBuilder.Append(obj);
}
return stringBuilder.ToString().Trim();
Ahora para usarlo simplemente tenemos que compilarlo con MSBuild:
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe SharpPick.csproj

Para probarlo preparamos por ejemplo un script prueba.ps1 con :

Get-Module -ListAvailable | Select -Property Name | Out-File C:\Users\vis0r\Desktop\Modules.txt
Llamamos al script y ya lo tenemos
SharpPick.exe -f script.ps1

¿Fácil verdad? Pues otra forma cocinada por nosotros mediante la instancia Powershell sería la siguiente:

  1. Agrega una referencia a System.Management.Automation.dll en tu proyecto.
  2. Crea una instancia de PowerShell utilizando la clase PowerShell del espacio de nombres System.Management.Automation.
  3. Agrega los comandos de PowerShell que deseas ejecutar utilizando el método AddCommand de la instancia de PowerShell.
  4. Ejecuta los comandos de PowerShell utilizando el método Invoke de la instancia de PowerShell.

Finalmente, te muestro un ejemplo de cómo ejecutar el comando Get-ChildItem (equivalente al comando dir en la línea de comandos) utilizando el siguiente código:

using System;
using System.Management.Automation;

class Program
{
    static void Main(string[] args)
    {
        // Crear una instancia de PowerShell
        PowerShell ps = PowerShell.Create();

        // Agregar el comando Get-ChildItem
        ps.AddCommand("Get-ChildItem");

        // Ejecutar el comando y obtener los resultados
        var results = ps.Invoke();

        // Imprimir los resultados
        foreach (var result in results)
        {
            Console.WriteLine(result.ToString());
        }
    }
}


Comentarios