Peekaboo

July 30, 2026 · View on GitHub

img

peekaboo is a modular framework designed to safely emulate malware behavior. It allows security researchers, red teamers, and blue teamers to reproduce complex threat scenarios - including Command & Control (C2) communication, persistence mechanisms, and lateral movement - without using destructive payloads.

The goal of peekaboo is to accelerate detection engineering and operator training by providing predictable, reproducible, and safe threat artifacts.

Star History Chart

key features

  • malware source code template - build a payload/stealer from templates (select C2 channel & data collection modules).
  • payload generator - automated generation of C/C++ based payloads with built-in obfuscation (API hashing, string encryption).
  • AV/EDR bypass - encryption/encoding (syscalls)
  • multi-channel C2 - support for various covert channels:
    • standard HTTP/S
    • GitHub (abusing Issues/Commits)
    • Telegram & Discord Webhooks
    • TODO: adding all channels from one of my recent research
  • exfiltration - staged exfil to controlled endpoints (Github/Discord/Slack/VirusTotal/Azure DevOps/Angelcam).
  • evasive persistence - modular implementation of Windows persistence (Registry Run Keys, Winlogon, Screensaver).
  • lightweight dashboard - a python-based C2 backend and dashboard for real-time monitoring of active "beacons".
  • MITRE ATT&CK R&D - browse 200+ blog post techniques mapped to ATT&CK IDs with inline source code, LLM-extracted TTPs, and per-post GPU-precomputed briefs.
  • Malpedia integration - threat actor and malware family lookup with semantic blog post matching via local LLM embeddings.
  • AI assistant - direct Ollama gateway; one canned answer for "what is Peekaboo?", everything else streamed live from Ollama; no RAG, no DB lookups at chat time.
  • APT campaign pipeline - the research-to-detection spine: Malpedia actor -> threat reports -> TTP extraction -> module selection -> binary compile -> detection overlay, visualized as an interactive tactic-lane graph for campaign analysis, threat hunting, and evidence review.
  • YARA rule generator - auto-generate YARA rules from compiled binaries or uploaded samples.
  • VirusTotal scanner - submit binaries for AV detection scoring; lookup by SHA256; poll analysis results.
  • Artifact Map - 400+ ATT&CK techniques cross-referenced with 4,000+ Sigma rules; per-technique EventID coverage, registry keys, processes, command-line indicators; GPU-precomputed detection briefs per technique.
  • single-file config - all API keys and per-service knobs live in one .env file.
  • safe by design - focuses on telemetry generation rather than actual system damage.

architecture

peekaboo consists of 5 main components: First malware module - highly portable C/C++ code designed to build specific "behaviors" (for final agent binary) on the target system.

  1. crypto (malware, agent) - build-in payload encryption/decryption logic constructor for agents.
  2. injection (malware, agent) - build-in injection logic constructor for agents.
  3. persistence (malware, agent) - build-in persistence logic constructor for agents (Registry Run Key, Winlogon, Screensaver).
  4. stealer (malware, agent) - stealer logic (Telegram, GitHub, VirusTotal, Bitbucket, Azure DevOps, Angelcam).

Second, payloads module - build-in payloads.

  1. payloads - for simplicity, just messagebox and reverse shell.

Final, peekaboo.py builder in Python.

demo

Run:

python3 peekaboo.py

img


dashboard

The dashboard is a Flask-based web UI that combines C2 monitoring, malware building, threat intelligence, and AI assistance in a single interface.

cd dashboard && python3 app.py

img

img

img

img

modules

moduledescription
BuilderCompile payloads and stealers from source templates with live build log streaming
ShellcodeParse, transform, encode, analyse and reformat shellcode in 11 output formats
Module LibraryBrowse 190+ malware-research modules sourced from the meow knowledge base
SamplesUpload and manage compiled samples organized by session
APT CampaignResearch-to-detection pipeline with an interactive Campaign/Hunt/Evidence graph, compiled implementations, report evidence, and Sigma/EventID coverage + blind spots
VirusTotalSubmit binaries to VirusTotal for AV detection scoring; lookup by SHA256; poll analysis
YARAAuto-generate YARA rules from any binary (From Build, From Session, or Upload)
Artifact Map400+ ATT&CK techniques cross-referenced with 4,000+ Sigma rules; per-technique event IDs, registry, process, and cmdline artifacts; GPU-precomputed detection briefs
MITRE ATT&CKBrowse 200+ blog posts mapped to ATT&CK techniques; Extracted TTPs tab; per-post GPU briefs; inline source code viewer
MalpediaThreat actor and malware family lookup with semantic blog post matching
AI AssistantDirect Ollama gateway; instant canned answer for "what is Peekaboo?", all other questions streamed live from Ollama

