shadowcat 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- shadowcat-2.0.0/.env.example +35 -0
- shadowcat-2.0.0/.gitignore +151 -0
- shadowcat-2.0.0/.gitmodules +3 -0
- shadowcat-2.0.0/CLAUDE.md +162 -0
- shadowcat-2.0.0/Dockerfile +101 -0
- shadowcat-2.0.0/LEARNING.md +61 -0
- shadowcat-2.0.0/LICENSE.md +21 -0
- shadowcat-2.0.0/Makefile +292 -0
- shadowcat-2.0.0/PKG-INFO +360 -0
- shadowcat-2.0.0/README.md +322 -0
- shadowcat-2.0.0/agent/__init__.py +17 -0
- shadowcat-2.0.0/agent/benchmark/__init__.py +11 -0
- shadowcat-2.0.0/agent/benchmark/cli.py +179 -0
- shadowcat-2.0.0/agent/benchmark/config.py +15 -0
- shadowcat-2.0.0/agent/benchmark/docker.py +192 -0
- shadowcat-2.0.0/agent/benchmark/registry.py +99 -0
- shadowcat-2.0.0/agent/core/__init__.py +0 -0
- shadowcat-2.0.0/agent/core/agent.py +362 -0
- shadowcat-2.0.0/agent/core/backend.py +1667 -0
- shadowcat-2.0.0/agent/core/config.py +106 -0
- shadowcat-2.0.0/agent/core/controller.py +638 -0
- shadowcat-2.0.0/agent/core/events.py +177 -0
- shadowcat-2.0.0/agent/core/langfuse.py +320 -0
- shadowcat-2.0.0/agent/core/phantom.py +2327 -0
- shadowcat-2.0.0/agent/core/planner.py +493 -0
- shadowcat-2.0.0/agent/core/profiling.py +58 -0
- shadowcat-2.0.0/agent/core/sanitizer.py +104 -0
- shadowcat-2.0.0/agent/core/session.py +228 -0
- shadowcat-2.0.0/agent/core/tracer.py +137 -0
- shadowcat-2.0.0/agent/interface/__init__.py +0 -0
- shadowcat-2.0.0/agent/interface/components/__init__.py +0 -0
- shadowcat-2.0.0/agent/interface/components/activity_feed.py +202 -0
- shadowcat-2.0.0/agent/interface/components/renderers.py +149 -0
- shadowcat-2.0.0/agent/interface/components/splash.py +112 -0
- shadowcat-2.0.0/agent/interface/main.py +1126 -0
- shadowcat-2.0.0/agent/interface/styles.tcss +421 -0
- shadowcat-2.0.0/agent/interface/tui.py +508 -0
- shadowcat-2.0.0/agent/parsing/html_distiller.py +230 -0
- shadowcat-2.0.0/agent/parsing/tool_parser.py +115 -0
- shadowcat-2.0.0/agent/prompts/__init__.py +0 -0
- shadowcat-2.0.0/agent/prompts/pentesting.py +238 -0
- shadowcat-2.0.0/agent/rag_module/knowledge_base.py +116 -0
- shadowcat-2.0.0/agent/tests/benchmark_phantom.py +455 -0
- shadowcat-2.0.0/agent/tools/__init__.py +14 -0
- shadowcat-2.0.0/agent/tools/base.py +99 -0
- shadowcat-2.0.0/agent/tools/executor.py +345 -0
- shadowcat-2.0.0/agent/tools/registry.py +47 -0
- shadowcat-2.0.0/backend/README.md +244 -0
- shadowcat-2.0.0/backend/__init__.py +10 -0
- shadowcat-2.0.0/backend/api/__init__.py +1 -0
- shadowcat-2.0.0/backend/api/routes_scan.py +932 -0
- shadowcat-2.0.0/backend/authz.py +75 -0
- shadowcat-2.0.0/backend/cli.py +261 -0
- shadowcat-2.0.0/backend/compliance/__init__.py +1 -0
- shadowcat-2.0.0/backend/compliance/pdpa_mapping.py +16 -0
- shadowcat-2.0.0/backend/core/__init__.py +1 -0
- shadowcat-2.0.0/backend/core/coverage.py +93 -0
- shadowcat-2.0.0/backend/core/events.py +166 -0
- shadowcat-2.0.0/backend/core/llm_client.py +614 -0
- shadowcat-2.0.0/backend/core/orchestrator.py +402 -0
- shadowcat-2.0.0/backend/core/scan_memory.py +236 -0
- shadowcat-2.0.0/backend/crawler/__init__.py +1 -0
- shadowcat-2.0.0/backend/crawler/csrf.py +75 -0
- shadowcat-2.0.0/backend/crawler/headless.py +232 -0
- shadowcat-2.0.0/backend/crawler/js_analyzer.py +133 -0
- shadowcat-2.0.0/backend/crawler/spider.py +550 -0
- shadowcat-2.0.0/backend/crawler/subdomains.py +279 -0
- shadowcat-2.0.0/backend/daemon.py +252 -0
- shadowcat-2.0.0/backend/db/README.md +86 -0
- shadowcat-2.0.0/backend/db/__init__.py +17 -0
- shadowcat-2.0.0/backend/db/engine.py +87 -0
- shadowcat-2.0.0/backend/db/models.py +206 -0
- shadowcat-2.0.0/backend/db/repository.py +316 -0
- shadowcat-2.0.0/backend/db/schema.sql +247 -0
- shadowcat-2.0.0/backend/modes/__init__.py +5 -0
- shadowcat-2.0.0/backend/modes/base.py +178 -0
- shadowcat-2.0.0/backend/modes/ctf.py +39 -0
- shadowcat-2.0.0/backend/modes/enterprise.py +210 -0
- shadowcat-2.0.0/backend/modes/general.py +226 -0
- shadowcat-2.0.0/backend/modes/registry.py +34 -0
- shadowcat-2.0.0/backend/reporting/__init__.py +0 -0
- shadowcat-2.0.0/backend/reporting/generator.py +285 -0
- shadowcat-2.0.0/backend/schemas/__init__.py +1 -0
- shadowcat-2.0.0/backend/schemas/api.py +423 -0
- shadowcat-2.0.0/backend/tools/__init__.py +62 -0
- shadowcat-2.0.0/backend/tools/dirbrute_tool.py +304 -0
- shadowcat-2.0.0/backend/tools/general_report_tool.py +135 -0
- shadowcat-2.0.0/backend/tools/http_tool.py +351 -0
- shadowcat-2.0.0/backend/tools/nuclei_tool.py +20 -0
- shadowcat-2.0.0/backend/tools/report_tool.py +145 -0
- shadowcat-2.0.0/backend/tools/shell_tools.py +23 -0
- shadowcat-2.0.0/backend/verification/__init__.py +1 -0
- shadowcat-2.0.0/backend/verification/evidence_store.py +125 -0
- shadowcat-2.0.0/backend/verification/general_oracle.py +369 -0
- shadowcat-2.0.0/backend/verification/idor_oracle.py +131 -0
- shadowcat-2.0.0/backend/waf/__init__.py +0 -0
- shadowcat-2.0.0/backend/waf/detector.py +147 -0
- shadowcat-2.0.0/backend/waf/evasion.py +117 -0
- shadowcat-2.0.0/backend/webui/index.html +713 -0
- shadowcat-2.0.0/backend/workspace.py +182 -0
- shadowcat-2.0.0/custom_exploits/example_exploit.py +8 -0
- shadowcat-2.0.0/docker-compose.yml +66 -0
- shadowcat-2.0.0/docs/ENTERPRISE_ARCH.md +172 -0
- shadowcat-2.0.0/docs/PROGRESS.md +345 -0
- shadowcat-2.0.0/docs/ROADMAP.md +1096 -0
- shadowcat-2.0.0/docs/nsc-shadowcat-pitch.md +134 -0
- shadowcat-2.0.0/docs/research/README.md +0 -0
- shadowcat-2.0.0/fix-workspace-permissions.sh +39 -0
- shadowcat-2.0.0/pyproject.toml +195 -0
- shadowcat-2.0.0/scripts/config.sh +202 -0
- shadowcat-2.0.0/scripts/entrypoint.sh +80 -0
- shadowcat-2.0.0/scripts/gen_report.js +254 -0
- shadowcat-2.0.0/scripts/test_client.py +106 -0
- shadowcat-2.0.0/setup.sh +130 -0
- shadowcat-2.0.0/tests/__init__.py +1 -0
- shadowcat-2.0.0/tests/conftest.py +123 -0
- shadowcat-2.0.0/tests/docker/__init__.py +1 -0
- shadowcat-2.0.0/tests/docker/test_container_health.py +167 -0
- shadowcat-2.0.0/tests/docker/test_docker_build.py +111 -0
- shadowcat-2.0.0/tests/integration/__init__.py +1 -0
- shadowcat-2.0.0/tests/integration/test_benchmark_cli.py +279 -0
- shadowcat-2.0.0/tests/integration/test_controller.py +174 -0
- shadowcat-2.0.0/tests/test_config_cli.py +82 -0
- shadowcat-2.0.0/tests/test_coverage_ledger.py +56 -0
- shadowcat-2.0.0/tests/test_daemon_cli.py +331 -0
- shadowcat-2.0.0/tests/test_db_persistence.py +233 -0
- shadowcat-2.0.0/tests/test_enterprise_api.py +422 -0
- shadowcat-2.0.0/tests/test_enterprise_engine.py +248 -0
- shadowcat-2.0.0/tests/test_executor.py +256 -0
- shadowcat-2.0.0/tests/test_general_oracle.py +120 -0
- shadowcat-2.0.0/tests/test_headless.py +84 -0
- shadowcat-2.0.0/tests/test_llm_wiring.py +376 -0
- shadowcat-2.0.0/tests/test_scan_memory.py +87 -0
- shadowcat-2.0.0/tests/test_sse_replay.py +133 -0
- shadowcat-2.0.0/tests/unit/__init__.py +1 -0
- shadowcat-2.0.0/tests/unit/test_backend_interface.py +145 -0
- shadowcat-2.0.0/tests/unit/test_benchmark_registry.py +91 -0
- shadowcat-2.0.0/tests/unit/test_config.py +173 -0
- shadowcat-2.0.0/tests/unit/test_events.py +160 -0
- shadowcat-2.0.0/tests/unit/test_flag_detection.py +164 -0
- shadowcat-2.0.0/tests/unit/test_langfuse.py +506 -0
- shadowcat-2.0.0/tests/unit/test_phantom_two_tier.py +415 -0
- shadowcat-2.0.0/tests/unit/test_planner_context.py +179 -0
- shadowcat-2.0.0/tests/unit/test_session.py +172 -0
- shadowcat-2.0.0/uv.lock +2061 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# ShadowCat Configuration
|
|
2
|
+
# Copy this file to .env and fill in your values.
|
|
3
|
+
|
|
4
|
+
# =============================================================================
|
|
5
|
+
# LLM API Key (required)
|
|
6
|
+
#
|
|
7
|
+
# Option A — PSU Blue (university gateway, recommended on campus):
|
|
8
|
+
# Key format: sk-user-... — auto-routed to https://ai.psu.blue/v1
|
|
9
|
+
# Models: qwen/qwen3.6-plus, qwen/qwen3.6-flash, openai/gpt-4o-mini, deepseek/deepseek-chat
|
|
10
|
+
#
|
|
11
|
+
# Option B — OpenRouter (public gateway):
|
|
12
|
+
# Get your key at https://openrouter.ai/keys (format: sk-or-...)
|
|
13
|
+
# Models: any slug from https://openrouter.ai/models
|
|
14
|
+
#
|
|
15
|
+
# Both use the same OPENROUTER_API_KEY variable — the system auto-detects the gateway.
|
|
16
|
+
# =============================================================================
|
|
17
|
+
OPENROUTER_API_KEY=sk-user-your-psu-key-here
|
|
18
|
+
|
|
19
|
+
# Model slug — must be available on whichever gateway your key targets.
|
|
20
|
+
# PSU Blue examples: qwen/qwen3.6-plus | openai/gpt-4o-mini | deepseek/deepseek-chat
|
|
21
|
+
# OpenRouter examples: anthropic/claude-3-5-sonnet | openai/gpt-4o
|
|
22
|
+
MODEL=qwen/qwen3.6-plus
|
|
23
|
+
|
|
24
|
+
# Override the API base URL (optional — auto-detected from key prefix).
|
|
25
|
+
# Set this only if you need to point at a non-standard endpoint.
|
|
26
|
+
# OPENROUTER_BASE_URL=https://ai.psu.blue/v1
|
|
27
|
+
|
|
28
|
+
# =============================================================================
|
|
29
|
+
# Database (optional) — Enterprise API persistence (app/db)
|
|
30
|
+
# When unset, the API runs in-memory and persists nothing. When set, scans,
|
|
31
|
+
# HTTP evidence, findings, and verdicts are written to PostgreSQL.
|
|
32
|
+
# Standard SQLAlchemy async URL (a plain postgresql:// is upgraded to asyncpg).
|
|
33
|
+
# Percent-encode any @ : / ? characters in the password. Never commit a real one.
|
|
34
|
+
# =============================================================================
|
|
35
|
+
# DATABASE_URL=postgresql+asyncpg://postgres:your-password@127.0.0.1:5432/shadowcat
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# ============================================================================
|
|
2
|
+
# Python
|
|
3
|
+
# ============================================================================
|
|
4
|
+
|
|
5
|
+
# Byte-compiled / optimized / DLL files
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
build/
|
|
14
|
+
develop-eggs/
|
|
15
|
+
dist/
|
|
16
|
+
downloads/
|
|
17
|
+
eggs/
|
|
18
|
+
.eggs/
|
|
19
|
+
lib/
|
|
20
|
+
lib64/
|
|
21
|
+
parts/
|
|
22
|
+
sdist/
|
|
23
|
+
var/
|
|
24
|
+
wheels/
|
|
25
|
+
share/python-wheels/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
.installed.cfg
|
|
28
|
+
*.egg
|
|
29
|
+
MANIFEST
|
|
30
|
+
|
|
31
|
+
# Installer logs
|
|
32
|
+
pip-log.txt
|
|
33
|
+
pip-delete-this-directory.txt
|
|
34
|
+
|
|
35
|
+
# ============================================================================
|
|
36
|
+
# Virtual Environments
|
|
37
|
+
# ============================================================================
|
|
38
|
+
|
|
39
|
+
.venv/
|
|
40
|
+
venv/
|
|
41
|
+
ENV/
|
|
42
|
+
env/
|
|
43
|
+
env.bak/
|
|
44
|
+
venv.bak/
|
|
45
|
+
|
|
46
|
+
# ============================================================================
|
|
47
|
+
# Poetry / PDM
|
|
48
|
+
# ============================================================================
|
|
49
|
+
|
|
50
|
+
poetry.lock
|
|
51
|
+
.pdm.toml
|
|
52
|
+
.pdm-build/
|
|
53
|
+
|
|
54
|
+
# ============================================================================
|
|
55
|
+
# Testing
|
|
56
|
+
# ============================================================================
|
|
57
|
+
|
|
58
|
+
.pytest_cache/
|
|
59
|
+
.coverage
|
|
60
|
+
.coverage.*
|
|
61
|
+
htmlcov/
|
|
62
|
+
.tox/
|
|
63
|
+
.nox/
|
|
64
|
+
.cache
|
|
65
|
+
nosetests.xml
|
|
66
|
+
coverage.xml
|
|
67
|
+
*.cover
|
|
68
|
+
*.py,cover
|
|
69
|
+
.hypothesis/
|
|
70
|
+
cover/
|
|
71
|
+
|
|
72
|
+
# ============================================================================
|
|
73
|
+
# Type Checking & Linting
|
|
74
|
+
# ============================================================================
|
|
75
|
+
|
|
76
|
+
.mypy_cache/
|
|
77
|
+
.dmypy.json
|
|
78
|
+
dmypy.json
|
|
79
|
+
.pytype/
|
|
80
|
+
.pyre/
|
|
81
|
+
.ruff_cache/
|
|
82
|
+
cython_debug/
|
|
83
|
+
|
|
84
|
+
# ============================================================================
|
|
85
|
+
# IDEs & Editors
|
|
86
|
+
# ============================================================================
|
|
87
|
+
|
|
88
|
+
.idea/
|
|
89
|
+
.vscode/
|
|
90
|
+
*.swp
|
|
91
|
+
*.swo
|
|
92
|
+
*~
|
|
93
|
+
.aider*
|
|
94
|
+
|
|
95
|
+
# ============================================================================
|
|
96
|
+
# OS Files
|
|
97
|
+
# ============================================================================
|
|
98
|
+
|
|
99
|
+
.DS_Store
|
|
100
|
+
Thumbs.db
|
|
101
|
+
|
|
102
|
+
# ============================================================================
|
|
103
|
+
# Project Specific
|
|
104
|
+
# ============================================================================
|
|
105
|
+
|
|
106
|
+
# Runtime workspace - NEVER commit (contains VPN configs, exploits, sensitive data)
|
|
107
|
+
workspace/*
|
|
108
|
+
!workspace/.gitkeep
|
|
109
|
+
|
|
110
|
+
# VPN configuration files (extra safety - never commit these anywhere)
|
|
111
|
+
*.ovpn
|
|
112
|
+
|
|
113
|
+
# Logs
|
|
114
|
+
*.log
|
|
115
|
+
logs/
|
|
116
|
+
|
|
117
|
+
# Environment
|
|
118
|
+
.env
|
|
119
|
+
.env.auth
|
|
120
|
+
|
|
121
|
+
# Agent runs
|
|
122
|
+
agent_runs/
|
|
123
|
+
|
|
124
|
+
# Legacy project files (when running from legacy/)
|
|
125
|
+
config/chatgpt_config.py
|
|
126
|
+
outputs/
|
|
127
|
+
test_history/
|
|
128
|
+
archive/
|
|
129
|
+
|
|
130
|
+
# ============================================================================
|
|
131
|
+
# Local Docker Overrides (for regional mirrors, etc.)
|
|
132
|
+
# ============================================================================
|
|
133
|
+
|
|
134
|
+
Dockerfile.vpn
|
|
135
|
+
docker-compose.override.yml
|
|
136
|
+
vpn-mode.sh
|
|
137
|
+
|
|
138
|
+
# ============================================================================
|
|
139
|
+
# Documentation
|
|
140
|
+
# ============================================================================
|
|
141
|
+
|
|
142
|
+
docs/_build/
|
|
143
|
+
/site
|
|
144
|
+
|
|
145
|
+
# ============================================================================
|
|
146
|
+
# Jupyter
|
|
147
|
+
# ============================================================================
|
|
148
|
+
|
|
149
|
+
.ipynb_checkpoints
|
|
150
|
+
profile_default/
|
|
151
|
+
ipython_config.py
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
ShadowCat is an AI-powered autonomous penetration testing agent with a terminal user interface (TUI). It uses an agentic pipeline to solve CTF challenges, Hack The Box machines, and authorized security assessments.
|
|
8
|
+
|
|
9
|
+
**Stack:** Python 3.12+, uv, Docker (Ubuntu 24.04), Textual (TUI), Rich (CLI), Agent SDK
|
|
10
|
+
|
|
11
|
+
## Common Commands
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Development
|
|
15
|
+
uv sync # Install dependencies
|
|
16
|
+
uv run shadowcat-agent --target X # Run the agentic TUI single-shot (CTF/HTB)
|
|
17
|
+
uv run uvicorn backend.api.routes_scan:app --port 8000 # Run the NSC2026 DAST backend
|
|
18
|
+
|
|
19
|
+
# Local-First Agent OS (daemon + dashboard)
|
|
20
|
+
shadowcat up # Start the local daemon and open the dashboard
|
|
21
|
+
shadowcat status # Show daemon status (pid, port, uptime)
|
|
22
|
+
shadowcat down # Stop the daemon
|
|
23
|
+
|
|
24
|
+
# Testing
|
|
25
|
+
make test # Run all tests
|
|
26
|
+
make test-cov # Run tests with coverage
|
|
27
|
+
uv run pytest tests/test_controller.py -v # Run single test file
|
|
28
|
+
|
|
29
|
+
# Code Quality
|
|
30
|
+
make lint # Run ruff linter
|
|
31
|
+
make format # Format code with ruff
|
|
32
|
+
make typecheck # Run mypy type checking
|
|
33
|
+
make check # All checks (lint + typecheck)
|
|
34
|
+
|
|
35
|
+
# Docker Workflow
|
|
36
|
+
make install # Build Docker image
|
|
37
|
+
make connect # Connect to container (main usage)
|
|
38
|
+
make stop # Stop container
|
|
39
|
+
make clean-docker # Remove everything including config
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Architecture
|
|
43
|
+
|
|
44
|
+
### Entry Point
|
|
45
|
+
- `agent/interface/main.py` - CLI entry, argument parsing, mode selection (the `shadowcat-agent` command)
|
|
46
|
+
- Command: `shadowcat-agent --target <IP/URL> [--instruction "hint"] [--non-interactive] [--raw] [--debug]`
|
|
47
|
+
- `backend/cli.py` - the `shadowcat` Local-First Agent OS control plane (`up`/`status`/`down`)
|
|
48
|
+
|
|
49
|
+
### Core Layer (`agent/core/`)
|
|
50
|
+
- **agent.py** - `PentestAgent`: Wraps the LLM agent, handles flag detection, logs to `/workspace/shadowcat-debug.log`
|
|
51
|
+
- **backend.py** - `AgentBackend` interface + `OpenRouterBackend` implementation (OpenAI-compatible)
|
|
52
|
+
- **controller.py** - `AgentController`: 5-state lifecycle (IDLE->RUNNING->PAUSED->COMPLETED->ERROR), pause/resume at message boundaries
|
|
53
|
+
- **events.py** - `EventBus`: Singleton pub/sub for TUI-agent decoupling (STATE_CHANGED, MESSAGE, TOOL, FLAG_FOUND events)
|
|
54
|
+
- **session.py** - `SessionStore`: File-based persistence in `~/.shadowcat/sessions/`, supports session resumption
|
|
55
|
+
- **config.py** - Pydantic settings with `.env` file support
|
|
56
|
+
|
|
57
|
+
### Interface Layer (`agent/interface/`)
|
|
58
|
+
- **tui.py** - Textual TUI app with real-time activity feed, F1 help, Ctrl+P pause, Ctrl+Q quit
|
|
59
|
+
- **components/** - ActivityFeed, SplashScreen, tool-specific Renderers
|
|
60
|
+
|
|
61
|
+
### System Prompts (`agent/prompts/`)
|
|
62
|
+
- **pentesting.py** - `CTF_SYSTEM_PROMPT`: CTF methodology, flag formats, persistence directives
|
|
63
|
+
|
|
64
|
+
## Key Patterns
|
|
65
|
+
|
|
66
|
+
- **Event-Driven**: TUI subscribes to EventBus; agent emits events for state changes, messages, flags
|
|
67
|
+
- **Singletons**: `EventBus.get()`, `get_global_tracer()` for global access
|
|
68
|
+
- **Abstract Backend**: `AgentBackend` interface allows swapping LLM backends
|
|
69
|
+
- **Flag Detection**: Regex patterns in agent.py match `flag{}`, `HTB{}`, `CTF{}`, 32-char hex
|
|
70
|
+
|
|
71
|
+
## Testing
|
|
72
|
+
|
|
73
|
+
Tests use pytest with pytest-asyncio. Mock backends for unit tests.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv run pytest tests/ -v # All tests
|
|
77
|
+
uv run pytest tests/test_controller.py -v # Single file
|
|
78
|
+
uv run pytest tests/test_controller.py::test_name # Single test
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Docker Notes
|
|
82
|
+
|
|
83
|
+
- Non-root user: `shadowcat` with sudo
|
|
84
|
+
- Workdir: `/workspace` (mounted from `./workspace`)
|
|
85
|
+
- API keys set via `.env.auth` or environment variables
|
|
86
|
+
- Pre-installed: nmap, netcat, curl, wget, git, ripgrep, tmux
|
|
87
|
+
|
|
88
|
+
## Legacy Version
|
|
89
|
+
|
|
90
|
+
The previous multi-LLM version (v0.15) is archived in `archive/legacy/`. It supports:
|
|
91
|
+
- OpenAI (GPT-4o, o3, o4-mini)
|
|
92
|
+
- Google Gemini
|
|
93
|
+
- Deepseek
|
|
94
|
+
- Ollama (local LLMs)
|
|
95
|
+
- GPT4All
|
|
96
|
+
|
|
97
|
+
To develop on the legacy version:
|
|
98
|
+
```bash
|
|
99
|
+
cd archive/legacy
|
|
100
|
+
pip install -e .
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Benchmark System
|
|
104
|
+
|
|
105
|
+
Use the standalone benchmark runner at `benchmark/standalone-xbow-benchmark-runner/`:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
cd benchmark/standalone-xbow-benchmark-runner
|
|
109
|
+
|
|
110
|
+
python3 run_benchmarks.py --range 1-10 --pattern-flag # Run benchmarks 1-10
|
|
111
|
+
python3 run_benchmarks.py --all --pattern-flag # Run all 104 benchmarks
|
|
112
|
+
python3 run_benchmarks.py --retry-failed # Retry failed benchmarks
|
|
113
|
+
python3 run_benchmarks.py --dry-run --range 1-5 # Preview without executing
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
See `benchmark/standalone-xbow-benchmark-runner/README.md` for full documentation.
|
|
117
|
+
|
|
118
|
+
## Repository Structure
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
.
|
|
122
|
+
├── backend/ # NSC2026 entry — enterprise AI DAST (FastAPI + SSE)
|
|
123
|
+
│ ├── api/ # routes_scan.py — scan lifecycle (create/stream/report)
|
|
124
|
+
│ ├── core/ # orchestrator (ReAct loop), llm_client, events
|
|
125
|
+
│ ├── crawler/ # spider, csrf, js_analyzer, subdomains
|
|
126
|
+
│ ├── modes/ # general / enterprise / ctf agent modes + SafetyPolicy
|
|
127
|
+
│ ├── tools/ # http_request, dir_bruteforce, report tools
|
|
128
|
+
│ ├── verification/ # evidence_store + deterministic oracles
|
|
129
|
+
│ ├── waf/ # WAF detection + payload evasion
|
|
130
|
+
│ ├── reporting/ # HTML/PDF report generator
|
|
131
|
+
│ ├── db/ # async SQLAlchemy persistence (optional)
|
|
132
|
+
│ ├── compliance/ # PDPA mapping
|
|
133
|
+
│ └── schemas/ # Pydantic API contracts
|
|
134
|
+
├── agent/ # Agentic TUI package (CTF/HTB) — `shadowcat-agent` CLI; pyproject builds agent + backend
|
|
135
|
+
│ ├── core/ # Agent, controller, events, session
|
|
136
|
+
│ ├── interface/ # TUI and CLI
|
|
137
|
+
│ └── prompts/ # System prompts
|
|
138
|
+
├── docs/ # ENTERPRISE_ARCH.md, PROGRESS.md, demo/, research/
|
|
139
|
+
├── tests/ # Test suite (backend + agent)
|
|
140
|
+
├── scripts/ # entrypoint.sh, config.sh, test_client.py (manual SSE client)
|
|
141
|
+
├── archive/ # Superseded code (not imported anywhere)
|
|
142
|
+
│ ├── api/ # Earlier DAG/RAG orchestrator attempt
|
|
143
|
+
│ └── legacy/ # Archived v0.15 (multi-LLM)
|
|
144
|
+
├── benchmark/ # Benchmark suites
|
|
145
|
+
│ ├── xbow-validation-benchmarks/ # 104 XBOW benchmarks (git submodule)
|
|
146
|
+
│ └── standalone-xbow-benchmark-runner/ # Benchmark runner
|
|
147
|
+
├── custom_exploits/ # Exploit library (path-pinned by agent prompts)
|
|
148
|
+
├── workspace/ # Runtime workspace (Docker mount)
|
|
149
|
+
├── Dockerfile # Ubuntu 24.04 container
|
|
150
|
+
├── docker-compose.yml # Container orchestration
|
|
151
|
+
└── Makefile # Development commands
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
> The NSC2026 backend runs with `uv run uvicorn backend.api.routes_scan:app --port 8000`
|
|
155
|
+
> and is consumed by the SecureThai Next.js frontend (separate repo).
|
|
156
|
+
|
|
157
|
+
## Modification Requirements
|
|
158
|
+
|
|
159
|
+
When modifying code, ensure:
|
|
160
|
+
- Adherence to existing architecture and patterns
|
|
161
|
+
- Comprehensive tests for new features
|
|
162
|
+
- Ensure to run tests after changes, and do further updates to ensure code quality. Always keep the documentation up to date with any architectural changes. Also ensure all tests pass after modifications.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# ShadowCat Docker Image
|
|
2
|
+
# AI-powered autonomous web security scanner
|
|
3
|
+
|
|
4
|
+
FROM ubuntu:24.04
|
|
5
|
+
|
|
6
|
+
LABEL description="ShadowCat - AI-Powered Autonomous Web Security Scanner"
|
|
7
|
+
LABEL version="2.0.0"
|
|
8
|
+
|
|
9
|
+
# Prevent interactive prompts during build
|
|
10
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
11
|
+
|
|
12
|
+
# Update and install system dependencies
|
|
13
|
+
RUN apt-get update && \
|
|
14
|
+
apt-get upgrade -y && \
|
|
15
|
+
apt-get install -y \
|
|
16
|
+
# Build essentials
|
|
17
|
+
build-essential \
|
|
18
|
+
software-properties-common \
|
|
19
|
+
ca-certificates \
|
|
20
|
+
gnupg \
|
|
21
|
+
# Python
|
|
22
|
+
python3.12 \
|
|
23
|
+
python3-pip \
|
|
24
|
+
python3-venv \
|
|
25
|
+
python3-dev \
|
|
26
|
+
# Essential security tools
|
|
27
|
+
nmap \
|
|
28
|
+
netcat-openbsd \
|
|
29
|
+
curl \
|
|
30
|
+
wget \
|
|
31
|
+
git \
|
|
32
|
+
sudo \
|
|
33
|
+
# Network utilities
|
|
34
|
+
net-tools \
|
|
35
|
+
dnsutils \
|
|
36
|
+
whois \
|
|
37
|
+
# VPN (for authorized connectivity)
|
|
38
|
+
openvpn \
|
|
39
|
+
# Text processing
|
|
40
|
+
jq \
|
|
41
|
+
ripgrep \
|
|
42
|
+
# Terminal
|
|
43
|
+
tmux \
|
|
44
|
+
&& apt-get autoremove -y \
|
|
45
|
+
&& apt-get autoclean \
|
|
46
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
47
|
+
|
|
48
|
+
# Remove EXTERNALLY-MANAGED marker to allow pip in Docker
|
|
49
|
+
RUN rm -f /usr/lib/python3.*/EXTERNALLY-MANAGED && \
|
|
50
|
+
apt-get remove -y python3-cryptography && \
|
|
51
|
+
apt-get autoremove -y
|
|
52
|
+
|
|
53
|
+
# Node.js 20 + Claude Code CLI — required by claude-agent-sdk (OAuth auth mode)
|
|
54
|
+
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
|
|
55
|
+
apt-get install -y nodejs && \
|
|
56
|
+
npm install -g @anthropic-ai/claude-code && \
|
|
57
|
+
apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
58
|
+
|
|
59
|
+
# Install uv for fast Python dependency management
|
|
60
|
+
RUN pip install uv
|
|
61
|
+
|
|
62
|
+
# Create non-root user
|
|
63
|
+
RUN useradd -m -s /bin/bash shadowcat && \
|
|
64
|
+
usermod -aG sudo shadowcat && \
|
|
65
|
+
echo "shadowcat ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
|
66
|
+
|
|
67
|
+
# Set up working directories
|
|
68
|
+
RUN mkdir -p /workspace /app /home/shadowcat/.claude && \
|
|
69
|
+
chown -R shadowcat:shadowcat /workspace /app /home/shadowcat/.claude && \
|
|
70
|
+
chmod 700 /home/shadowcat/.claude
|
|
71
|
+
|
|
72
|
+
# Switch to shadowcat user
|
|
73
|
+
USER shadowcat
|
|
74
|
+
WORKDIR /app
|
|
75
|
+
|
|
76
|
+
# Copy project files
|
|
77
|
+
COPY --chown=shadowcat:shadowcat pyproject.toml uv.lock README.md /app/
|
|
78
|
+
COPY --chown=shadowcat:shadowcat agent/ /app/agent/
|
|
79
|
+
COPY --chown=shadowcat:shadowcat backend/ /app/backend/
|
|
80
|
+
COPY --chown=shadowcat:shadowcat scripts/entrypoint.sh /home/shadowcat/entrypoint.sh
|
|
81
|
+
|
|
82
|
+
# Install Python dependencies via uv (frozen = reproducible)
|
|
83
|
+
USER root
|
|
84
|
+
RUN uv sync --frozen --no-dev && \
|
|
85
|
+
chmod +x /home/shadowcat/entrypoint.sh
|
|
86
|
+
|
|
87
|
+
# Switch back to shadowcat user for runtime
|
|
88
|
+
USER shadowcat
|
|
89
|
+
|
|
90
|
+
# Set environment variables
|
|
91
|
+
ENV PYTHONPATH=/app
|
|
92
|
+
ENV PYTHONUNBUFFERED=1
|
|
93
|
+
|
|
94
|
+
# Default working directory
|
|
95
|
+
WORKDIR /workspace
|
|
96
|
+
|
|
97
|
+
# Use entrypoint script for auth setup
|
|
98
|
+
ENTRYPOINT ["/home/shadowcat/entrypoint.sh"]
|
|
99
|
+
|
|
100
|
+
# Default command - interactive bash
|
|
101
|
+
CMD ["/bin/bash"]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# LEARNING.md — แผนเรียนรู้ ShadowCat เพื่อ NSC ครั้งที่ 28
|
|
2
|
+
|
|
3
|
+
> ไฟล์นี้คือ "แผนการเรียน" ของเจ้าของโปรเจค เป้าหมายคือ **อ่านโค้ดตัวเองออก
|
|
4
|
+
> และอธิบาย/ป้องกันงานบนเวทีแข่งได้** — ไม่ใช่แค่ส่งงานที่ AI ทำให้
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## เป้าหมาย (ปลายทาง)
|
|
9
|
+
1. อ่านโค้ดในโปรเจคนี้แล้วเข้าใจว่ามันทำอะไร ทำไมถึงเขียนแบบนั้น
|
|
10
|
+
2. ตอบกรรมการได้เวลาถูกถาม "ตรงนี้ทำงานยังไง / ทำไมทำแบบนี้"
|
|
11
|
+
3. แก้/ต่อยอดโค้ดเองได้บ้าง ไม่ใช่ต้องพึ่ง AI 100%
|
|
12
|
+
|
|
13
|
+
## กฎการทำงานของเรา (โหมดสอน)
|
|
14
|
+
- **AI สอน เจ้าของลงมือ** — จะไม่เขียนให้เฉยๆ อีกแล้ว
|
|
15
|
+
- เรียนผ่าน **โค้ดจริงในโปรเจคนี้** (`backend/`) ไม่ใช่คอร์ส Python ลอยๆ
|
|
16
|
+
- ทุกบทจบด้วย **"อธิบายกลับให้ฟัง"** — อธิบายได้ = เข้าใจจริง = ตอบกรรมการได้
|
|
17
|
+
- งงตรงไหน **พูดเลย ไม่ต้องเดาให้สวย** — การบอกว่า "ตรงนี้ไม่เข้าใจ" คือก้าวที่เร็วที่สุด
|
|
18
|
+
|
|
19
|
+
## คุณอยู่ตรงไหนตอนนี้ (เช็คเมื่อ 2026-06-13)
|
|
20
|
+
- ✅ อ่านค่าตรงๆ ในโค้ดได้ (`return`, อ่าน key/value ใน dict ถูก)
|
|
21
|
+
- ✅ เริ่มจับทักษะ **"แยกบรรทัดเป็นชิ้นๆ"** และโยง type hint เข้ากับค่าจริงได้
|
|
22
|
+
- ⏳ ยังต้องสร้างคำศัพท์พื้นฐาน: `def`/function, decorator (`@`), `async`, type hint, `dict`/`list`
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## เส้นทาง (ทำทีละโมดูลตามลำดับ)
|
|
27
|
+
รูปแบบแต่ละโมดูล: **[อ่านไฟล์ไหน] → [ต้องเข้าใจอะไร] → [ข้อสอบ: อธิบายกลับ]**
|
|
28
|
+
|
|
29
|
+
- [x] **โมดูล 0 — อ่าน 1 บรรทัดเป็นชิ้นๆ + dict คือ key→value** *(ผ่านแล้ว 2026-06-13)*
|
|
30
|
+
- [x] **โมดูล 1 — ตัวแปร & ชนิดข้อมูล**: `str` `int` `bool` `dict` `list` + อ่าน `dict[K,V]`/`list[T]` *(ผ่านแล้ว 2026-06-14)*
|
|
31
|
+
- [ ] **โมดูล 2 — ฟังก์ชัน**: `def` คืออะไร, รับ input (arguments), `return` ค่ากลับ
|
|
32
|
+
- [ ] **โมดูล 3 — เว็บเบื้องต้น (FastAPI)**: route, decorator `@app.get` ทำงานยังไง
|
|
33
|
+
→ ไฟล์ `backend/api/routes_scan.py` (เริ่มจาก `/health`)
|
|
34
|
+
- [ ] **โมดูล 4 — `async`/`await`**: ทำไมต้องมี (สแกนยิง HTTP หลายอันพร้อมกัน)
|
|
35
|
+
→ ไฟล์ `backend/tools/http_tool.py`
|
|
36
|
+
- [ ] **โมดูล 5 — หัวใจของโปรเจค: agent ReAct loop** (คิด → เรียกเครื่องมือ → ดูผล → วนซ้ำ)
|
|
37
|
+
→ ไฟล์ `backend/core/orchestrator.py` ← ตัวที่กรรมการน่าจะถามมากสุด
|
|
38
|
+
- [ ] **โมดูล 6 — สัญญาข้อมูล (Pydantic schemas)**: รูปร่างของ request/response
|
|
39
|
+
→ ไฟล์ `backend/schemas/api.py`
|
|
40
|
+
- [ ] **โมดูล 7 — Live Feed ทำงานยังไง (SSE events)**
|
|
41
|
+
→ ไฟล์ `backend/core/events.py`
|
|
42
|
+
- [ ] **โมดูล 8 — ของที่เราเพิ่งสร้าง**: scan_memory (ความจำข้ามสแกน), coverage, oracle (ตัวตัดสิน finding)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## ข้อสอบเวที — คำถามที่กรรมการน่าจะถาม (เป้าหมายว่าต้องตอบได้)
|
|
47
|
+
ฝึกตอบทีละข้อเมื่อเรียนถึงโมดูลที่เกี่ยว:
|
|
48
|
+
1. โปรเจคนี้ทำอะไร? อธิบายใน 30 วินาที
|
|
49
|
+
2. agent มัน "คิด" และ "ลงมือ" ยังไง? (ReAct loop — โมดูล 5)
|
|
50
|
+
3. กันไม่ให้มันสแกนนอกขอบเขตที่ได้รับอนุญาตยังไง? (SafetyPolicy)
|
|
51
|
+
4. ทำไม finding ถึงเชื่อถือได้? (oracle เป็นคนตัดสิน ไม่ใช่ AI เดาเอง — โมดูล 8)
|
|
52
|
+
5. ประหยัด cost / token ยังไง? (pruning, scan memory)
|
|
53
|
+
6. "ความจำข้ามสแกน" ทำงานยังไง ทำไมยิ่งสแกนยิ่งฉลาด? (โมดูล 8)
|
|
54
|
+
7. ใช้ AI สร้างเยอะ แล้วส่วนไหนที่คุณเข้าใจ/ออกแบบเอง? ← ตอบตรงๆ ได้คือแต้มต่อ
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## บันทึกความคืบหน้า (อัปเดตทุกครั้งที่เรียน)
|
|
59
|
+
- **2026-06-13** — เริ่มโหมดสอน. ผ่านโมดูล 0 (แยกบรรทัด + dict key/value).
|
|
60
|
+
- **2026-06-14** — ผ่านโมดูล 1: ชนิดข้อมูล 5 ตัว (`str` `int` `bool` `list` `dict`) + อ่าน
|
|
61
|
+
type hint `dict[str,str]` และ `list[str]` ได้เองโดยไม่ต้องใบ้. ต่อไป: โมดูล 2 (ฟังก์ชัน).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ShadowCat Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|