Skip to content

Commit ac0a64d

Browse files
wiring in
1 parent 5050ee6 commit ac0a64d

65 files changed

Lines changed: 2600 additions & 3130 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.shells.yaml

Lines changed: 8 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,9 @@
1-
logger:
2-
level: "info"
3-
format: "json"
4-
output_paths: ["stdout"]
5-
61
database:
7-
driver: "sqlite3"
8-
dsn: "/opt/shells/shells.db"
9-
max_connections: 10
10-
max_idle_conns: 5
11-
conn_max_lifetime: "1h"
12-
13-
redis:
14-
addr: "localhost:6379"
15-
db: 0
16-
max_retries: 3
17-
dial_timeout: "5s"
18-
read_timeout: "3s"
19-
write_timeout: "3s"
20-
21-
worker:
22-
count: 3
23-
queue_poll_interval: "5s"
24-
max_retries: 3
25-
retry_delay: "10s"
26-
27-
telemetry:
28-
enabled: true
29-
service_name: "shells"
30-
exporter_type: "otlp"
31-
endpoint: "localhost:4317"
32-
sample_rate: 1.0
33-
34-
security:
35-
rate_limit:
36-
requests_per_second: 10
37-
burst_size: 20
38-
enable_auth: false
39-
40-
tools:
41-
nmap:
42-
binary_path: "nmap"
43-
timeout: "30m"
44-
profiles:
45-
default: "-sS -sV -O"
46-
fast: "-T4 -F"
47-
thorough: "-sS -sV -sC -O -A"
48-
49-
ssl:
50-
timeout: "10s"
51-
follow_redirects: true
52-
check_revocation: true
53-
54-
nuclei:
55-
binary_path: "nuclei"
56-
templates_path: ""
57-
timeout: "30m"
58-
rate_limit: 150
59-
bulk_size: 25
60-
concurrency: 25
61-
retries: 2
62-
63-
httpx:
64-
binary_path: "httpx"
65-
timeout: "10s"
66-
threads: 50
67-
rate_limit: 150
68-
retries: 2
69-
follow_redirects: true
70-
probe_all_ips: false
71-
72-
scim:
73-
discovery_timeout: "5m"
74-
max_bulk_operations: 10
75-
test_authentication: true
76-
test_filters: true
77-
test_bulk_ops: true
78-
test_provisions: true
79-
timeout: "30s"
80-
max_retries: 3
81-
user_agent: "shells-scim-scanner/1.0"
82-
follow_redirects: true
83-
verify_ssl: true
84-
85-
smuggling:
86-
techniques: ["cl.te", "te.cl", "te.te", "http2"]
87-
differential_delay: "5s"
88-
max_payload_size: 1048576
89-
timeout: "30s"
90-
max_retries: 3
91-
user_agent: "shells-smuggling-scanner/1.0"
92-
follow_redirects: false
93-
verify_ssl: true
94-
enable_timing_analysis: true
95-
enable_differential_analysis: true
2+
type: sqlite
3+
dsn: "shells_demo.db"
4+
logger:
5+
level: info
6+
format: console
7+
discovery:
8+
timeout: 30s
9+
max_depth: 3

cmd/atomic.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,18 +316,18 @@ Examples:
316316