GPU / CPU split

Heavy LLM generation runs once, offline, on a GPU machine via worker.py - embeddings, tags, TTP extraction, summaries, Sigma briefs, actor/family/campaign briefs. Results are stored in dashboard/peekaboo.db. Serving those precomputed results is zero-LLM: the CPU dashboard just reads the DB.

The one exception is live semantic search, which embeds the user's query at request time. That is a single lightweight vector, cached in query_embeddings (so repeated searches cost nothing), and it degrades gracefully: if Ollama is offline the dashboard keeps serving everything else and flags semantic search as paused rather than crashing. Run python worker.py status (GPU) or peekaboo status (CPU) for a readiness verdict.

GPU machine (offline, LLM)          CPU machine (dashboard, DB reads)
-----------------------------       -------------------------------------
python worker.py embed              cosine similarity search
python worker.py tag         ---->  ATT&CK badge rendering
python worker.py ttp         rsync  extracted TTP table
python worker.py summarize          post + AI assistant summaries
python worker.py sigma              artifact map + detection briefs
python worker.py apt                campaign brief per session
python worker.py actor              actor threat profile briefs
python worker.py family             malware family behavioral briefs
                            (CPU)   pipeline detection overlay
                                      Sigma / EventID coverage per TTP,
                                      derived live from the Sigma artifact map

The only runtime LLM call is the search query embed, and it is cached in the query_embeddings table - so a repeated Malpedia / semantic search costs zero Ollama round-trips, and with a warm cache the dashboard is effectively zero-LLM. If Ollama is offline the dashboard keeps serving every precomputed result and flags semantic search as paused rather than crashing. Check readiness any time with python worker.py status (GPU) or peekaboo status (CPU).

All worker.py subcommands are resumable - they use NOT IN SQL patterns to skip already-processed rows. Interrupt and re-run at any time.

WAL checkpoint before scp/rsync - SQLite runs in WAL mode, so the DB lives in two files (peekaboo.db + peekaboo.db-wal). Copying them with scp/rsync non-atomically can produce a corrupted DB on the receiving end if the WAL is mid-write. Always checkpoint first:

# on the GPU server, before copying
sqlite3 ~/hacking/peekaboo/dashboard/peekaboo.db "PRAGMA wal_checkpoint(TRUNCATE);"
scp gpu-server:~/hacking/peekaboo/dashboard/peekaboo.db dashboard/peekaboo.db

Alternatively use .backup for a guaranteed-consistent snapshot while workers are still running:

sqlite3 ~/hacking/peekaboo/dashboard/peekaboo.db ".backup /tmp/peekaboo_snapshot.db"
scp gpu-server:/tmp/peekaboo_snapshot.db dashboard/peekaboo.db

scan, init, embed, tag, ttp, summarize, sigma, apt, actor, and family catch KeyboardInterrupt and print a clean resume hint instead of a traceback:

[actor] interrupted at 47/312  (46 saved, 265 remaining)
[actor] resume: python3 worker.py actor --model qwen3:14b

img


worker.py

worker.py runs from the project root (~/hacking/peekaboo/) and enriches dashboard/peekaboo.db with embeddings, tags, TTPs, and LLM summaries.

python worker.py <subcommand> [options]

img

subcommands

