gates / gates (push) Successful in 1m56s
Evidence audits/night-fixes-2026-10-26/ (scanned: 0 secret hits).
126 lines
6.4 KiB
Python
126 lines
6.4 KiB
Python
#!/usr/bin/env python3
|
|
"""r1187_r1220_live.py — R-1220 and R-1187 (a)(b) live on scratch guest 9202, through the endpoints the UI invokes.
|
|
|
|
A THROWAWAY Grimmory (drive appdata binds). Steps:
|
|
1. install; a marker folder in its drive appdata: an owned file (1000:1001, 0640), a link inside, a link outside;
|
|
2. R-1220: its app.yaml made unreadable (a byte copy saved first) → after a stack rescan the „Megőrzött adatok" page does
|
|
NOT list its folder; the app.yaml put back byte-identical;
|
|
3. R-1187 (a): a FIFO in the folder → the export FAILS naming the FIFO's path; the FIFO removed;
|
|
4. R-1187 (a)(b): export → import over the running app → the owned file keeps owner and mode, the inside link comes
|
|
back, the outside link is refused (listed in the controller WARN);
|
|
5. teardown: the app removed through the product (data and backups), the bundles this run made deleted.
|
|
|
|
usage: SC=<0600 dir with .ctlpw> SWEEP_EV=<evidence dir> TARGET=9202 DRIVE_ROOT=/mnt/felhom-drives/scratch_hdd python3 -u r1187_r1220_live.py
|
|
"""
|
|
import os
|
|
import signal
|
|
import sys
|
|
import time
|
|
|
|
signal.signal(signal.SIGTERM, lambda *a: (_ for _ in ()).throw(SystemExit("SIGTERM — cleaning up")))
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../catalog-sweep-2026-10-24/tools"))
|
|
import sweep as sw # noqa: E402
|
|
|
|
w = sw.w
|
|
APP, SUB, DRIVE = "grimmory", "grimd53", os.environ.get("DRIVE_ROOT", "/mnt/felhom-drives/scratch_hdd")
|
|
say = print
|
|
|
|
|
|
def g(cmd):
|
|
return sw.g(cmd).strip()
|
|
|
|
|
|
def job(kind):
|
|
path = "/api/export/status" if kind == "export" else "/api/export/import/status"
|
|
for _ in range(180):
|
|
time.sleep(5)
|
|
code, d = w.ctl("GET", path)
|
|
j = d.get("data", d) if isinstance(d, dict) else {}
|
|
if j.get("done") or j.get("Done"):
|
|
return j
|
|
return {"timeout": True}
|
|
|
|
|
|
def scan_after(since):
|
|
"""Wait for a stack rescan that started after `since` (the controller rescans on its own every ~2 min)."""
|
|
for _ in range(40):
|
|
time.sleep(10)
|
|
if g(f"docker logs --since {since} felhom-controller 2>&1 | grep -c 'ScanStacks complete'") not in ("", "0"):
|
|
return True
|
|
return False
|
|
|
|
|
|
def main():
|
|
w.say = say
|
|
w.login()
|
|
try:
|
|
ok = w.deploy(APP, SUB, {"HDD_PATH": DRIVE}) and w.wait_app(SUB, "/", tries=90, delay=5)
|
|
say("1. grimmory installed and answering:", ok)
|
|
appdata = g(f"ls -d {DRIVE}/appdata/grimmory 2>/dev/null | head -1")
|
|
say(" its appdata folder:", appdata or "(not found)")
|
|
if not appdata:
|
|
raise SystemExit("INSTRUMENT: no appdata folder — no verdict")
|
|
m = f"{appdata}/data/cc-r1187" # INSIDE the bound folder (appdata/grimmory/data) — the export packs only binds
|
|
say(" markers:", g(f"mkdir -p {m} && printf hi > {m}/owned.txt && chown 1000:1001 {m}/owned.txt && chmod 0640 {m}/owned.txt"
|
|
f" && ln -sfn owned.txt {m}/link-in && ln -sfn /etc/hostname {m}/link-out && ls -ln {m} | tail -n +2"))
|
|
|
|
# 2. R-1220 (SKIP_R1220=1: already proven in the first run, `r1187-r1220-9202-run1.txt`)
|
|
if os.environ.get("SKIP_R1220"):
|
|
say("2. R-1220 skipped (proven in the first run)")
|
|
else:
|
|
stack = f"/opt/docker/stacks/{APP}"
|
|
g(f"cp -p {stack}/app.yaml /root/r1220-app.yaml.save && printf 'deployed: true\\nenv: [broken: yaml: here\\n' > {stack}/app.yaml")
|
|
t = int(time.time())
|
|
say("2. app.yaml made unreadable; rescan seen:", scan_after(t))
|
|
page = w.page("/kept-data")
|
|
say(" R-1220: the kept-data page lists grimmory's folder:", appdata in page, "(want False) | WARN lines:",
|
|
g(f"docker logs --since {t} felhom-controller 2>&1 | grep -c 'R-1220'"))
|
|
g(f"cp -p /root/r1220-app.yaml.save {stack}/app.yaml && rm -f /root/r1220-app.yaml.save")
|
|
say(" app.yaml put back, byte check:", g(f"sha256sum {stack}/app.yaml | cut -c1-16"))
|
|
scan_after(int(time.time()))
|
|
|
|
# 3. R-1187 (a) FIFO
|
|
g(f"mkfifo {m}/pipe")
|
|
code, d = w.ctl("POST", "/api/export/start", {"stack_name": APP, "dest_drive": DRIVE, "stop_app": False})
|
|
say("3. export with a FIFO ->", code, str(d)[:160])
|
|
if code != "200":
|
|
raise SystemExit("INSTRUMENT: the export start was refused — no verdict")
|
|
j = job("export")
|
|
say(" job:", str(j.get("error") or j.get("Error") or j)[:300])
|
|
g(f"rm -f {m}/pipe")
|
|
if j.get("timeout"):
|
|
raise SystemExit("INSTRUMENT: the export job never ended — no verdict")
|
|
|
|
# 4. R-1187 (a)(b) round trip
|
|
code, d = w.ctl("POST", "/api/export/start", {"stack_name": APP, "dest_drive": DRIVE, "stop_app": False})
|
|
say("4. export ->", code, str(d)[:120])
|
|
if code != "200":
|
|
raise SystemExit("INSTRUMENT: the export start was refused — no verdict")
|
|
j = job("export")
|
|
say(" job:", str(j)[:300])
|
|
fab = g(f"ls -t {DRIVE}/exports/grimmory*.fab 2>/dev/null | head -1")
|
|
say(" bundle:", fab)
|
|
say(" tar listing of the drive part:", g(f"mkdir -p /root/r1187x && cd /root/r1187x && tar -xzf {fab} data/hdd 2>/dev/null; "
|
|
f"for f in data/hdd/*.tar; do tar -tvf $f | grep cc-r1187; done; rm -rf /root/r1187x"))
|
|
g(f"rm -rf {m}") # the import must bring it back
|
|
ti = int(time.time())
|
|
code, d = w.ctl("POST", "/api/export/import", {"path": fab})
|
|
say(" import ->", code, str(d)[:160])
|
|
if code != "200":
|
|
raise SystemExit("INSTRUMENT: the import start was refused — no verdict")
|
|
j = job("import")
|
|
say(" import job:", str(j)[:300])
|
|
say(" after import:", g(f"ls -ln {m} | tail -n +2; stat -c '%n %u:%g %a' {m}/owned.txt; readlink {m}/link-in; "
|
|
f"ls -l {m}/link-out 2>&1 | head -1"))
|
|
say(" the import's WARN:", g(f"docker logs --since {ti} felhom-controller 2>&1 | grep 'R-1187 b' | cut -c1-220"))
|
|
say(" the app answers:", w.wait_app(SUB, "/", tries=60, delay=5))
|
|
finally:
|
|
sw.remove(APP, keep=False, say=say)
|
|
say("5. leftovers:", sw.leftovers(APP, SUB))
|
|
say(" bundles of this run removed:", g(f"ls {DRIVE}/exports/grimmory*.fab 2>/dev/null; rm -f {DRIVE}/exports/grimmory*.fab; ls {DRIVE}/exports/ 2>/dev/null | grep -c grimmory"))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|