317317
for _, finding := range findings {
318318
targetObj := atomic.Target{URL: finding.Target, Type: "web"}
319-
319+
320320
// Get techniques for this vulnerability type
321321
mapper := atomic.NewVulnToAttackMapper()
322322
techniques := mapper.GetTechniques(finding.Type)
323-
323+
324324
for _, technique := range techniques {
325325
demo, err := client.DemonstrateImpact(technique, targetObj)
326326
if err != nil {
327327
fmt.Printf("Warning: Could not demonstrate %s for %s: %v\n", technique, finding.Type, err)
328328
continue
329329
}
330-
330+
331331
demonstration := atomic.Demonstration{
332332
Technique: technique,
333333
Name: demo.TestName,

cmd/auth.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ Examples:
8282

8383
// Discover federation providers
8484
domain := extractDomain(target)
85-
85+
8686
// Create HTTP client with timeout
8787
httpClient := &http.Client{
8888
Timeout: 30 * time.Second,
@@ -586,12 +586,12 @@ func saveAuthResultsToDatabase(target string, report *common.AuthReport, scanTyp
586586

587587
// Create scan request
588588
scanRequest := &types.ScanRequest{
589-
ID: uuid.New().String(),
590-
Target: target,
591-
Type: scanType,
592-
Status: types.ScanStatusCompleted,
593-
CreatedAt: report.StartTime,
594-
StartedAt: &report.StartTime,
589+
ID: uuid.New().String(),
590+
Target: target,
591+
Type: scanType,
592+
Status: types.ScanStatusCompleted,
593+
CreatedAt: report.StartTime,
594+
StartedAt: &report.StartTime,
595595
CompletedAt: &report.EndTime,
596596
}
597597

cmd/discover.go

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import (
1111
)
1212

1313
var (
14-
discoverOutput string
15-
discoverVerbose bool
16-
discoverMaxDepth int
14+
discoverOutput string
15+
discoverVerbose bool
16+
discoverMaxDepth int
1717
discoverMaxAssets int
1818
)
1919

@@ -55,41 +55,41 @@ func init() {
5555
// runDiscoveryOnly runs discovery without testing
5656
func runDiscoveryOnly(target string) error {
5757
fmt.Printf("🔍 Starting asset discovery for: %s\n", target)
58-
58+
5959
// Create discovery configuration
6060
config := discovery.DefaultDiscoveryConfig()
6161
config.MaxDepth = discoverMaxDepth
6262
config.MaxAssets = discoverMaxAssets
63-
63+
6464
// Create discovery engine
6565
engine := discovery.NewEngine(config, &DiscoveryLogger{log: log})
66-
66+
6767
// Start discovery
6868
session, err := engine.StartDiscovery(target)
6969
if err != nil {
7070
return fmt.Errorf("failed to start discovery: %w", err)
7171
}
72-
72+
7373
if discoverVerbose {
7474
fmt.Printf("📋 Discovery session: %s\n", session.ID)
7575
fmt.Printf("🎯 Target type: %s\n", session.Target.Type)
7676
fmt.Printf("🎲 Confidence: %.0f%%\n", session.Target.Confidence*100)
7777
}
78-
78+
7979
// Monitor discovery progress
8080
fmt.Println("⏳ Discovery in progress...")
81-
81+
8282
for {
8383
session, err := engine.GetSession(session.ID)
8484
if err != nil {
8585
return fmt.Errorf("failed to get session: %w", err)
8686
}
87-
87+
8888
if discoverVerbose {
89-
fmt.Printf("\r🔄 Progress: %.0f%% | Assets: %d | High-Value: %d",
89+
fmt.Printf("\r🔄 Progress: %.0f%% | Assets: %d | High-Value: %d",
9090
session.Progress, session.TotalDiscovered, session.HighValueAssets)
9191
}
92-
92+
9393
if session.Status == discovery.StatusCompleted {
9494
if discoverVerbose {
9595
fmt.Println("\n✅ Discovery completed!")
@@ -102,16 +102,16 @@ func runDiscoveryOnly(target string) error {
102102
}
103103
return fmt.Errorf("discovery failed")
104104
}
105-
105+
106106
time.Sleep(1 * time.Second)
107107
}
108-
108+
109109
// Get final results
110110
session, err = engine.GetSession(session.ID)
111111
if err != nil {
112112
return fmt.Errorf("failed to get final session: %w", err)
113113
}
114-
114+
115115
// Output results based on format
116116
switch discoverOutput {
117117
case "json":
@@ -125,7 +125,7 @@ func runDiscoveryOnly(target string) error {
125125
func outputDiscoveryText(session *discovery.DiscoverySession) error {
126126
fmt.Printf("\n📊 Discovery Results for: %s\n", session.Target.Value)
127127
fmt.Printf("%s\n\n", strings.Repeat("=", len(session.Target.Value)+25))
128-
128+
129129
fmt.Printf("🎯 Target Information:\n")
130130
fmt.Printf(" Type: %s\n", session.Target.Type)
131131
fmt.Printf(" Confidence: %.0f%%\n", session.Target.Confidence*100)
@@ -135,23 +135,23 @@ func outputDiscoveryText(session *discovery.DiscoverySession) error {
135135
fmt.Printf(" %s: %s\n", key, value)
136136
}
137137
}
138-
138+
139139
fmt.Printf("\n📈 Summary:\n")
140140
fmt.Printf(" Total Assets: %d\n", session.TotalDiscovered)
141141
fmt.Printf(" High-Value Assets: %d\n", session.HighValueAssets)
142142
fmt.Printf(" Relationships: %d\n", len(session.Relationships))
143143
fmt.Printf(" Duration: %v\n", time.Since(session.StartedAt).Round(time.Second))
144-
144+
145145
// Group assets by type
146146
assetsByType := make(map[discovery.AssetType][]*discovery.Asset)
147147
for _, asset := range session.Assets {
148148
assetsByType[asset.Type] = append(assetsByType[asset.Type], asset)
149149
}
150-
150+
151151
// Display assets by type
152152
if len(session.Assets) > 0 {
153153
fmt.Printf("\n🔍 Discovered Assets:\n")
154-
154+
155155
// Order of asset types to display
156156
typeOrder := []discovery.AssetType{
157157
discovery.AssetTypeDomain,
@@ -164,27 +164,27 @@ func outputDiscoveryText(session *discovery.DiscoverySession) error {
164164
discovery.AssetTypePayment,
165165
discovery.AssetTypeAPI,
166166
}
167-
167+
168168
for _, assetType := range typeOrder {
169169
assets := assetsByType[assetType]
170170
if len(assets) == 0 {
171171
continue
172172
}
173-
173+
174174
fmt.Printf("\n %s (%d):\n", assetType, len(assets))
175175
for _, asset := range assets {
176176
priority := ""
177177
if discovery.IsHighValueAsset(asset) {
178178
priority = " 🔥"
179179
}
180-
180+
181181
confidence := ""
182182
if asset.Confidence < 0.8 {
183183
confidence = fmt.Sprintf(" (%.0f%%)", asset.Confidence*100)
184184
}
185-
185+
186186
fmt.Printf(" • %s%s%s\n", asset.Value, confidence, priority)
187-
187+
188188
if discoverVerbose {
189189
if asset.Title != "" {
190190
fmt.Printf(" Title: %s\n", asset.Title)
@@ -201,7 +201,7 @@ func outputDiscoveryText(session *discovery.DiscoverySession) error {
201201
}
202202
}
203203
}
204-
204+
205205
// Display remaining asset types
206206
for assetType, assets := range assetsByType {
207207
found := false
@@ -223,7 +223,7 @@ func outputDiscoveryText(session *discovery.DiscoverySession) error {
223223
}
224224
}
225225
}
226-
226+
227227
// Display high-value assets summary
228228
if session.HighValueAssets > 0 {
229229
fmt.Printf("\n🎯 High-Value Assets:\n")
@@ -236,27 +236,27 @@ func outputDiscoveryText(session *discovery.DiscoverySession) error {
236236
}
237237
}
238238
}
239-
239+
240240
// Display relationships if verbose
241241
if discoverVerbose && len(session.Relationships) > 0 {
242242
fmt.Printf("\n🔗 Asset Relationships:\n")
243243
for _, rel := range session.Relationships {
244244
sourceAsset := session.Assets[rel.Source]
245245
targetAsset := session.Assets[rel.Target]
246246
if sourceAsset != nil && targetAsset != nil {
247-
fmt.Printf(" %s → %s (%s)\n",
247+
fmt.Printf(" %s → %s (%s)\n",
248248
sourceAsset.Value, targetAsset.Value, rel.Type)
249249
}
250250
}
251251
}
252-
252+
253253
fmt.Printf("\n💡 Next Steps:\n")
254254
fmt.Printf(" • Run security tests: shells %s\n", session.Target.Value)
255255
fmt.Printf(" • View specific assets: shells discover %s --verbose\n", session.Target.Value)
256256
if session.HighValueAssets > 0 {
257257
fmt.Printf(" • Focus on high-value assets for manual testing\n")
258258
}
259-
259+
260260
return nil
261261
}
262262

@@ -282,12 +282,12 @@ func outputDiscoveryJSON(session *discovery.DiscoverySession) error {
282282
"started_at": session.StartedAt,
283283
"completed_at": session.CompletedAt,
284284
}
285-
285+
286286
jsonData, err := json.MarshalIndent(result, "", " ")
287287
if err != nil {
288288
return fmt.Errorf("failed to marshal JSON: %w", err)
289289
}
290-
290+
291291
fmt.Println(string(jsonData))
292292
return nil
293-
}
293+
}

0 commit comments

Comments
 (0)