subcommandstepdescription
scanCPUWalk _posts/*.markdown files and import slugs + metadata into kb_docs
initCPUImport library cache JSON into kb_docs (alternative to scan)
embedGPUCompute embedding vectors for all unembedded docs (nomic-embed-text)
tagGPU/LLMClassify each doc with constrained-JSON ATT&CK tags
ttpGPU/LLMExtract MITRE ATT&CK IDs, tactics, confidence, and rationale from source code
reportsGPU/LLMFetch Malpedia-linked HTML/PDF reports and precompute validated report TTPs for offline APT runs
summarizeGPU/LLMPrecompute one 3-sentence summary per blog post (what/how/detection)
sigmaCPU+GPUParse Sigma rules into artifact map, then precompute detection briefs per technique
aptGPU/LLMPrecompute 3-sentence campaign brief per finished pipeline session
actorGPU/LLMPrecompute threat profile brief per Malpedia actor
familyGPU/LLMPrecompute behavioral brief per Malpedia malware family
refreshallOne-shot incremental update: scan -> init -> embed -> tag -> (ttp?) -> (summarize?)
statusCPURow/pending/stale counts for all tables, plus a readiness verdict (is the DB ready to serve, is runtime Ollama needed)

scan

python worker.py scan
python worker.py scan --posts ~/hacking/meow/_posts

Walks markdown files, extracts frontmatter (title, date, category, ATT&CK IDs), finds associated source files (.c, .cpp, .nim, .asm, .s, .py), and writes data/library_cache.json. Note: results are built in memory and written atomically at the end - if interrupted, no data is saved and re-running restarts the scan from scratch (fast, CPU-only).

Ctrl+C safe - prints a clean message on interrupt. Re-run to redo the scan.

init

python worker.py init

Imports data/library_cache.json into kb_docs (idempotent upsert). Each doc is written to DB immediately, so interrupting and re-running will skip already-upserted entries.

Ctrl+C safe - each doc is upserted immediately. Press Ctrl+C at any time; re-run to resume from where it stopped.

embed

python worker.py embed
python worker.py embed --model nomic-embed-text --rebuild

Computes 768-dim embedding vectors for all docs without an embedding. Stored in kb_embeddings. Used by semantic search and Malpedia matching.

flagdefaultdescription
--modelnomic-embed-textOllama embedding model
--urlhttp://localhost:11434Ollama base URL
--batch32Docs per batch
--rebuildoffWipe existing embeddings and recompute
--watch NoffRe-run every N seconds

Ctrl+C safe - each batch is written to DB immediately. Press Ctrl+C at any time; re-run the same command to resume from where it stopped. Also exits --watch mode cleanly.

tag

python worker.py tag
python worker.py tag --model qwen3:1.7b --rebuild-changed

Asks the LLM to classify each doc with ATT&CK tactic tags (constrained JSON output). Tags are used by the chatbot RAG context and the MITRE Library filter.

flagdefaultdescription
--modelqwen3:1.7bOllama chat model
--rebuildoffWipe all tags and retag
--rebuild-changedoffOnly retag docs whose source file changed since last tag
--watch NoffRe-run every N seconds

Ctrl+C safe - each tag is written to DB immediately. Press Ctrl+C at any time; re-run the same command to resume from where it stopped. Also exits --watch mode cleanly.

ttp

python worker.py ttp
python worker.py ttp --model qwen3:14b

Reads each doc's source code file, asks the LLM to extract MITRE ATT&CK IDs with tactic, confidence (high/medium/low), and a one-sentence rationale. Results are stored in ttp_extracted and shown in the Extracted TTPs tab of the MITRE panel.

flagdefaultdescription
--modelqwen3:14bOllama chat model (use a larger model for better accuracy)
--rebuildoffWipe and redo all TTP extraction
--rebuild-changedoffOnly redo docs whose source changed

Ctrl+C safe - each result is written to DB immediately. Press Ctrl+C at any time; re-run the same command to resume from where it stopped.

reports

python worker.py reports --actor apt29
python worker.py reports --actor lazarus_group
python worker.py reports --actor turla
python worker.py reports --family win.cobalt_strike
python worker.py reports --family win.agent_tesla

Fetches Malpedia-linked threat reports for one actor/family, extracts text from HTML and PDF reports, asks the LLM for constrained JSON ATT&CK mappings, validates every ID against artifact_map, and stores evidence-backed rows in report_ttps. The APT pipeline reads these rows first, so demo actors run offline and skip live report downloads; if no precomputed rows exist, the old live regex fallback still runs.

flagdefaultdescription
--actor ID / --family ID-Malpedia subject to precompute
--modelqwen3:14bOllama chat model
--limit12Max report URLs to process
--rebuildoffWipe and redo this subject/model

summarize

python worker.py summarize
python worker.py summarize --model qwen3:14b --posts ~/hacking/meow/_posts

Reads both the blog post markdown and the associated source code for each doc, then asks the LLM to write a 3-sentence summary: what the technique does, how it works at the API/syscall level, and what defenders should look for. Summaries are stored in kb_summaries and served by:

  • The BRIEF block in the MITRE Library detail card
flagdefaultdescription
--modelqwen3:14bOllama chat model
--posts PATH$BLOG_POSTS_ROOTRoot directory of blog post markdown files
--meow-root PATH$MEOW_ROOTRoot of the meow source repo (for resolving src paths)
--rebuildoffWipe all summaries and recompute
--rebuild-changedoffOnly recompute summaries for docs whose source or markdown changed
--watch NoffRe-run every N seconds

Ctrl+C safe - each summary is written to DB immediately. Press Ctrl+C at any time; re-run the same command to resume from where it stopped. Also exits --watch mode cleanly.

sigma

# Step 1 (CPU) - parse 4,000+ Sigma rules into artifact_map
python worker.py sigma --sigma-path ~/hacking/sigma --parse-only

# Step 2 (GPU) - precompute detection briefs per technique
python worker.py sigma --model qwen3:14b

# Full rebuild (if GPU machine also has the sigma repo)
python worker.py sigma --sigma-path ~/hacking/sigma --rebuild --model qwen3:14b

malware

Step 1 (parse): Walks all .yml Sigma rule files, extracts per-technique event IDs, registry keys, process images, and command-line patterns, and stores them in artifact_map. This is the same data the dashboard "Build from Sigma Rules" button produces - but now runnable from the CLI without a browser.

Step 2 (LLM): For each technique in artifact_map, builds a detection-focused prompt (TID, name, tactic, event IDs, processes, registry keys, rule count) and asks the LLM to write a 3-sentence detection brief: what the adversary does, the most reliable telemetry to detect it, and one detection recommendation. Stored in artifact_summaries.

Briefs appear in the Overview tab of the Artifact Map technique modal with a typing animation.

flagdefaultdescription
--sigma-path PATH-Parse Sigma rules from this directory first
--parse-onlyoffOnly parse rules, skip LLM step
--modelqwen3:14bOllama chat model
--rebuildoffWipe existing LLM briefs and redo all

Ctrl+C safe - each brief is written to DB immediately. Press Ctrl+C at any time; re-run the same command to resume from where it stopped.

Typical GPU/CPU workflow:

# On CPU machine - parse rules, then copy DB to GPU
python worker.py sigma --sigma-path ~/hacking/sigma --parse-only
rsync dashboard/peekaboo.db gpu-server:~/hacking/peekaboo/dashboard/

# On GPU machine - compute briefs
python worker.py sigma --model qwen3:14b
rsync gpu-server:~/hacking/peekaboo/dashboard/peekaboo.db dashboard/

apt

python worker.py apt
python worker.py apt --model qwen3:14b --rebuild

Reads every finished (status='success') pipeline session from pipeline_sessions, builds a prompt from the session's actor ID, ATT&CK technique list, tactics, and implant modules, then asks the LLM to write a 3-sentence campaign brief:

  • Sentence 1 - who the actor is and what they targeted
  • Sentence 2 - key ATT&CK techniques and tactics used
  • Sentence 3 - highest-priority detection recommendation

Briefs are stored in session_summaries and served by /api/apt/brief/<session_id>. In the APT Campaign panel, every row in the sessions table has a [brief] button - clicking it opens the slide panel with the precomputed text and a typing animation. No LLM at render time.

flagdefaultdescription
--modelqwen3:14bOllama chat model
--urlhttp://localhost:11434Ollama base URL
--timeout120Per-call timeout (s)
--rebuildoffWipe existing session briefs and redo all

Ctrl+C safe - each brief is written to DB immediately. Press Ctrl+C at any time; re-run the same command to resume from where it stopped.

actor

python worker.py actor
python worker.py actor --model qwen3:14b --rebuild

Loads the local Malpedia actor cache (data/malpedia_actors_cache.json), fetches each actor's full profile from the API (name, country, suspected targets, victim sectors, incident type, malware families), and asks the LLM to write a 3-sentence threat actor profile:

  • Sentence 1 - who the actor is, suspected origin, and motivation
  • Sentence 2 - typical targets and known malware families
  • Sentence 3 - a behavioral signature defenders should hunt for

Briefs are stored in actor_summaries and served by /api/malpedia/actor/<id>/brief. In the Malpedia panel, the actor/family detail card shows a [brief] button inline in the title - clicking it opens the slide panel.

In the CLI malpedia sub-REPL, brief <actor-id> now auto-routes to the actor profile (or brief <slug> for KB posts, or brief <family-id> for malware families).

flagdefaultdescription
--modelqwen3:14bOllama chat model
--urlhttp://localhost:11434Ollama base URL
--timeout120Per-call timeout (s)
--rebuildoffWipe existing actor briefs and redo all

Ctrl+C safe - each brief is written to DB immediately. Press Ctrl+C at any time; re-run the same command to resume from where it stopped.

Prerequisite: Malpedia actor list must be cached first. Run the Malpedia panel in the dashboard (actors tab) or call list_actors() from the malpedia module once.

family

python worker.py family
python worker.py family --model qwen3:14b --rebuild

Same flow as actor but for malware families. Fetches each family's description, alt-names, and attribution from the Malpedia API, then generates a 3-sentence behavioral brief:

  • Sentence 1 - what the malware does and its primary capabilities
  • Sentence 2 - how it persists, evades, or moves laterally
  • Sentence 3 - most actionable detection or hunting recommendation

Briefs are stored in family_summaries and served by /api/malpedia/family/<id>/brief.

flagdefaultdescription
--modelqwen3:14bOllama chat model
--urlhttp://localhost:11434Ollama base URL
--timeout120Per-call timeout (s)
--rebuildoffWipe existing family briefs and redo all

Ctrl+C safe - each brief is written to DB immediately. Press Ctrl+C at any time; re-run the same command to resume from where it stopped.

Prerequisite: Malpedia family list must be cached first. Same as actor.

refresh

python worker.py refresh
python worker.py refresh --scan --ttp --summarize --meow-root ~/hacking/meow

One-shot incremental pipeline: runs scan (optional) -> init -> embed -> tag -> ttp (optional) -> summarize (optional). Skips already-processed rows in every step.

flagdefaultdescription
--scanoffRe-scan local _posts/ before init
--rebuildoffWipe embeddings + tags first
--ttpoffAlso run TTP extraction
--summarizeoffAlso run summary precompute
--ttp-modelqwen3:14bModel for TTP extraction
--sum-modelqwen3:14bModel for summarization

status

python worker.py status

Shows row counts and pending/stale counts for all enrichment tables, followed by a readiness verdict - a one-glance answer to "is this DB ready to serve a CPU dashboard, and is Ollama needed at runtime?":

kb_docs        : 309
kb_embeddings  : 309  (nomic-embed-text)  pending: 0
kb_tags        : 309  (qwen3:14b)         pending: 0, stale: 0
ttp_extracted  : 276  (qwen3:14b)         pending: 0, stale: 0
kb_summaries   : 309  (qwen3:14b)         pending: 0, stale: 0
artifact_summ  : 410  (qwen3:14b)         pending: 0
actor_summ     : 979  (qwen3:14b)
family_summ    : 3704 (qwen3:14b)

readiness
  ✔ docs indexed         309
  ✔ embeddings ready     309/309
  ✔ summaries ready      309/309
  ✔ artifact briefs      410/410
  ✔ actor briefs         979
  ✔ family briefs        3704
  runtime Ollama needed for LIVE semantic search (query embedding); precomputed briefs need none.

The same verdict is available on the CPU box after copying the DB with peekaboo status.


configuration (.env)

All API keys, credentials, and per-service knobs live in a single .env file at the project root.

cp .env.example .env
$EDITOR .env   # fill in real tokens
groupexample variables
AI: OllamaOLLAMA_BASE_URL, OLLAMA_MODEL, OLLAMA_NUM_CTX
Threat IntelMALPEDIA_API_TOKEN, VT_API_KEY
Stealer / C2TELEGRAM_BOT_TOKEN, GITHUB_TOKEN, BITBUCKET_TOKEN_BASE64, SLACK_WEBHOOK_URL, AZURE_PAT, ANGELCAM_API_KEY
APT PipelineAPT_PIPELINE_COMPILE_EACH, APT_PIPELINE_OLLAMA_NARRATION, APT_PIPELINE_OLLAMA_MODEL
PathsMEOW_ROOT, BLOG_POSTS_ROOT

.env is gitignored. .env.example is the redacted template.


dashboard panels

Builder

Select malware type (injection or stealer), injection technique, encryption algorithm, payload, stealer channel, and persistence method. Build output streams live to the UI. On success, the compiled binary and persistence binary (if enabled) are available for immediate download.

Build History

Every build is persisted to SQLite. The history table shows build ID, status badge, module/stealer name, compiler options, timestamp, and download links.

Samples / Sessions

Upload binary samples captured during red team exercises. Each session groups files by actor/host, stores upload time, and provides direct download links.

YARA Rule Generator

Auto-generates YARA rules from a binary using string extraction, section name heuristics, import pattern matching, and entropy thresholds.

img

  • From Build - select any compiled build binary
  • From Session - select a captured sample
  • Upload - drag-and-drop any PE file

VirusTotal Scanner

Submit binaries directly to VirusTotal. Features: upload, From Build, From Session, SHA256 lookup, and poll for pending analysis.

img

img

MITRE ATT&CK R&D

The MITRE ATT&CK tab has four sub-tabs:

Techniques - ATT&CK technique browser grouped by tactic; click any technique to see matched blog posts.

Technique Library - all 200+ blog posts indexed from the meow research repository, mapped to ATT&CK IDs.

Filter by category (injection, persistence, evasion, cryptography, linux, macos, etc.)
Each row has a [brief] button - click to show the GPU-precomputed 3-sentence summary inline, without opening the full detail card
Click any row to expand the full detail card with inline source code (C, C++, Nim, assembly), blog post link, and BRIEF block (GPU summary with typing animation)

TTP Implementations - blog posts indexed by extracted ATT&CK ID with tactic, platform, and blog link. The ttp_implementations table is seeded automatically at dashboard startup from the static implementation list in mitre.py (no manual step required). Filter by tactic, platform, or keyword; click any ATT&CK ID badge to open a detection brief.

img

Extracted TTPs - LLM-inferred ATT&CK mappings per blog post: technique ID, tactic, confidence level, and rationale. Populated by worker.py ttp.

img

Malpedia integration

The Malpedia tab connects to the Malpedia REST API to browse threat actors and malware families. For each actor or family, related blog posts are matched using semantic similarity - the actor/family description is embedded via nomic-embed-text, then cosine-ranked against all cached post embeddings.

img

Search actors by name, country, or malware family
Expand any actor/family to see techniques, aliases, and semantically matched blog posts with similarity score
Each actor/family detail card has a [brief] button in the title - shows the GPU-precomputed threat profile or behavioral brief in the slide panel (no LLM at render time; requires worker.py actor / worker.py family)
Each related blog post row has a [brief] button -> KB summary from worker.py summarize
Requires a Malpedia API key in .env (MALPEDIA_API_TOKEN)

APT campaign pipeline

This is the spine of peekaboo - a single research-to-detection pipeline that the rest of the modules feed into:

Malpedia actor -> threat reports -> TTPs -> local modules -> build sample -> detection overlay (Sigma / EventIDs / YARA / VT)

It does not stop at "here is the malware." Every session ends as a purple-team artifact: the simulated attack chain plus what a defender should expect to see for each stage, plus the blind spots where no detection exists.

img

img

img

#StageWhat it does
1Malpedia FetchResolves actor/family ID, retrieves metadata
2Report SourceUses GPU-precomputed report TTPs from report_ttps when present; otherwise downloads linked reports as fallback
3TTP ExtractionUses validated precomputed HTML/PDF report mappings when present; otherwise falls back to local regex/name matching
4Module SelectionWeighted random pick per TTP from top-5 candidates (see below)
5Binary CompileBuilds a Windows PE ready for EDR testing
6Detection OverlayCross-references each TTP against the Artifact Map -> expected Sigma rules, Windows EventIDs, registry keys, processes, cmdline indicators; flags TTPs with no coverage as blind spots (no LLM, pure DB join)

img

All progress streams live to the UI. Every session is persisted to SQLite and can be inspected through Graph, Reports, TTPs, Detection, and Binary tabs.

Interactive campaign graph

The Graph tab is the default view for a completed session. It builds a deterministic threat path directly from the session data already stored in peekaboo.db; rendering requires no LLM call or network access. ATT&CK tactics are shown as lanes, stages are connected in execution order, and selecting a stage highlights the path leading to it while opening the related intelligence in a compact detail panel.

ModeFocus
CampaignActor-to-stage kill chain grouped by ATT&CK tactic
HuntPurple-team overlay with per-stage Sigma counts, EventIDs, coverage, and blind spots
EvidenceReport -> ATT&CK stage -> blog implementation / compiled source and binary relationships

The detail panel keeps the evidence quote, source report, matching blog implementation, compiler/platform metadata, downloadable artifacts, Sigma rules, and EventIDs together. The graph supports stage navigation, zoom/pan, fit-to-view, a short deterministic replay, reduced-motion preferences, responsive mobile layout, and fullscreen presentation mode. Cytoscape.js is vendored locally with the dashboard, so the visualization remains available during an offline demo.

img

Detection overlay (purple-team hunt sheet)

Step 6 turns the attack chain into a defender-facing artifact. For every kill-chain stage, agent_detection_overlay() (pipeline/apt_pipeline.py) joins the stage's ATT&CK ID against the precomputed Artifact Map (400+ techniques x 4,000+ Sigma rules) and attaches, per stage, the Sigma rules, Windows EventIDs, registry keys, processes, and command-line indicators a blue team should hunt for. The session manifest.json gains a detection rollup:

  • coverage % - how many stages have any detection at all
  • unique Sigma rules / EventIDs across the whole chain
  • gaps - the TTPs in this chain with zero Sigma coverage, i.e. the blind spots

This is pure DB cross-reference - no LLM, no network - so it runs in the same sub-minute pass as the source-only build.

Closing the loop. A blind-spot stage that also produced a compiled binary (compile_each: true) gets a starter YARA rule auto-generated from that binary (hunt_<ttp>_stage<NN>.yar, written into the session dir and listed in manifest.json). So a detection gap doesn't just get flagged - it ships with a first-draft detection. Source-only gaps get a hint to compile.

Inspect any session from the terminal - frameless, ASCII, colored:

peekaboo pipeline list                 # every campaign + coverage bar + gaps
peekaboo pipeline show <session_id>    # per-stage hunt sheet: Sigma / EventIDs / blind spots / generated YARA
peekaboo status                        # readiness: indexed data + whether Ollama is needed

Each session row in the history table has a [brief] button - shows a GPU-precomputed 3-sentence campaign brief (actor, techniques used, detection priority) in the slide panel. No LLM at render time; requires worker.py apt.

Module selection strategy

Running the same actor twice produces a different kill chain each time. This is intentional - the goal is detection coverage breadth, not reproducibility.

pipeline/apt_pipeline.py -> agent_select_modules() uses a three-layer scoring mechanism:

Base score (deterministic, tactic alignment):

SignalPoints
Module category maps to TTP tactic+5
Windows platform (primary demo target)+1
Has associated blog post+1

Sophistication score (metadata-driven, no per-module allowlist):

SignalPoints
Blog series suffix, e.g. malware-injection-21up to +3.6
Advanced title markers such as syscall, undocumented, Native API, KernelCallbackTable, ZwQueueApcThread, callback, thread hijacking+1.8

This biases shared ATT&CK buckets such as T1055 toward the more interesting blog examples (malware-injection-21, malware-injection-15, malware-injection-14, etc.) instead of repeatedly picking the introductory injection-1 / injection-2 posts.

Session deduplication (hard constraint):

-10 if the module's source file was already selected in this session -> guarantees no two stages compile the same .c/.cpp/.nim file

Cross-session rotation (soft pressure):

-3 if the module ID appeared in any of the last 10 pipeline sessions -> naturally rotates through the library across repeated runs of the same actor

Jitter (variety):

+[0, 2) uniform random added to every candidate score -> breaks ties and ensures even equal-scoring modules vary across runs

The top-5 candidates by adjusted score are then passed to random.choices() with weights proportional to (score - min + 1). Quality still wins most of the time, but lower-ranked alternatives get a real shot (~20-40% depending on score gaps).

Result: same actor, same extracted TTPs, different malware assembly every run - wider technique coverage for blue team detection tuning.

Artifact Map

Cross-references 400+ ATT&CK techniques with 4,000+ Sigma detection rules. For each technique, the map extracts:

Windows event IDs (Sysmon + Security)
Registry key patterns
Process image names
Command-line indicators
Logsource categories

img

Building the map:

Option A - browser: open the Artifact Map panel -> click ⚙ Build from Sigma Rules. Progress streams live.

Option B - CLI (recommended for GPU workflows):

python worker.py sigma --sigma-path ~/hacking/sigma --parse-only

Detection briefs: after building the map, run worker.py sigma on the GPU to precompute a detection-focused 3-sentence brief per technique. Briefs appear in the Overview tab of each technique's modal with a typing animation - no LLM call at render time.

AI assistant

Direct Ollama gateway for technical malware research questions.

img

How responses work:

"what is Peekaboo?" - instant canned answer; no LLM call.
everything else - streamed directly from Ollama /api/chat; no RAG, no DB lookups.

provider: configure via OLLAMA_BASE_URL, OLLAMA_MODEL, and OLLAMA_BEARER_TOKEN in .env.

Recommended and tested: qwen25-coder-offensive:v1-q8


CLI (peekaboo_cli.py)

Peekaboo has two terminal interfaces backed by the same SQLite data and dashboard modules:

  • TUI mode: running peekaboo in an interactive terminal opens the full-screen application.
  • Classic mode: subcommands keep stable, pipe-friendly output for scripts and automation.

The TUI provides nine navigable workspaces: Overview, APT Campaigns, Research Library, MITRE ATT&CK, Detection, Threat Intel, Build History, Samples, and Toolkit. It uses the dashboard's purple palette and includes live AND-search, compact and wide layouts, record drill-down, a full-screen Monokai source viewer, the AI assistant, confirmed local module builds, and YARA generation from build history.

peekaboo terminal application

Install the peekaboo entry point in an isolated environment:

python3 -m venv .venv
.venv/bin/python -m pip install -e .
.venv/bin/peekaboo

Launch a specific workspace directly:

.venv/bin/peekaboo tui --view campaigns
.venv/bin/peekaboo tui --view detection

TUI navigation follows the keyboard-first model used by focused terminal tools:

keyaction
1...9Switch workspace
[ / ]Previous / next workspace
/Live search in the current workspace
arrows or j / kMove through records
enterOpen full record detail
g / GFirst / last record
sOpen source for a Research Library or ATT&CK implementation
aOpen the AI assistant
bBuild the selected Research Library module after confirmation
yGenerate YARA for the selected build
oOpen the selected public report or blog URL
rReload local data
?Keyboard reference
qQuit

The source viewer reads the complete local file when available, falls back to the cached snippet, and uses Monokai highlighting with line numbers and two-axis keyboard scrolling.

peekaboo TUI Monokai source viewer

Direct classic execution remains supported. When stdout is redirected or captured, a bare invocation prints the classic home instead of trying to open a TUI:

python3 peekaboo_cli.py examples
python3 peekaboo_cli.py pipeline list

peekaboo CLI home

Use examples for the common workflows:

python3 peekaboo_cli.py examples

peekaboo CLI examples

Global flags work before or after a command:

python3 peekaboo_cli.py --help
python3 peekaboo_cli.py --version
peekaboo artifacts stats --json          # raw JSON, no Rich formatting
peekaboo --color never pipeline list     # auto, always, or never
peekaboo --offline search injection      # hard network-disable switch
peekaboo --db /path/to/peekaboo.db doctor

Quick workflows:

# Local readiness and cross-domain search
peekaboo doctor --demo
peekaboo search "process injection"

# Campaign intelligence
peekaboo pipeline list
peekaboo pipeline show <session> --view campaign
peekaboo pipeline show <session> --view hunt
peekaboo pipeline show <session> --view evidence
peekaboo pipeline diff <session-a> <session-b>
peekaboo pipeline export <session> --format navigator -o campaign.json
peekaboo pipeline export <session> --format markdown -o campaign.md

# Malpedia threat intelligence
peekaboo malpedia search lazarus
peekaboo malpedia actor lazarus_group
peekaboo malpedia reports --limit 10

# ATT&CK implementations and detection coverage
peekaboo ttp search "process injection"
peekaboo ttp show T1055
peekaboo artifacts show T1055
peekaboo artifacts rules T1059.001 --level high

# Research library
peekaboo library list --category injection
peekaboo library show malware-injection-17

# Local shellcode and build workflows
peekaboo shellcode analyse payload.bin
peekaboo shellcode convert payload.bin --to python --transform xor_key --xor-key 0x41
peekaboo builder build malware-injection-17
peekaboo yara gen-build <build-id> --save /tmp/rule.yar

# Upload is explicit; non-interactive VT uploads require --yes
peekaboo vtscan scan <build-id> --yes
peekaboo vtscan lookup <sha256>

Malpedia search returns matching actors/families and gives direct next steps:

peekaboo Malpedia search

ATT&CK TTP detail links techniques back to local buildable research modules:

peekaboo ATT&CK TTP show

Detection artifacts expose ATT&CK-to-Sigma coverage and severity filtering:

peekaboo detection artifact rules

The research library remains browsable from the terminal:

peekaboo library list

library show renders full source code with Rich/Pygments syntax highlighting, line numbers, indentation guides, and language detection for C/C++, Rust, Python, Assembly, Nim, Go, shell, YARA, and other Pygments-supported languages.

peekaboo library source highlighting

peekaboo library source highlighting

Command groups:

commanddescription
examplesShow common workflows
statusReadiness verdict: indexed data + whether runtime Ollama is needed
tuiLaunch the full-screen terminal application, optionally at a named workspace
doctorRead-only SQLite, demo filesystem, report/blog linkage, and toolchain verification
searchUnified local search across techniques, modules, artifacts, campaigns, actors, and families
pipelineCampaign/Hunt/Evidence views, session diff, and Navigator/Markdown export
libraryBrowse/search research modules and source code
malpediaThreat actors, malware families, reports, and Malpedia YARA
ttpMITRE ATT&CK techniques mapped to local implementations
artifactsATT&CK x Sigma coverage, EventIDs, registry/process/cmdline artifacts
builderList/build compilable research modules and inspect build history
yaraGenerate YARA rules from files or build outputs
vtscanUpload binaries, poll analyses, and lookup VirusTotal reports
shellcodeAnalyse binary/text payloads and convert them through 11 formats and 7 transforms

Notes:

  • --json writes machine-readable JSON directly to stdout; errors use stderr.
  • --offline blocks Malpedia detail/report downloads and all VirusTotal operations. Cached Malpedia IDs, briefs, database search, campaign views, builds, YARA, and shellcode remain local.
  • TUI browsing is local and database-driven. In --offline mode, the AI assistant allows its built-in Peekaboo answer but blocks live Ollama requests.
  • --color auto is the default and respects non-TTY output and NO_COLOR; use always only when recording ANSI intentionally.
  • Session IDs accept an unambiguous prefix. Export writes atomically when --output is used.
  • VirusTotal uploads ask for confirmation and require --yes in scripts.

Attention

This tool is a Proof of Concept and is for Educational Purposes Only!!! Author takes no responsibility of any damage you cause

License

MIT