swarmhack-cli 0.1.0 → 0.1.1
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.
- package/README.md +126 -5
- package/bin/swarmhack.js +29 -1
- package/config/swarmhack.yaml +445 -0
- package/index.js +31 -1
- package/native/linux-x64/swarmhack +0 -0
- package/package.json +3 -1
- package/scripts/postinstall.js +17 -9
package/README.md
CHANGED
|
@@ -1,34 +1,73 @@
|
|
|
1
|
-
#
|
|
1
|
+
# swarmhack-cli
|
|
2
2
|
|
|
3
3
|
Neural swarm-based penetration testing framework.
|
|
4
4
|
|
|
5
|
+
## What's New in v0.2.0
|
|
6
|
+
|
|
7
|
+
- **Runtime Modes**: Choose between `local` (direct execution) or `docker` (containerized) mode
|
|
8
|
+
- **OCSF 1.1.0 Reports**: Industry-standard vulnerability reports with optimized JSON structure
|
|
9
|
+
- **Prancer Portal Integration**: Secure authentication with Prancer Portal
|
|
10
|
+
- **Bundled Configuration**: Default config file included - no manual setup required
|
|
11
|
+
- **Multi-Platform Support**: Linux, macOS, and Windows binaries
|
|
12
|
+
|
|
5
13
|
## Installation
|
|
6
14
|
|
|
7
15
|
```bash
|
|
8
|
-
npm install -g
|
|
16
|
+
npm install -g swarmhack-cli
|
|
9
17
|
```
|
|
10
18
|
|
|
11
19
|
Or use npx:
|
|
12
20
|
|
|
13
21
|
```bash
|
|
14
|
-
npx
|
|
22
|
+
npx swarmhack-cli --help
|
|
15
23
|
```
|
|
16
24
|
|
|
25
|
+
## Configuration
|
|
26
|
+
|
|
27
|
+
SwarmHack includes a default configuration file (`config/swarmhack.yaml`) that is automatically used when running commands. You can override it by:
|
|
28
|
+
|
|
29
|
+
1. **Using your own config file:**
|
|
30
|
+
```bash
|
|
31
|
+
swarmhack spawn --config /path/to/your/config.yaml --target "http://example.com"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
2. **Creating a local config in your project:**
|
|
35
|
+
Place `config/swarmhack.yaml` in your project root - it will be automatically detected.
|
|
36
|
+
|
|
37
|
+
3. **Customizing the bundled config:**
|
|
38
|
+
Copy the bundled config to your project and modify it:
|
|
39
|
+
```bash
|
|
40
|
+
cp $(npm root -g)/swarmhack-cli/config/swarmhack.yaml ./config/
|
|
41
|
+
```
|
|
42
|
+
|
|
17
43
|
## CLI Usage
|
|
18
44
|
|
|
19
45
|
```bash
|
|
20
|
-
# Run SQL injection scan
|
|
46
|
+
# Run SQL injection scan (local mode - default)
|
|
21
47
|
swarmhack spawn --agents sqli \
|
|
22
48
|
--target "http://example.com" \
|
|
23
49
|
--customer "your-customer" \
|
|
24
50
|
--token "your-token"
|
|
25
51
|
|
|
52
|
+
# Run in Docker mode (isolated execution)
|
|
53
|
+
swarmhack spawn --agents sqli \
|
|
54
|
+
--target "http://example.com" \
|
|
55
|
+
--runtime docker \
|
|
56
|
+
--docker-image "swarmhack/pentest:latest"
|
|
57
|
+
|
|
26
58
|
# Run multiple agents
|
|
27
59
|
swarmhack spawn --agents sqli,xss,csrf \
|
|
28
60
|
--target "http://example.com" \
|
|
29
61
|
--customer "your-customer" \
|
|
30
62
|
--token "your-token"
|
|
31
63
|
|
|
64
|
+
# Run in Docker with custom image and volumes
|
|
65
|
+
swarmhack spawn --agents sqli \
|
|
66
|
+
--target "http://example.com" \
|
|
67
|
+
--runtime docker \
|
|
68
|
+
--docker-image "myregistry/swarmhack:v1.0" \
|
|
69
|
+
--docker-volume "/host/reports:/app/reports"
|
|
70
|
+
|
|
32
71
|
# List available agents
|
|
33
72
|
swarmhack agents list
|
|
34
73
|
|
|
@@ -36,10 +75,47 @@ swarmhack agents list
|
|
|
36
75
|
swarmhack doctor
|
|
37
76
|
```
|
|
38
77
|
|
|
78
|
+
## Runtime Modes
|
|
79
|
+
|
|
80
|
+
SwarmHack supports two runtime modes:
|
|
81
|
+
|
|
82
|
+
| Mode | Description | Use Case |
|
|
83
|
+
|------|-------------|----------|
|
|
84
|
+
| `local` | Run directly on host system | Development, CI/CD with pre-installed tools |
|
|
85
|
+
| `docker` | Run inside Docker containers | Production, isolated execution, portable |
|
|
86
|
+
|
|
87
|
+
### CLI Runtime Options
|
|
88
|
+
|
|
89
|
+
| Option | Description |
|
|
90
|
+
|--------|-------------|
|
|
91
|
+
| `--runtime` | Runtime mode: `local` (default) or `docker` |
|
|
92
|
+
| `--docker-image` | Docker image to use (overrides config) |
|
|
93
|
+
| `--docker-container` | Custom container name |
|
|
94
|
+
| `--docker-volume` | Additional volumes (can be repeated) |
|
|
95
|
+
| `--docker-env` | Environment variables (format: KEY=VALUE) |
|
|
96
|
+
|
|
97
|
+
### Config File Runtime Options
|
|
98
|
+
|
|
99
|
+
```yaml
|
|
100
|
+
# In config/swarmhack.yaml
|
|
101
|
+
runtime:
|
|
102
|
+
mode: docker # or "local"
|
|
103
|
+
docker_image: swarmhack/pentest:latest
|
|
104
|
+
docker_auto_remove: true
|
|
105
|
+
docker_volumes:
|
|
106
|
+
- /host/reports:/app/reports
|
|
107
|
+
docker_env:
|
|
108
|
+
CUSTOM_VAR: value
|
|
109
|
+
docker_network: bridge
|
|
110
|
+
docker_resources:
|
|
111
|
+
memory: 1g
|
|
112
|
+
cpus: "1"
|
|
113
|
+
```
|
|
114
|
+
|
|
39
115
|
## Node.js API
|
|
40
116
|
|
|
41
117
|
```javascript
|
|
42
|
-
const swarmhack = require('
|
|
118
|
+
const swarmhack = require('swarmhack-cli');
|
|
43
119
|
|
|
44
120
|
// Run a scan
|
|
45
121
|
const results = await swarmhack.scan({
|
|
@@ -93,11 +169,56 @@ docker run --rm \
|
|
|
93
169
|
| `auth_bypass` | Authentication bypass |
|
|
94
170
|
| `cmdi` | Command injection |
|
|
95
171
|
|
|
172
|
+
## OCSF Reports
|
|
173
|
+
|
|
174
|
+
SwarmHack generates reports in [OCSF 1.1.0](https://schema.ocsf.io/) format, the industry standard for security findings:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"scan_info": {
|
|
179
|
+
"scanner": { "name": "SwarmHack", "vendor": "Prancer" },
|
|
180
|
+
"customer": "your-customer",
|
|
181
|
+
"target": "http://example.com",
|
|
182
|
+
"duration_formatted": "3m 11s",
|
|
183
|
+
"summary": { "findings_count": 5, "crown_jewels_count": 12 }
|
|
184
|
+
},
|
|
185
|
+
"class_name": "Vulnerability Finding",
|
|
186
|
+
"class_uid": 6001,
|
|
187
|
+
"findings": [...]
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Authentication
|
|
192
|
+
|
|
193
|
+
SwarmHack requires Prancer Portal authentication:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
swarmhack spawn \
|
|
197
|
+
--target "http://example.com" \
|
|
198
|
+
--agents sqli,xss \
|
|
199
|
+
--customer "your-customer" \
|
|
200
|
+
--token "your-32-char-token"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Get your token from [Prancer Portal](https://portal.prancer.io) → Settings → Access Tokens.
|
|
204
|
+
|
|
96
205
|
## Requirements
|
|
97
206
|
|
|
98
207
|
- Node.js 16+
|
|
99
208
|
- Prancer Portal account (for `--token` and `--customer`)
|
|
100
209
|
|
|
210
|
+
## Changelog
|
|
211
|
+
|
|
212
|
+
### v0.2.0
|
|
213
|
+
- Added runtime mode selection (local/docker)
|
|
214
|
+
- Added OCSF 1.1.0 report generation
|
|
215
|
+
- Added Prancer Portal authentication
|
|
216
|
+
- Bundled default configuration file
|
|
217
|
+
- Multi-platform binary support
|
|
218
|
+
|
|
219
|
+
### v0.1.0
|
|
220
|
+
- Initial release
|
|
221
|
+
|
|
101
222
|
## License
|
|
102
223
|
|
|
103
224
|
MIT
|
package/bin/swarmhack.js
CHANGED
|
@@ -65,9 +65,37 @@ Or use Docker instead:
|
|
|
65
65
|
// Get binary path
|
|
66
66
|
const binaryPath = getBinaryPath();
|
|
67
67
|
|
|
68
|
+
// Get config path - bundled with npm package
|
|
69
|
+
function getConfigPath() {
|
|
70
|
+
// Check if user already specified --config
|
|
71
|
+
const args = process.argv.slice(2);
|
|
72
|
+
if (args.includes('--config') || args.includes('-c')) {
|
|
73
|
+
return null; // User specified their own config
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Check for local config first (user's project)
|
|
77
|
+
const localConfig = path.join(process.cwd(), 'config', 'swarmhack.yaml');
|
|
78
|
+
if (fs.existsSync(localConfig)) {
|
|
79
|
+
return localConfig;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Use bundled config from npm package
|
|
83
|
+
const bundledConfig = path.join(__dirname, '..', 'config', 'swarmhack.yaml');
|
|
84
|
+
if (fs.existsSync(bundledConfig)) {
|
|
85
|
+
return bundledConfig;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
68
91
|
// Spawn the binary with all arguments
|
|
69
92
|
const args = process.argv.slice(2);
|
|
70
|
-
const
|
|
93
|
+
const configPath = getConfigPath();
|
|
94
|
+
|
|
95
|
+
// Add config flag if we have a bundled config and user didn't specify one
|
|
96
|
+
const finalArgs = configPath ? ['--config', configPath, ...args] : args;
|
|
97
|
+
|
|
98
|
+
const child = spawn(binaryPath, finalArgs, {
|
|
71
99
|
stdio: 'inherit',
|
|
72
100
|
env: {
|
|
73
101
|
...process.env,
|
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
# ========== RUNTIME ENVIRONMENT CONFIGURATION ==========
|
|
2
|
+
# Controls whether SwarmHack runs locally or inside Docker containers
|
|
3
|
+
runtime:
|
|
4
|
+
# Runtime mode: "local" or "docker"
|
|
5
|
+
# - local: Run directly on the host system (default, requires tools installed)
|
|
6
|
+
# - docker: Run inside Docker containers (portable, isolated)
|
|
7
|
+
mode: local
|
|
8
|
+
|
|
9
|
+
# Docker image to use when mode is "docker"
|
|
10
|
+
docker_image: swarmhack/pentest:latest
|
|
11
|
+
|
|
12
|
+
# Docker container name prefix
|
|
13
|
+
docker_container_prefix: swarmhack
|
|
14
|
+
|
|
15
|
+
# Auto-remove containers after execution
|
|
16
|
+
docker_auto_remove: true
|
|
17
|
+
|
|
18
|
+
# Additional Docker volumes (format: /host/path:/container/path)
|
|
19
|
+
docker_volumes: []
|
|
20
|
+
|
|
21
|
+
# Additional environment variables for Docker containers
|
|
22
|
+
docker_env: {}
|
|
23
|
+
|
|
24
|
+
# Docker network mode (bridge, host, none, or custom network name)
|
|
25
|
+
docker_network: bridge
|
|
26
|
+
|
|
27
|
+
# Pull policy: always, missing, never
|
|
28
|
+
docker_pull_policy: missing
|
|
29
|
+
|
|
30
|
+
# Docker socket path
|
|
31
|
+
docker_socket: /var/run/docker.sock
|
|
32
|
+
|
|
33
|
+
# Resource limits for Docker containers
|
|
34
|
+
docker_resources:
|
|
35
|
+
memory: 1g
|
|
36
|
+
cpus: "1"
|
|
37
|
+
|
|
38
|
+
queen:
|
|
39
|
+
topology: hierarchical # CHANGED: mesh → hierarchical for parent-child agent coordination
|
|
40
|
+
max_agents: 50
|
|
41
|
+
consensus_threshold: 0.67
|
|
42
|
+
spawn_strategy: dynamic
|
|
43
|
+
|
|
44
|
+
# ========== AUTHENTICATION DETECTION CONFIGURATION ==========
|
|
45
|
+
# BUG #11 FIX: Generic authentication detection patterns (NO HARDCODING)
|
|
46
|
+
authentication:
|
|
47
|
+
# Patterns indicating FAILED authentication (redirect to these = invalid session)
|
|
48
|
+
failed_auth_indicators:
|
|
49
|
+
- "/login"
|
|
50
|
+
- "/signin"
|
|
51
|
+
- "/auth"
|
|
52
|
+
- "/authenticate"
|
|
53
|
+
- "?login"
|
|
54
|
+
- "?signin"
|
|
55
|
+
|
|
56
|
+
# Patterns indicating SUCCESSFUL authentication (content contains these = valid session)
|
|
57
|
+
successful_auth_indicators:
|
|
58
|
+
- "logout"
|
|
59
|
+
- "sign out"
|
|
60
|
+
- "log out"
|
|
61
|
+
- "account"
|
|
62
|
+
- "dashboard"
|
|
63
|
+
- "profile"
|
|
64
|
+
- "settings"
|
|
65
|
+
|
|
66
|
+
# Negative indicators (if content has these, NOT authenticated)
|
|
67
|
+
negative_auth_indicators:
|
|
68
|
+
- "please log in"
|
|
69
|
+
- "please sign in"
|
|
70
|
+
- "authentication required"
|
|
71
|
+
- "please login"
|
|
72
|
+
- "login to continue"
|
|
73
|
+
- "<input[^>]*name=['\"]username"
|
|
74
|
+
- "<input[^>]*name=['\"]password"
|
|
75
|
+
- "<input[^>]*type=['\"]password"
|
|
76
|
+
|
|
77
|
+
# Cookie name patterns (regex)
|
|
78
|
+
session_cookie_patterns:
|
|
79
|
+
- ".*SESSIONID.*"
|
|
80
|
+
- ".*SID.*"
|
|
81
|
+
- ".*session.*"
|
|
82
|
+
- ".*token.*"
|
|
83
|
+
- ".*auth.*"
|
|
84
|
+
|
|
85
|
+
# Max redirects to follow
|
|
86
|
+
max_redirect_hops: 3
|
|
87
|
+
|
|
88
|
+
# Content-based authentication scoring
|
|
89
|
+
auth_score_threshold: 2
|
|
90
|
+
|
|
91
|
+
# ========== CREDENTIAL SYNTHESIS CONFIGURATION ==========
|
|
92
|
+
# BUG #11 FIX PHASE 2B: Generate potential credentials when SQLi yields 0 valid sessions
|
|
93
|
+
credential_synthesis:
|
|
94
|
+
enabled: true
|
|
95
|
+
|
|
96
|
+
# Default credentials by technology
|
|
97
|
+
default_credentials:
|
|
98
|
+
altoromutual:
|
|
99
|
+
- username: "admin"
|
|
100
|
+
password: "admin"
|
|
101
|
+
- username: "jsmith"
|
|
102
|
+
password: "demo1234"
|
|
103
|
+
demo_apps:
|
|
104
|
+
- username: "admin"
|
|
105
|
+
password: "password"
|
|
106
|
+
- username: "test"
|
|
107
|
+
password: "test"
|
|
108
|
+
|
|
109
|
+
# Common patterns
|
|
110
|
+
common_patterns:
|
|
111
|
+
- "admin:admin"
|
|
112
|
+
- "admin:password"
|
|
113
|
+
- "test:test"
|
|
114
|
+
- "demo:demo"
|
|
115
|
+
- "user:user"
|
|
116
|
+
|
|
117
|
+
# Field name mappings
|
|
118
|
+
field_mappings:
|
|
119
|
+
username_fields: ["uid", "username", "user", "login", "email"]
|
|
120
|
+
password_fields: ["passw", "password", "pass", "pwd"]
|
|
121
|
+
|
|
122
|
+
# Confidence scores
|
|
123
|
+
confidence:
|
|
124
|
+
form_inferred: 0.5
|
|
125
|
+
default_creds: 0.8 # BUG #11 FIX: Increased from 0.6 to 0.8 to ensure default credentials pass filtering
|
|
126
|
+
common_patterns: 0.3
|
|
127
|
+
vuln_context: 0.7
|
|
128
|
+
|
|
129
|
+
agents:
|
|
130
|
+
sqli:
|
|
131
|
+
enabled: true
|
|
132
|
+
databases: [mysql, postgresql, mssql, oracle, mongodb, sqlite] # ENHANCED: Added mssql, oracle, mongodb, sqlite
|
|
133
|
+
attack_types: [boolean, error, union, time, blind, stacked] # ENHANCED: Added union, time, blind, stacked
|
|
134
|
+
attack_mode: balanced
|
|
135
|
+
pentest_mode: true # Depth-first: stop after first SQLi, exploit deep (DB/tables/data extraction)
|
|
136
|
+
xss:
|
|
137
|
+
enabled: true
|
|
138
|
+
contexts: [html, javascript, attribute, url, css, json] # ENHANCED: Added javascript, attribute, url, css, json
|
|
139
|
+
attack_types: [reflected, stored, dom, blind] # ENHANCED: Added stored, dom, blind
|
|
140
|
+
attack_mode: balanced
|
|
141
|
+
pentest_mode: true # Depth-first: stop after first XSS, exploit deep (session hijack/cookie theft)
|
|
142
|
+
csrf:
|
|
143
|
+
enabled: true
|
|
144
|
+
attack_types: [form_submission, json_request, xml_request, multipart, ajax] # ENHANCED: Added json_request, xml_request, multipart, ajax
|
|
145
|
+
attack_mode: balanced
|
|
146
|
+
idor:
|
|
147
|
+
enabled: true
|
|
148
|
+
attack_types: [sequential, uuid, hash, encoded] # ENHANCED: Added uuid, hash, encoded
|
|
149
|
+
attack_mode: balanced
|
|
150
|
+
auth_bypass:
|
|
151
|
+
enabled: true
|
|
152
|
+
attack_types: [brute_force, sql_injection, logic_flaw, default_creds, credential_stuffing, session_hijack, jwt_manipulation] # ENHANCED: Added sql_injection, logic_flaw, default_creds, credential_stuffing, session_hijack, jwt_manipulation
|
|
153
|
+
attack_mode: balanced
|
|
154
|
+
cmdi:
|
|
155
|
+
enabled: true
|
|
156
|
+
attack_types: [time_based, output_based, error_based, blind]
|
|
157
|
+
operating_systems: [linux, windows, unix]
|
|
158
|
+
max_payloads: 100
|
|
159
|
+
time_delay: 5
|
|
160
|
+
attack_mode: balanced
|
|
161
|
+
crawler:
|
|
162
|
+
enabled: true
|
|
163
|
+
report_info_findings: false # Suppress API endpoint/tech fingerprint info findings
|
|
164
|
+
max_depth: 3
|
|
165
|
+
max_pages: 1000
|
|
166
|
+
requests_per_second: 10.0
|
|
167
|
+
|
|
168
|
+
memory:
|
|
169
|
+
agentdb:
|
|
170
|
+
vector_size: 384
|
|
171
|
+
hnsw_m: 16
|
|
172
|
+
hnsw_ef_construction: 200
|
|
173
|
+
quantization_enabled: false
|
|
174
|
+
persistence_path: .agentdb/vectors.db
|
|
175
|
+
use_real_embeddings: true
|
|
176
|
+
embedding_model: sentence-transformers/all-MiniLM-L6-v2
|
|
177
|
+
reasoningbank:
|
|
178
|
+
distillation_frequency: 100
|
|
179
|
+
min_trajectories: 50
|
|
180
|
+
confidence_threshold: 0.7
|
|
181
|
+
persistence_path: .reasoningbank/trajectories.db
|
|
182
|
+
|
|
183
|
+
pretraining:
|
|
184
|
+
enabled: false
|
|
185
|
+
data_directory: data/pretraining
|
|
186
|
+
quality_threshold: 80
|
|
187
|
+
enable_deduplication: true
|
|
188
|
+
enable_cognitive_tagging: true
|
|
189
|
+
|
|
190
|
+
evasion:
|
|
191
|
+
enable_firewall_evasion: false
|
|
192
|
+
enable_waf_bypass: false
|
|
193
|
+
enable_neural_generation: false
|
|
194
|
+
enable_autonomous_learning: false
|
|
195
|
+
timing_mode: sneaky
|
|
196
|
+
fragmentation_mtu: 1500
|
|
197
|
+
max_adaptation_attempts: 3
|
|
198
|
+
|
|
199
|
+
neural:
|
|
200
|
+
enable_neural_generation: false
|
|
201
|
+
enable_autonomous_learning: false
|
|
202
|
+
learning_rate: 0.01
|
|
203
|
+
mutation_count: 10
|
|
204
|
+
|
|
205
|
+
kill_chain:
|
|
206
|
+
phases: [recon, discovery, exploitation]
|
|
207
|
+
|
|
208
|
+
containers:
|
|
209
|
+
image: swarmhack/unified-pentest:latest
|
|
210
|
+
pool_size: 10
|
|
211
|
+
idle_timeout_seconds: 300
|
|
212
|
+
startup_timeout_seconds: 30
|
|
213
|
+
|
|
214
|
+
targets:
|
|
215
|
+
urls: []
|
|
216
|
+
domains: []
|
|
217
|
+
ip_ranges: []
|
|
218
|
+
exclusions: []
|
|
219
|
+
|
|
220
|
+
crown_jewels:
|
|
221
|
+
# ENHANCED: Comprehensive crown jewel detection patterns (4 → 60+ patterns)
|
|
222
|
+
patterns:
|
|
223
|
+
# Credentials & Passwords
|
|
224
|
+
- password
|
|
225
|
+
- passwd
|
|
226
|
+
- pwd
|
|
227
|
+
- pass
|
|
228
|
+
- credential
|
|
229
|
+
- credentials
|
|
230
|
+
- login
|
|
231
|
+
- username
|
|
232
|
+
- user_name
|
|
233
|
+
|
|
234
|
+
# API Keys & Secrets
|
|
235
|
+
- api_key
|
|
236
|
+
- apikey
|
|
237
|
+
- api-key
|
|
238
|
+
- api_secret
|
|
239
|
+
- secret
|
|
240
|
+
- secret_key
|
|
241
|
+
- client_secret
|
|
242
|
+
- app_secret
|
|
243
|
+
|
|
244
|
+
# Tokens & Authentication
|
|
245
|
+
- token
|
|
246
|
+
- access_token
|
|
247
|
+
- refresh_token
|
|
248
|
+
- auth_token
|
|
249
|
+
- bearer
|
|
250
|
+
- jwt
|
|
251
|
+
- session
|
|
252
|
+
- session_id
|
|
253
|
+
- cookie
|
|
254
|
+
- auth_cookie
|
|
255
|
+
|
|
256
|
+
# Private Keys & Certificates
|
|
257
|
+
- private_key
|
|
258
|
+
- privatekey
|
|
259
|
+
- private-key
|
|
260
|
+
- public_key
|
|
261
|
+
- certificate
|
|
262
|
+
- cert
|
|
263
|
+
- encryption_key
|
|
264
|
+
- signing_key
|
|
265
|
+
- ssh_key
|
|
266
|
+
|
|
267
|
+
# Database Connections
|
|
268
|
+
- connection_string
|
|
269
|
+
- db_password
|
|
270
|
+
- database_url
|
|
271
|
+
- database_password
|
|
272
|
+
- mongodb_uri
|
|
273
|
+
- redis_password
|
|
274
|
+
- postgres_password
|
|
275
|
+
- mysql_password
|
|
276
|
+
|
|
277
|
+
# Cloud Provider Credentials
|
|
278
|
+
- aws_access_key
|
|
279
|
+
- aws_secret_key
|
|
280
|
+
- aws_access_key_id
|
|
281
|
+
- aws_secret_access_key
|
|
282
|
+
- s3_bucket
|
|
283
|
+
- iam_role
|
|
284
|
+
- azure_key
|
|
285
|
+
- gcp_key
|
|
286
|
+
- google_api_key
|
|
287
|
+
|
|
288
|
+
# Payment Information
|
|
289
|
+
- credit_card
|
|
290
|
+
- creditcard
|
|
291
|
+
- card_number
|
|
292
|
+
- cvv
|
|
293
|
+
- card_cvv
|
|
294
|
+
- stripe_key
|
|
295
|
+
- paypal
|
|
296
|
+
- payment_token
|
|
297
|
+
|
|
298
|
+
# Personal Identifiable Information (PII)
|
|
299
|
+
- ssn
|
|
300
|
+
- social_security
|
|
301
|
+
- tax_id
|
|
302
|
+
- passport
|
|
303
|
+
- driver_license
|
|
304
|
+
- national_id
|
|
305
|
+
- phone_number
|
|
306
|
+
- email_address
|
|
307
|
+
|
|
308
|
+
# OAuth & Third-party
|
|
309
|
+
- oauth_token
|
|
310
|
+
- oauth_secret
|
|
311
|
+
- client_id
|
|
312
|
+
- client_credentials
|
|
313
|
+
- webhook_secret
|
|
314
|
+
- github_token
|
|
315
|
+
- gitlab_token
|
|
316
|
+
|
|
317
|
+
confidence_threshold: 0.8
|
|
318
|
+
max_extractions: 10000 # ENHANCED: Increased from 1000 to 10000 for comprehensive extraction
|
|
319
|
+
|
|
320
|
+
logging:
|
|
321
|
+
level: info
|
|
322
|
+
format: json
|
|
323
|
+
output_path: logs/swarmhack.log
|
|
324
|
+
|
|
325
|
+
rate_limiting:
|
|
326
|
+
requests_per_second: 10
|
|
327
|
+
burst_size: 20
|
|
328
|
+
algorithm: token_bucket
|
|
329
|
+
retry:
|
|
330
|
+
max_retries: 5
|
|
331
|
+
backoff_base_ms: 1000
|
|
332
|
+
max_backoff_ms: 16000
|
|
333
|
+
jitter_ms: 100
|
|
334
|
+
|
|
335
|
+
# ========== HYBRID MODE CONFIGURATION ==========
|
|
336
|
+
# Orchestrates Kill Chain → Extract Crown Jewels → AEL Amplification workflow
|
|
337
|
+
hybrid_mode:
|
|
338
|
+
# Enable hybrid mode (3-phase workflow)
|
|
339
|
+
enabled: true
|
|
340
|
+
|
|
341
|
+
# Minimum jewels required to trigger AEL phase (if fewer, return Kill Chain results only)
|
|
342
|
+
min_jewels_for_ael: 1
|
|
343
|
+
|
|
344
|
+
# Minimum confidence for extracting jewels from vulnerabilities
|
|
345
|
+
jewel_extraction_confidence_threshold: 0.7
|
|
346
|
+
|
|
347
|
+
# Target amplification factor (logging/metrics only, not enforced)
|
|
348
|
+
amplification_target: 5.0
|
|
349
|
+
|
|
350
|
+
# Vulnerability categories to extract crown jewels from
|
|
351
|
+
extraction_categories:
|
|
352
|
+
- sqli
|
|
353
|
+
- auth_bypass
|
|
354
|
+
- xss
|
|
355
|
+
- idor
|
|
356
|
+
- lfi
|
|
357
|
+
- rce
|
|
358
|
+
|
|
359
|
+
# Kill Chain phase timeout (seconds)
|
|
360
|
+
kill_chain_timeout_secs: 900
|
|
361
|
+
|
|
362
|
+
# AEL phase timeout (seconds)
|
|
363
|
+
ael_phase_timeout_secs: 1200
|
|
364
|
+
|
|
365
|
+
# Enable jewel type conversion (KC jewels → AEL jewels)
|
|
366
|
+
enable_type_conversion: true
|
|
367
|
+
|
|
368
|
+
# Conversion strictness (lenient|moderate|strict)
|
|
369
|
+
conversion_strictness: moderate
|
|
370
|
+
|
|
371
|
+
# Parallel execution for phases
|
|
372
|
+
enable_parallel_execution: true
|
|
373
|
+
|
|
374
|
+
# Deduplicate jewels between phases
|
|
375
|
+
deduplicate_jewels: true
|
|
376
|
+
|
|
377
|
+
# Merge strategy for final results (union|kill_chain_priority|ael_priority)
|
|
378
|
+
result_merge_strategy: union
|
|
379
|
+
|
|
380
|
+
# Report both individual phase results
|
|
381
|
+
report_phase_breakdown: true
|
|
382
|
+
|
|
383
|
+
# ========== EXTRACTION CONFIGURATION ==========
|
|
384
|
+
# SQL Injection Data Extraction System (enabled for testphp.vulnweb.com test)
|
|
385
|
+
extraction:
|
|
386
|
+
enabled: true
|
|
387
|
+
|
|
388
|
+
# Authorized targets for extraction (security control)
|
|
389
|
+
authorized_targets:
|
|
390
|
+
- "testphp.vulnweb.com"
|
|
391
|
+
- "*.vulnweb.com"
|
|
392
|
+
|
|
393
|
+
# Require explicit authorization flag
|
|
394
|
+
require_explicit_authorization: false
|
|
395
|
+
|
|
396
|
+
# Union-based extraction
|
|
397
|
+
union:
|
|
398
|
+
enabled: true
|
|
399
|
+
max_columns: 50
|
|
400
|
+
timeout_seconds: 30
|
|
401
|
+
max_rows: 1000
|
|
402
|
+
|
|
403
|
+
# Error-based extraction
|
|
404
|
+
error:
|
|
405
|
+
enabled: true
|
|
406
|
+
max_extractions: 100
|
|
407
|
+
databases: [mysql, postgresql, mssql]
|
|
408
|
+
timeout_seconds: 20
|
|
409
|
+
|
|
410
|
+
# Blind extraction
|
|
411
|
+
blind:
|
|
412
|
+
enabled: true
|
|
413
|
+
charset: "abcdefghijklmnopqrstuvwxyz0123456789_@.-"
|
|
414
|
+
max_length: 100
|
|
415
|
+
timeout_seconds: 60
|
|
416
|
+
binary_search: true
|
|
417
|
+
|
|
418
|
+
# Performance controls
|
|
419
|
+
max_concurrent_extractions: 3
|
|
420
|
+
total_timeout_seconds: 300
|
|
421
|
+
|
|
422
|
+
# Audit logging
|
|
423
|
+
audit:
|
|
424
|
+
enabled: true
|
|
425
|
+
log_path: logs/extraction_audit.log
|
|
426
|
+
include_data: true
|
|
427
|
+
|
|
428
|
+
# ========== OCSF REPORT OPTIMIZATION ==========
|
|
429
|
+
# Phase 1: Quick wins for report size reduction
|
|
430
|
+
reporting:
|
|
431
|
+
ocsf:
|
|
432
|
+
# Response body truncation (bytes, 0 = no truncation)
|
|
433
|
+
max_response_body_bytes: 500
|
|
434
|
+
|
|
435
|
+
# Verification steps limit (0 = no limit)
|
|
436
|
+
max_verification_steps: 3
|
|
437
|
+
|
|
438
|
+
# Deduplicate similar findings (Phase 2)
|
|
439
|
+
deduplicate_findings: true
|
|
440
|
+
|
|
441
|
+
# Include form fields in per-finding details
|
|
442
|
+
include_form_fields_per_finding: false
|
|
443
|
+
|
|
444
|
+
# Keep only security-relevant HTTP headers
|
|
445
|
+
security_headers_only: true
|
package/index.js
CHANGED
|
@@ -31,10 +31,30 @@ function getBinaryPath() {
|
|
|
31
31
|
throw new Error(`SwarmHack binary not found for ${platform}-${arch}`);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Get path to bundled config file
|
|
36
|
+
*/
|
|
37
|
+
function getConfigPath() {
|
|
38
|
+
// Check for local config first (user's project)
|
|
39
|
+
const localConfig = path.join(process.cwd(), 'config', 'swarmhack.yaml');
|
|
40
|
+
if (fs.existsSync(localConfig)) {
|
|
41
|
+
return localConfig;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Use bundled config from npm package
|
|
45
|
+
const bundledConfig = path.join(__dirname, 'config', 'swarmhack.yaml');
|
|
46
|
+
if (fs.existsSync(bundledConfig)) {
|
|
47
|
+
return bundledConfig;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
34
53
|
/**
|
|
35
54
|
* Run SwarmHack with arguments
|
|
36
55
|
* @param {string[]} args - Command line arguments
|
|
37
56
|
* @param {object} options - Spawn options
|
|
57
|
+
* @param {boolean} options.useConfig - Whether to use bundled config (default: true)
|
|
38
58
|
* @returns {Promise<{code: number, stdout: string, stderr: string}>}
|
|
39
59
|
*/
|
|
40
60
|
function run(args = [], options = {}) {
|
|
@@ -43,7 +63,16 @@ function run(args = [], options = {}) {
|
|
|
43
63
|
const stdout = [];
|
|
44
64
|
const stderr = [];
|
|
45
65
|
|
|
46
|
-
|
|
66
|
+
// Add config flag if not already specified and useConfig is true (default)
|
|
67
|
+
let finalArgs = args;
|
|
68
|
+
if (options.useConfig !== false && !args.includes('--config') && !args.includes('-c')) {
|
|
69
|
+
const configPath = getConfigPath();
|
|
70
|
+
if (configPath) {
|
|
71
|
+
finalArgs = ['--config', configPath, ...args];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const child = spawn(binaryPath, finalArgs, {
|
|
47
76
|
...options,
|
|
48
77
|
env: { ...process.env, ...options.env },
|
|
49
78
|
});
|
|
@@ -134,4 +163,5 @@ module.exports = {
|
|
|
134
163
|
version,
|
|
135
164
|
doctor,
|
|
136
165
|
getBinaryPath,
|
|
166
|
+
getConfigPath,
|
|
137
167
|
};
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swarmhack-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "SwarmHack - Neural swarm-based penetration testing framework",
|
|
5
5
|
"author": "Prancer <support@prancer.io>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
"bin/",
|
|
27
27
|
"scripts/",
|
|
28
|
+
"native/",
|
|
29
|
+
"config/",
|
|
28
30
|
"index.js",
|
|
29
31
|
"README.md"
|
|
30
32
|
],
|
package/scripts/postinstall.js
CHANGED
|
@@ -78,6 +78,23 @@ async function main() {
|
|
|
78
78
|
const platformKey = getPlatformKey();
|
|
79
79
|
const remoteBinary = PLATFORM_MAP[platformKey];
|
|
80
80
|
|
|
81
|
+
const nativeDir = path.join(__dirname, '..', 'native', platformKey);
|
|
82
|
+
const binaryPath = path.join(nativeDir, getBinaryName());
|
|
83
|
+
|
|
84
|
+
// Skip if already exists (bundled in package)
|
|
85
|
+
if (fs.existsSync(binaryPath)) {
|
|
86
|
+
// Make sure it's executable
|
|
87
|
+
if (os.platform() !== 'win32') {
|
|
88
|
+
try {
|
|
89
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
90
|
+
} catch (e) {
|
|
91
|
+
// Ignore permission errors
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
console.log(`✓ SwarmHack binary ready: ${binaryPath}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
81
98
|
if (!remoteBinary) {
|
|
82
99
|
console.log(`
|
|
83
100
|
╔════════════════════════════════════════════════════════════╗
|
|
@@ -98,15 +115,6 @@ async function main() {
|
|
|
98
115
|
return;
|
|
99
116
|
}
|
|
100
117
|
|
|
101
|
-
const nativeDir = path.join(__dirname, '..', 'native', platformKey);
|
|
102
|
-
const binaryPath = path.join(nativeDir, getBinaryName());
|
|
103
|
-
|
|
104
|
-
// Skip if already exists
|
|
105
|
-
if (fs.existsSync(binaryPath)) {
|
|
106
|
-
console.log(`SwarmHack binary already exists: ${binaryPath}`);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
118
|
// Create directory
|
|
111
119
|
fs.mkdirSync(nativeDir, { recursive: true });
|
|
112
120
|
|