stackscan 2.6.3__tar.gz → 2.7.2__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.
Files changed (84) hide show
  1. {stackscan-2.6.3 → stackscan-2.7.2}/PKG-INFO +65 -3
  2. {stackscan-2.6.3 → stackscan-2.7.2}/README.md +62 -0
  3. {stackscan-2.6.3 → stackscan-2.7.2}/pyproject.toml +15 -1
  4. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/__init__.py +1 -1
  5. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/cli.py +295 -61
  6. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/config/__init__.py +10 -1
  7. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/config/sources.py +3 -1
  8. stackscan-2.7.2/src/stackscan/embed.py +387 -0
  9. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/render.py +59 -12
  10. stackscan-2.7.2/src/stackscan/runner.py +286 -0
  11. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/scan.py +30 -10
  12. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/theme.py +2 -30
  13. stackscan-2.7.2/src/stackscan/utils/__init__.py +13 -0
  14. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/utils/urls.py +8 -0
  15. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_brute.py +47 -1
  16. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_cli_helpers.py +9 -1
  17. stackscan-2.7.2/tests/test_embed.py +162 -0
  18. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_ports.py +3 -1
  19. stackscan-2.7.2/tests/test_reekeer_host.py +148 -0
  20. stackscan-2.7.2/tests/test_render.py +46 -0
  21. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_scan.py +50 -0
  22. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_services.py +6 -2
  23. stackscan-2.7.2/tests/test_theme.py +20 -0
  24. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_vhost.py +36 -0
  25. stackscan-2.6.3/src/stackscan/utils/__init__.py +0 -4
  26. stackscan-2.6.3/tests/test_theme.py +0 -26
  27. {stackscan-2.6.3 → stackscan-2.7.2}/.gitignore +0 -0
  28. {stackscan-2.6.3 → stackscan-2.7.2}/LICENSE +0 -0
  29. {stackscan-2.6.3 → stackscan-2.7.2}/scripts/build_cve_db.py +0 -0
  30. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/__main__.py +0 -0
  31. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/__init__.py +0 -0
  32. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/creds.py +0 -0
  33. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/cve.py +0 -0
  34. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/exposure.py +0 -0
  35. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/generic.py +0 -0
  36. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/infra.py +0 -0
  37. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/osdetect.py +0 -0
  38. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/security.py +0 -0
  39. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/services.py +0 -0
  40. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/social.py +0 -0
  41. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/tech.py +0 -0
  42. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/analyzers/vibe.py +0 -0
  43. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/config/sigdb_loader.py +0 -0
  44. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/core/__init__.py +0 -0
  45. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/core/core.py +0 -0
  46. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/data/builtin.sigdb +0 -0
  47. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/data/cve.json.gz +0 -0
  48. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/data/reekeer-logo.png +0 -0
  49. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/data/subdomains.txt +0 -0
  50. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/export.py +0 -0
  51. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/__init__.py +0 -0
  52. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/dns.py +0 -0
  53. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/fingerprint.py +0 -0
  54. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/geo.py +0 -0
  55. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/ipinfo.py +0 -0
  56. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/ports.py +0 -0
  57. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/resolver.py +0 -0
  58. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/subdomains.py +0 -0
  59. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/tld.py +0 -0
  60. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/tls.py +0 -0
  61. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/net/whois.py +0 -0
  62. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/scanners/__init__.py +0 -0
  63. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/scanners/isp_blocked.py +0 -0
  64. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/scanners/secrets.py +0 -0
  65. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/scanners/takeover.py +0 -0
  66. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/types/__init__.py +0 -0
  67. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/types/models.py +0 -0
  68. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/types/output.py +0 -0
  69. {stackscan-2.6.3 → stackscan-2.7.2}/src/stackscan/utils/paths.py +0 -0
  70. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_builtin_sigdb.py +0 -0
  71. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_creds.py +0 -0
  72. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_cve.py +0 -0
  73. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_dns_records.py +0 -0
  74. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_export.py +0 -0
  75. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_extra.py +0 -0
  76. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_infra.py +0 -0
  77. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_osdetect.py +0 -0
  78. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_scanners.py +0 -0
  79. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_social.py +0 -0
  80. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_sources.py +0 -0
  81. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_subdomains.py +0 -0
  82. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_tech.py +0 -0
  83. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_vibe.py +0 -0
  84. {stackscan-2.6.3 → stackscan-2.7.2}/tests/test_whois.py +0 -0
