shadowcat 2.0.0__py3-none-any.whl
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.
- agent/__init__.py +17 -0
- agent/benchmark/__init__.py +11 -0
- agent/benchmark/cli.py +179 -0
- agent/benchmark/config.py +15 -0
- agent/benchmark/docker.py +192 -0
- agent/benchmark/registry.py +99 -0
- agent/core/__init__.py +0 -0
- agent/core/agent.py +362 -0
- agent/core/backend.py +1667 -0
- agent/core/config.py +106 -0
- agent/core/controller.py +638 -0
- agent/core/events.py +177 -0
- agent/core/langfuse.py +320 -0
- agent/core/phantom.py +2327 -0
- agent/core/planner.py +493 -0
- agent/core/profiling.py +58 -0
- agent/core/sanitizer.py +104 -0
- agent/core/session.py +228 -0
- agent/core/tracer.py +137 -0
- agent/interface/__init__.py +0 -0
- agent/interface/components/__init__.py +0 -0
- agent/interface/components/activity_feed.py +202 -0
- agent/interface/components/renderers.py +149 -0
- agent/interface/components/splash.py +112 -0
- agent/interface/main.py +1126 -0
- agent/interface/styles.tcss +421 -0
- agent/interface/tui.py +508 -0
- agent/parsing/html_distiller.py +230 -0
- agent/parsing/tool_parser.py +115 -0
- agent/prompts/__init__.py +0 -0
- agent/prompts/pentesting.py +238 -0
- agent/rag_module/knowledge_base.py +116 -0
- agent/tests/benchmark_phantom.py +455 -0
- agent/tools/__init__.py +14 -0
- agent/tools/base.py +99 -0
- agent/tools/executor.py +345 -0
- agent/tools/registry.py +47 -0
- backend/README.md +244 -0
- backend/__init__.py +10 -0
- backend/api/__init__.py +1 -0
- backend/api/routes_scan.py +932 -0
- backend/authz.py +75 -0
- backend/cli.py +261 -0
- backend/compliance/__init__.py +1 -0
- backend/compliance/pdpa_mapping.py +16 -0
- backend/core/__init__.py +1 -0
- backend/core/coverage.py +93 -0
- backend/core/events.py +166 -0
- backend/core/llm_client.py +614 -0
- backend/core/orchestrator.py +402 -0
- backend/core/scan_memory.py +236 -0
- backend/crawler/__init__.py +1 -0
- backend/crawler/csrf.py +75 -0
- backend/crawler/headless.py +232 -0
- backend/crawler/js_analyzer.py +133 -0
- backend/crawler/spider.py +550 -0
- backend/crawler/subdomains.py +279 -0
- backend/daemon.py +252 -0
- backend/db/README.md +86 -0
- backend/db/__init__.py +17 -0
- backend/db/engine.py +87 -0
- backend/db/models.py +206 -0
- backend/db/repository.py +316 -0
- backend/db/schema.sql +247 -0
- backend/modes/__init__.py +5 -0
- backend/modes/base.py +178 -0
- backend/modes/ctf.py +39 -0
- backend/modes/enterprise.py +210 -0
- backend/modes/general.py +226 -0
- backend/modes/registry.py +34 -0
- backend/reporting/__init__.py +0 -0
- backend/reporting/generator.py +285 -0
- backend/schemas/__init__.py +1 -0
- backend/schemas/api.py +423 -0
- backend/tools/__init__.py +62 -0
- backend/tools/dirbrute_tool.py +304 -0
- backend/tools/general_report_tool.py +135 -0
- backend/tools/http_tool.py +351 -0
- backend/tools/nuclei_tool.py +20 -0
- backend/tools/report_tool.py +145 -0
- backend/tools/shell_tools.py +23 -0
- backend/verification/__init__.py +1 -0
- backend/verification/evidence_store.py +125 -0
- backend/verification/general_oracle.py +369 -0
- backend/verification/idor_oracle.py +131 -0
- backend/waf/__init__.py +0 -0
- backend/waf/detector.py +147 -0
- backend/waf/evasion.py +117 -0
- backend/webui/index.html +713 -0
- backend/workspace.py +182 -0
- shadowcat-2.0.0.dist-info/METADATA +360 -0
- shadowcat-2.0.0.dist-info/RECORD +95 -0
- shadowcat-2.0.0.dist-info/WHEEL +4 -0
- shadowcat-2.0.0.dist-info/entry_points.txt +4 -0
- shadowcat-2.0.0.dist-info/licenses/LICENSE.md +21 -0
agent/core/config.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""Configuration management for ShadowCat using Pydantic."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, Literal
|
|
5
|
+
|
|
6
|
+
from pydantic import AliasChoices, Field
|
|
7
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
8
|
+
|
|
9
|
+
# User-global config written by ``shadowcat config``. Used as the lowest-priority
|
|
10
|
+
# fallback so a pip-installed CLI works from any directory without a local .env.
|
|
11
|
+
_USER_ENV = str(Path.home() / ".shadowcat" / ".env")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ShadowCatConfig(BaseSettings):
|
|
15
|
+
"""Main configuration for ShadowCat."""
|
|
16
|
+
|
|
17
|
+
model_config = SettingsConfigDict(
|
|
18
|
+
# Read several files; later entries override earlier ones. So precedence
|
|
19
|
+
# (highest first) is: real env vars > project `.env.auth` > project `.env`
|
|
20
|
+
# > user-global `~/.shadowcat/.env`. The global file is the fallback for
|
|
21
|
+
# the pip-installed CLI; project files override it for local dev.
|
|
22
|
+
env_file=(_USER_ENV, ".env", ".env.auth"),
|
|
23
|
+
env_file_encoding="utf-8",
|
|
24
|
+
case_sensitive=False,
|
|
25
|
+
extra="ignore",
|
|
26
|
+
populate_by_name=True,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# LLM Configuration
|
|
30
|
+
llm_model: str = Field(
|
|
31
|
+
default="",
|
|
32
|
+
validation_alias=AliasChoices("MODEL", "LLM_MODEL"),
|
|
33
|
+
description="Model identifier for OpenRouter (e.g. anthropic/claude-3-5-sonnet)",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
openrouter_api_key: str | None = Field(
|
|
37
|
+
default=None,
|
|
38
|
+
validation_alias=AliasChoices("OPENROUTER_API_KEY"),
|
|
39
|
+
description="OpenRouter API key (https://openrouter.ai/keys)",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Agent Configuration
|
|
43
|
+
max_iterations: int = Field(default=300, description="Maximum iterations for the agent")
|
|
44
|
+
|
|
45
|
+
working_directory: Path = Field(
|
|
46
|
+
default_factory=lambda: Path.cwd() / "workspace",
|
|
47
|
+
description="Working directory for agent operations",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Target Configuration
|
|
51
|
+
target: str = Field(
|
|
52
|
+
..., # Required
|
|
53
|
+
description="Target for penetration testing (URL, IP, domain, or path)",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
custom_instruction: str | None = Field(
|
|
57
|
+
default=None, description="Optional custom instructions for the agent"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Interface Configuration
|
|
61
|
+
interface_mode: Literal["tui", "cli"] = Field(
|
|
62
|
+
default="tui", description="Interface mode: TUI (interactive) or CLI (headless)"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
verbose: bool = Field(default=True, description="Enable verbose output")
|
|
66
|
+
|
|
67
|
+
def __init__(self, **data: Any) -> None:
|
|
68
|
+
"""Initialize configuration."""
|
|
69
|
+
super().__init__(**data)
|
|
70
|
+
|
|
71
|
+
# Create working directory if it doesn't exist
|
|
72
|
+
# Ignore permission errors if directory already exists
|
|
73
|
+
try:
|
|
74
|
+
self.working_directory.mkdir(parents=True, exist_ok=True)
|
|
75
|
+
except (PermissionError, OSError):
|
|
76
|
+
# Directory already exists or we don't have permission to create it
|
|
77
|
+
# This is fine if the directory is already available
|
|
78
|
+
if not self.working_directory.exists():
|
|
79
|
+
raise
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def system_prompt_path(self) -> Path:
|
|
83
|
+
"""Get path to system prompt file."""
|
|
84
|
+
return Path(__file__).parent.parent / "prompts" / "pentesting.py"
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def from_env(cls, **overrides: object) -> "ShadowCatConfig":
|
|
88
|
+
"""Create config from environment variables with optional overrides."""
|
|
89
|
+
return cls(**overrides)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def load_config(**overrides: object) -> ShadowCatConfig:
|
|
93
|
+
"""
|
|
94
|
+
Load configuration from environment with optional overrides.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
**overrides: Keyword arguments to override config values
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
ShadowCatConfig instance
|
|
101
|
+
|
|
102
|
+
Example:
|
|
103
|
+
>>> config = load_config(target="example.com", verbose=True)
|
|
104
|
+
"""
|
|
105
|
+
# Create config with overrides
|
|
106
|
+
return ShadowCatConfig.from_env(**overrides)
|