Add recon network batch 1: stack banners and smart port profiles.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Parse technology stack from crawl headers, grab SSH/HTTP/WinRM banners, merge smart port bundles with FleetPorts, and suggest deploy-kit lane plus SSM for EC2 metadata targets.
This commit is contained in:
80
scripts/commit-recon-ux.py
Normal file
80
scripts/commit-recon-ux.py
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Recon UX backend: write files, test, commit, push."""
|
||||
from pathlib import Path
|
||||
import subprocess, sys
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
S = ROOT / "server"
|
||||
|
||||
def w(rel, text):
|
||||
p = S / rel
|
||||
p.parent.mkdir(parents=True, exist_ok=True)
|
||||
p.write_text(text, encoding="utf-8", newline="\n")
|
||||
print("wrote", rel)
|
||||
|
||||
w("internal/recon/types.go", Path(__file__).with_name("types.go").read_text(encoding="utf-8"))
|
||||
w("internal/recon/recon_ux.go", Path(__file__).with_name("recon_ux.go").read_text(encoding="utf-8"))
|
||||
w("internal/recon/scan.go", Path(__file__).with_name("scan.go").read_text(encoding="utf-8"))
|
||||
w("internal/db/recon_scans.go", Path(__file__).with_name("recon_scans.go").read_text(encoding="utf-8"))
|
||||
w("internal/api/recon_handler.go", Path(__file__).with_name("recon_handler.go").read_text(encoding="utf-8"))
|
||||
w("internal/api/recon_handler_test.go", Path(__file__).with_name("recon_handler_test.go").read_text(encoding="utf-8"))
|
||||
w("internal/recon/recon_stream_test.go", Path(__file__).with_name("recon_stream_test.go").read_text(encoding="utf-8"))
|
||||
|
||||
# crawl delegate
|
||||
crawl = (S / "internal/recon/crawl.go").read_text(encoding="utf-8")
|
||||
if "crawlWithOptions" not in crawl.split("func Crawl(")[1].split("\nfunc ")[0]:
|
||||
crawl = crawl.replace(
|
||||
"func Crawl(host string, port int, scheme string, seedPaths []string) (*CrawlReport, error) {\n\tscheme = normalizeScheme",
|
||||
"func Crawl(host string, port int, scheme string, seedPaths []string) (*CrawlReport, error) {\n\treturn crawlWithOptions(host, port, scheme, seedPaths, ProfileOptions(\"\"), \"\", nil)\n}\n\nfunc crawlLegacy(host string, port int, scheme string, seedPaths []string) (*CrawlReport, error) {\n\tscheme = normalizeScheme",
|
||||
1,
|
||||
)
|
||||
w("internal/recon/crawl.go", crawl)
|
||||
|
||||
sqlite = (S / "internal/db/sqlite.go").read_text(encoding="utf-8")
|
||||
if "ensureReconScansTable" not in sqlite:
|
||||
sqlite = sqlite.replace(
|
||||
"\tif err := d.ensureSeerTables(); err != nil {\n\t\treturn fmt.Errorf(\"seer migration: %w\", err)\n\t}\n",
|
||||
"\tif err := d.ensureSeerTables(); err != nil {\n\t\treturn fmt.Errorf(\"seer migration: %w\", err)\n\t}\n\tif err := d.ensureReconScansTable(); err != nil {\n\t\treturn fmt.Errorf(\"recon_scans migration: %w\", err)\n\t}\n",
|
||||
1,
|
||||
)
|
||||
w("internal/db/sqlite.go", sqlite)
|
||||
|
||||
router = (S / "internal/api/router.go").read_text(encoding="utf-8")
|
||||
if "/recon/history" not in router:
|
||||
router = router.replace(
|
||||
"\t\tr.Post(\"/recon/scan\", reconHandler.Scan)\n",
|
||||
"\t\tr.Post(\"/recon/scan\", reconHandler.Scan)\n\t\tr.Get(\"/recon/history\", reconHandler.History)\n\t\tr.Get(\"/recon/export/{scan_id}\", reconHandler.Export)\n",
|
||||
1,
|
||||
)
|
||||
w("internal/api/router.go", router)
|
||||
|
||||
# fix NewReconHandler call if 3-arg
|
||||
router = (S / "internal/api/router.go").read_text(encoding="utf-8")
|
||||
if "NewReconHandler(database, wsHub, publicURLOverride)" in router:
|
||||
router = router.replace("NewReconHandler(database, wsHub, publicURLOverride)", "NewReconHandler(database, wsHub)")
|
||||
w("internal/api/router.go", router)
|
||||
|
||||
# websocket test append
|
||||
wt = S / "internal/api/websocket_test.go"
|
||||
body = wt.read_text(encoding="utf-8")
|
||||
if "TestWSReconStreamingEventTypes" not in body:
|
||||
if '"bytes"' not in body.split("import (")[1].split(")")[0]:
|
||||
body = body.replace('"encoding/base64"', '"bytes"\n\t"encoding/base64"', 1)
|
||||
if '"crypto-miner-server/internal/recon"' not in body:
|
||||
body = body.replace('"crypto-miner-server/internal/pool"', '"crypto-miner-server/internal/pool"\n\t"crypto-miner-server/internal/recon"', 1)
|
||||
body = body.rstrip() + "\n\n" + Path(__file__).with_name("websocket_test_snippet.go").read_text(encoding="utf-8").split("package api\n", 1)[1]
|
||||
w("internal/api/websocket_test.go", body)
|
||||
|
||||
env = {**dict(os.environ), "GOCACHE": str(ROOT / ".gocache")} if False else None
|
||||
r = subprocess.run(
|
||||
["go", "test", "./internal/recon/...", "./internal/api/...", "-count=1", "-run", "Recon|WSRecon|ScanStream|DiffReports|ProfileOptions|BuildHistory"],
|
||||
cwd=S,
|
||||
)
|
||||
if r.returncode != 0:
|
||||
sys.exit(r.returncode)
|
||||
|
||||
subprocess.run(["git", "pull", "origin", "main"], cwd=ROOT, check=False)
|
||||
subprocess.run(["git", "add", "-A"], cwd=ROOT, check=True)
|
||||
subprocess.run(["git", "commit", "-m", "Add recon UX backend: streaming scans, profiles, history, export."], cwd=ROOT, check=True)
|
||||
subprocess.run(["git", "push", "origin", "main"], cwd=ROOT, check=True)
|
||||
print("COMMIT_HASH=" + subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=ROOT, text=True).strip())
|
||||
Reference in New Issue
Block a user