# The Closed Quorum: Inside the first reported autonomous AI C2 implant

CLOSEDQUORUM is a Go Windows implant that delegates C2 decisions to a quorum of four commercial LLMs, then steals LSASS, browser, and crypto wallet credentials.

- Payout: Research
- Severity: high
- Program: Microsoft
- Write-up by: Ryan Fetterman
- Disclosed: 2026-09-22
- Write-up quality: 8/10
- Original: https://blog.talosintelligence.com/the-closed-quorum-inside-the-first-reported-autonomous-ai-c2-implant/
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-talosintelligence-com-the-closed-quorum-inside-the-first-reported-autonomous-ai-c2-implant
- Tags: area:ai domain:ai impact:data-leak impact:funds-loss kind:research platform:threat-intel sev:high tech:go tech:llm tech:windows technique:reverse-engineering technique:source-review vuln:misconfiguration vuln:secrets-leak

**Target:** Windows endpoint (Go implant binary)
**Root cause:** The implant treats commercial LLM provider APIs as its C2 infrastructure, querying up to four models (DeepSeek, Qwen, Mistral, Gemini) with a constrained JSON decision schema and executing the plurality-voted action, removing the need for an operator or dedicated C2 server.
**Steps:**
1. Binary initializes four LLM provider keys as string constants: `deepseek`, `qwen`, `mistral`, `gemini` (lines 109–116).
2. `gatherSystemInfo()` captures hostname, OS arch, CPU count, Windows version, admin status; stored as `TARGET: %s` context.
3. Loop `while (uVar16 < 4)` calls `main.queryLLM(model, prompt)` for each provider with system prompt `You are an advanced malware strategist. Provide ONLY executable decisions.`
4. Responses deserialized into Go struct with `Decision` field; `interModelDiscussion()` tallies via `map[string]int` plurality vote; ties broken by order DeepSeek > Qwen > Mistral > Gemini.
5. Winning decision routed to capability: `steal` → `lsassDump()` + `dumpBrowserCredentials()` + `extractCryptoWallets()`; `inject` → `generateShellcode()` then `injectProcess()` (process_hollow) or `earlyBirdInject()`; `persist` → `establishPersistence()`.
6. Stolen data AES-256-GCM encrypted with date-derived key, base64-encoded, split into 1,900-byte segments, posted to operator Discord webhook at 1s intervals.
7. Loop sleeps randomized 5–15 minutes and repeats; fallback decision `consensus` has no handler so it retries.
**How found:** Cisco Talos CAIRN project static analysis of a 16.4MB Go binary; Ghidra decompilation of `main.interModelDiscussion` revealed the four-provider query loop and plurality vote; DWARF symbols and embedded system prompt confirmed the decision schema.
**Exploitation:** Developer compiles a per-operator binary with the operator's Discord webhook and LLM API keys injected via -ldflags; operator handles delivery. On execution the implant waits 5 minutes, gathers host info, queries the LLM quorum, and autonomously executes steal/inject/persist actions, exfiltrating LSASS dumps, browser credentials (Chrome/Edge/Firefox), and MetaMask/Exodus/Ethereum wallets to the operator's Discord channel.
**Escalation:** Multi-provider quorum provides resilience against refusals/timeouts; deterministic tie-break biases toward DeepSeek; capability modules chain credential theft with process injection and multiple persistence mechanisms (Run key, schtasks, WMI subscription).
**Insight:** When auditing AI-integrated malware, look for unstripped Go DWARF symbols and embedded system prompts/JSON schemas — they reveal the full decision language and capability routing without dynamic execution; also check for deterministic tie-break logic that biases one provider.

## Proof of concept (copied exactly from the original report)

**Hardcoded system prompt and decision schema strings**

```
$prompt = "You are an advanced malware strategist. Provide ONLY executable decisions." ascii 
 // Binary-level: LLM decision schema 
 $schema = "decision: \"inject\"|\"persist\"|\"steal\"|\"move\"" ascii
```

