@murk-security/runner-darwin-x64 0.8.0 → 0.8.2
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/bin/harness +0 -0
- package/package.json +1 -1
- package/runners/basic_harness_run.py +37 -2
package/bin/harness
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -30,6 +30,7 @@ import json
|
|
|
30
30
|
import os
|
|
31
31
|
import re
|
|
32
32
|
import signal
|
|
33
|
+
import socket
|
|
33
34
|
import sqlite3
|
|
34
35
|
import subprocess
|
|
35
36
|
import sys
|
|
@@ -91,10 +92,12 @@ SCAN_PROFILES: dict[str, dict] = {
|
|
|
91
92
|
"orchestrator": DEFAULT_ORCHESTRATOR, # council
|
|
92
93
|
"coord_model": DEFAULT_COORD_MODEL, # kimi-k3 at the synthesis locus
|
|
93
94
|
"orch_model": DEFAULT_ORCH_MODEL, # glm-5.3 council chair + members
|
|
94
|
-
"teams": "
|
|
95
|
-
"max_cost": "
|
|
95
|
+
"teams": "7", "cells": "4", "team_calls": "60", "workers": "12",
|
|
96
|
+
"max_cost": "20", "default_minutes": 30.0,
|
|
96
97
|
},
|
|
97
98
|
}
|
|
99
|
+
# NOTE: the Full time box (30 min) is mirrored in the CLI's buildLocalSpec and the dashboard's
|
|
100
|
+
# DEFAULT_DURATION so hosted and local runs match; keep the three in sync.
|
|
98
101
|
|
|
99
102
|
|
|
100
103
|
def scan_profile_for(spec: dict) -> tuple[str, dict]:
|
|
@@ -959,6 +962,23 @@ def _run_remediate(spec: dict, em: "Emitter") -> int:
|
|
|
959
962
|
return 0
|
|
960
963
|
|
|
961
964
|
|
|
965
|
+
def _target_listening(origin: str, timeout: float = 6.0) -> bool:
|
|
966
|
+
"""Whether something is listening at the origin's host:port (a quick TCP connect). A refused or
|
|
967
|
+
timed-out connect means the app isn't running there, so the scan would hunt against nothing and
|
|
968
|
+
report no findings -- which reads as 'found nothing' rather than 'nothing was there'. An
|
|
969
|
+
unparseable origin returns True (don't block on a parse failure)."""
|
|
970
|
+
try:
|
|
971
|
+
u = urlparse(origin if "//" in origin else "http://" + origin)
|
|
972
|
+
host = u.hostname or ""
|
|
973
|
+
port = u.port or (443 if u.scheme == "https" else 80)
|
|
974
|
+
if not host:
|
|
975
|
+
return True
|
|
976
|
+
with socket.create_connection((host, port), timeout=timeout):
|
|
977
|
+
return True
|
|
978
|
+
except Exception:
|
|
979
|
+
return False
|
|
980
|
+
|
|
981
|
+
|
|
962
982
|
def main() -> int:
|
|
963
983
|
ap = argparse.ArgumentParser()
|
|
964
984
|
ap.add_argument("--spec", required=True)
|
|
@@ -1015,6 +1035,21 @@ def main() -> int:
|
|
|
1015
1035
|
em.emit("run.completed", {"stop": "halt", "findings": 0, "ok": True,
|
|
1016
1036
|
"message": "no findings with a reproduction recipe to retest"})
|
|
1017
1037
|
return 0
|
|
1038
|
+
# Fail fast if a live target isn't actually up. Otherwise the whole hunt runs against a dead
|
|
1039
|
+
# origin and reports no findings, which reads as "the scanner found nothing" rather than
|
|
1040
|
+
# "nothing was running there to scan". The `murk scan` CLI pre-checks before booking a local
|
|
1041
|
+
# run; this covers hosted runs and is a backstop for local. Skippable for tests/dev.
|
|
1042
|
+
_live_origins = (spec.get("target") or {}).get("origins") or []
|
|
1043
|
+
if kind == "assess" and _live_origins and os.environ.get("BASIC_HARNESS_SKIP_REACHABILITY") != "1":
|
|
1044
|
+
if all(not _target_listening(o) for o in _live_origins):
|
|
1045
|
+
em.emit("run.failed", {
|
|
1046
|
+
"category": "target",
|
|
1047
|
+
"message": ("couldn't reach the target (" + ", ".join(_live_origins) + ") — is the "
|
|
1048
|
+
"application running and listening there? No scan was performed."),
|
|
1049
|
+
"stop": "unreachable",
|
|
1050
|
+
})
|
|
1051
|
+
return 4
|
|
1052
|
+
|
|
1018
1053
|
goal = build_retest_brief(retest_findings) if kind == "retest" else build_brief(spec)
|
|
1019
1054
|
rounds = (os.environ.get("BASIC_HARNESS_RETEST_ROUNDS", "1") if kind == "retest"
|
|
1020
1055
|
else os.environ.get("BASIC_HARNESS_ROUNDS", "3"))
|