@@ -1,11 +1,11 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: stackscan
3
- Version: 2.6.3
3
+ Version: 2.7.2
4
4
  Summary: Full web stack, infrastructure, DNS, port, subdomain and CVE analyzer.
5
5
  Project-URL: Source, https://github.com/reekeer/stackscan
6
6
  Project-URL: Issues, https://github.com/reekeer/stackscan/issues
7
7
  Author: reekeer team
8
- Maintainer-email: delewer <del@reekeer.hidden>
8
+ Maintainer: delewer
9
9
  License: MIT
10
10
  License-File: LICENSE
11
11
  Keywords: cli,fingerprinting,osint,stack,tech,wappalyzer
@@ -77,6 +77,26 @@ pip install "stackscan[geo]" # offline IP geolocation via geoip2 + a MaxMind .
77
77
  `nmap` is used for port scans when present; without it a pure-Python scanner is
78
78
  used automatically.
79
79
 
80
+ ### Inside the reekeer shell
81
+
82
+ stackscan is also a [reekeer](https://github.com/reekeer/reekeer) plugin, mounted
83
+ at `/tools/recon/stackscan` (alias `ss`):
84
+
85
+ ```bash
86
+ reekeer exec /plugins install reekeer/stackscan
87
+ ```
88
+
89
+ Hosted there it drops the banner and the window title and hands the scan back as
90
+ data for reekeer to render in the shell's own tables, so it reads as a command of
91
+ the shell rather than a script being shelled out to. Every flag behaves the same,
92
+ and standalone (`pip`, `uvx stackscan`) is unchanged.
93
+
94
+ In reekeer's window the scan also gets a form. stackscan says which of its flags
95
+ are worth a control — the targets, the four switches that decide how deep a scan
96
+ goes, and the bounds worth changing when one is too slow — and reekeer draws
97
+ those. The rest are not hidden: the argument line under the form still takes
98
+ anything argparse takes, `--help` included.
99
+
80
100
  ---
81
101
 
82
102
  ## ✨ Features
@@ -194,6 +214,46 @@ Below are performance benchmarks conducted on two production targets using diffe
194
214
 
195
215
  ---
196
216
 
217
+ ## 🛰 Runner mode
218
+
219
+ `stackscan --runner` turns the scanner into a worker for a StackScan panel: it
220
+ claims jobs (`POST /api/jobs/claim`), fingerprints each target with the normal
221
+ engine, and posts the results back (`POST /api/results`). It needs nothing but
222
+ network access to the panel — no database, no Redis, no shared filesystem.
223
+
224
+ ```bash
225
+ STACKSCAN_BACKEND_URL=https://panel.example STACKSCAN_WORKER_TOKEN=… \
226
+ stackscan --runner
227
+ ```
228
+
229
+ | Variable | Default | What it is |
230
+ | --- | --- | --- |
231
+ | `STACKSCAN_BACKEND_URL` | `http://localhost:8787` | Panel base URL |
232
+ | `STACKSCAN_WORKER_TOKEN` | — | Shared worker token, sent as `X-Worker-Token` |
233
+ | `STACKSCAN_RUNNER_ID` | `runner-<host>-<pid>` | Stable id for this runner |
234
+ | `STACKSCAN_RUNNER_BATCH` | `5` | Jobs claimed per cycle |
235
+ | `STACKSCAN_RUNNER_IDLE` | `5` | Seconds to wait when the queue is empty |
236
+ | `STACKSCAN_RUNNER` | — | Truthy value selects runner mode without the flag |
237
+
238
+ Every one has a flag (`--backend`, `--worker-token`, `--runner-id`, `--batch`,
239
+ `--sigdb`, `--user-agent`), and `--once` runs a single claim/scan/report cycle,
240
+ which is what you want in a cron job or a smoke test. The runner profile is
241
+ deliberately lean — DNS, TLS, geo and IP info, no ports, CVEs or brute passes —
242
+ because it is meant for volume rather than depth.
243
+
244
+ Packaged for it:
245
+
246
+ ```bash
247
+ docker build -t stackscan:latest .
248
+ docker run --rm -e STACKSCAN_BACKEND_URL=http://panel:8787 \
249
+ -e STACKSCAN_WORKER_TOKEN=… stackscan:latest
250
+ ```
251
+
252
+ Runner mode is refused inside the reekeer shell: it is a loop that runs until it
253
+ is killed, and a shell command that never answers is not a command.
254
+
255
+ ---
256
+
197
257
  ## 🚀 Smart Scan Pipeline
198
258
 
199
259
  The Smart Scan engine performs multiple analysis stages to collect infrastructure, technology, and security information about the target before generating the final report.
@@ -325,6 +385,8 @@ stackscan/
325
385
  │ ├── config/ ← bundled + sourced sigdb loading
326
386
  │ ├── data/ ← builtin.sigdb, cve.json.gz, subdomains.txt
327
387
  │ ├── render.py ← the colorized panel report
388
+ │ ├── embed.py ← findings as data, and the form, for reekeer to draw
389
+ │ ├── runner.py ← panel worker: claim jobs, scan, report back
328
390
  │ ├── scan.py ← per-target orchestration
329
391
  │ └── cli.py ← argument parsing and entry point
330
392
  ├── scripts/ ← build_cve_db.py (NVD → offline dataset)
@@ -39,6 +39,26 @@ pip install "stackscan[geo]" # offline IP geolocation via geoip2 + a MaxMind .
39
39
  `nmap` is used for port scans when present; without it a pure-Python scanner is
40
40
  used automatically.
41
41
 
42
+ ### Inside the reekeer shell
43
+
44
+ stackscan is also a [reekeer](https://github.com/reekeer/reekeer) plugin, mounted
45
+ at `/tools/recon/stackscan` (alias `ss`):
46
+
47
+ ```bash
48
+ reekeer exec /plugins install reekeer/stackscan
49
+ ```
50
+
51
+ Hosted there it drops the banner and the window title and hands the scan back as
52
+ data for reekeer to render in the shell's own tables, so it reads as a command of
53
+ the shell rather than a script being shelled out to. Every flag behaves the same,
54
+ and standalone (`pip`, `uvx stackscan`) is unchanged.
55
+
56
+ In reekeer's window the scan also gets a form. stackscan says which of its flags
57
+ are worth a control — the targets, the four switches that decide how deep a scan
58
+ goes, and the bounds worth changing when one is too slow — and reekeer draws
59
+ those. The rest are not hidden: the argument line under the form still takes
60
+ anything argparse takes, `--help` included.
61
+
42
62
  ---
43
63
 
44
64
  ## ✨ Features
@@ -156,6 +176,46 @@ Below are performance benchmarks conducted on two production targets using diffe
156
176
 
157
177
  ---
158
178
 
179
+ ## 🛰 Runner mode
180
+
181
+ `stackscan --runner` turns the scanner into a worker for a StackScan panel: it
182
+ claims jobs (`POST /api/jobs/claim`), fingerprints each target with the normal
183
+ engine, and posts the results back (`POST /api/results`). It needs nothing but
184
+ network access to the panel — no database, no Redis, no shared filesystem.
185
+
186
+ ```bash
187
+ STACKSCAN_BACKEND_URL=https://panel.example STACKSCAN_WORKER_TOKEN=… \
188
+ stackscan --runner
189
+ ```
190
+
191
+ | Variable | Default | What it is |
192
+ | --- | --- | --- |
193
+ | `STACKSCAN_BACKEND_URL` | `http://localhost:8787` | Panel base URL |
194
+ | `STACKSCAN_WORKER_TOKEN` | — | Shared worker token, sent as `X-Worker-Token` |
195
+ | `STACKSCAN_RUNNER_ID` | `runner-<host>-<pid>` | Stable id for this runner |
196
+ | `STACKSCAN_RUNNER_BATCH` | `5` | Jobs claimed per cycle |
197
+ | `STACKSCAN_RUNNER_IDLE` | `5` | Seconds to wait when the queue is empty |
198
+ | `STACKSCAN_RUNNER` | — | Truthy value selects runner mode without the flag |
199
+
200
+ Every one has a flag (`--backend`, `--worker-token`, `--runner-id`, `--batch`,
201
+ `--sigdb`, `--user-agent`), and `--once` runs a single claim/scan/report cycle,
202
+ which is what you want in a cron job or a smoke test. The runner profile is
203
+ deliberately lean — DNS, TLS, geo and IP info, no ports, CVEs or brute passes —
204
+ because it is meant for volume rather than depth.
205
+
206
+ Packaged for it:
207
+
208
+ ```bash
209
+ docker build -t stackscan:latest .
210
+ docker run --rm -e STACKSCAN_BACKEND_URL=http://panel:8787 \
211
+ -e STACKSCAN_WORKER_TOKEN=… stackscan:latest
212
+ ```
213
+
214
+ Runner mode is refused inside the reekeer shell: it is a loop that runs until it
215
+ is killed, and a shell command that never answers is not a command.
216
+
217
+ ---
218
+
159
219
  ## 🚀 Smart Scan Pipeline
160
220
 
161
221
  The Smart Scan engine performs multiple analysis stages to collect infrastructure, technology, and security information about the target before generating the final report.
@@ -287,6 +347,8 @@ stackscan/
287
347
  │ ├── config/ ← bundled + sourced sigdb loading
288
348
  │ ├── data/ ← builtin.sigdb, cve.json.gz, subdomains.txt
289
349
  │ ├── render.py ← the colorized panel report
350
+ │ ├── embed.py ← findings as data, and the form, for reekeer to draw
351
+ │ ├── runner.py ← panel worker: claim jobs, scan, report back
290
352
  │ ├── scan.py ← per-target orchestration
291
353
  │ └── cli.py ← argument parsing and entry point
292
354
  ├── scripts/ ← build_cve_db.py (NVD → offline dataset)
@@ -14,7 +14,7 @@ authors = [
14
14
  { name = "reekeer team" }
15
15
  ]
16
16
  maintainers = [
17
- { name = "delewer", email = "del@reekeer.hidden" }
17
+ { name = "delewer" }
18
18
  ]
19
19
 
20
20
  dependencies = [
@@ -67,6 +67,20 @@ Issues = "https://github.com/reekeer/stackscan/issues"
67
67
  [project.scripts]
68
68
  stackscan = "stackscan.cli:main"
69
69
 
70
+ # Mounts stackscan inside the reekeer shell as /recon/stackscan.
71
+ #
72
+ # Not `/tools/recon`: a root that holds every plugin distinguishes none of them, so the category is
73
+ # the top-level group.
74
+ #
75
+ # Name, version, description, authors and dependencies are read from [project] above, so nothing is
76
+ # repeated here. No arguments are declared on purpose: stackscan's own argparse keeps ownership of all
77
+ # of them, including `--help` and the `sigdb` subcommand, and reekeer hands it the raw tokens.
78
+ [tool.reekeer]
79
+ group = "/recon"
80
+ entrypoint = "stackscan.cli:main"
81
+ python-root = "src"
82
+ aliases = ["ss"]
83
+
70
84
  [tool.hatch.version]
71
85
  path = "src/stackscan/__init__.py"
72
86
 
@@ -2,4 +2,4 @@ from .core import StackscanSession
2
2
  from .utils import normalize_url
3
3
 
4
4
  __all__ = ["StackscanSession", "__version__", "normalize_url"]
5
- __version__ = "2.6.3"
5
+ __version__ = "2.7.2"