Repository navigation
Expand file tree
/
Copy pathscan_pool.py
More file actions
116 lines (99 loc) · 2.61 KB
/
Copy pathscan_pool.py
File metadata and controls
116 lines (99 loc) · 2.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""ScanPool example — async continuous dynamic scanning from Python."""
import asyncio
from nucleisdk import ScanEngine, TemplateBytesEntry
# Simulated vulnerability feed items
vuln_feed = [
{
"target": "https://example.com",
"cve_id": "CVE-2024-1234",
"template": b"""
id: CVE-2024-1234
info:
name: Example RCE
severity: critical
author: scanner
tags: cve,rce
http:
- method: GET
path:
- "{{BaseURL}}/api/debug"
matchers:
- type: word
words:
- "stack trace"
""",
},
{
"target": "https://example.com",
"cve_id": "CVE-2024-5678",
"template": b"""
id: CVE-2024-5678
info:
name: Example SSRF
severity: high
author: scanner
tags: cve,ssrf
http:
- method: GET
path:
- "{{BaseURL}}/webhook?url=http://example.com-ip"
matchers:
- type: word
words:
- "ami-id"
""",
},
]
async def main():
# Setup engine once
engine = ScanEngine(
rate_limit=100,
timeout=10,
no_interactsh=True,
silent=True,
)
await engine.setup()
# Create pool with 5 workers
pool = await engine.scan_pool(workers=5)
# Consume results in background
consumer = asyncio.create_task(consume_results(pool))
# Submit jobs dynamically (simulating a vuln feed)
for item in vuln_feed:
await pool.submit(
label=item["cve_id"],
targets=[item["target"]],
template_bytes=[
TemplateBytesEntry(name=item["cve_id"], data=item["template"])
],
)
print(f"Submitted: {item['cve_id']} -> {item['target']}")
# Also submit a filter-based scan
await pool.submit(
label="Tech scan",
targets=["https://example.com"],
tags=["tech"],
protocol_types="http",
)
print("Submitted: Tech scan")
# Close pool (waits for all jobs to finish)
await pool.close()
# Wait for result consumer
await consumer
# Print stats
stats = await pool.stats()
print(f"\n--- Pool Stats ---")
print(f" Submitted: {stats.submitted}")
print(f" Completed: {stats.completed}")
print(f" Failed: {stats.failed}")
print(f" Pending: {stats.pending}")
await engine.close()
async def consume_results(pool):
"""Read and print results from the pool."""
async for lr in pool.results():
r = lr.result
if r.error:
print(f" [{lr.label}] ERROR: {r.error}")
else:
print(f" [{lr.label}] [{r.severity}] {r.template_id} - {r.matched_url}")
if __name__ == "__main__":
asyncio.run(main())