"""GTFOBins check behaviour (rollup vs detailed, absent list toggle).""" from __future__ import annotations from pathlib import Path from applepy.checks import catalogues from applepy.context import RunContext def _minimal_ctx(tmp_path: Path) -> RunContext: return RunContext(home=tmp_path, output_dir=tmp_path, phase="unprivileged", dry_run=False) def test_check_gtfo_no_absent_finding_by_default(monkeypatch, tmp_path: Path) -> None: monkeypatch.delenv("APPLEPY_GTFO_LIST_ABSENT", raising=False) monkeypatch.delenv("APPLEPY_GTFO_DETAILED", raising=False) monkeypatch.delenv("APPLEPY_SKIP_CATALOG_FETCH", raising=False) data = { "executables": { "true": {"functions": {"Shell": {}}}, "missingbin_xyz": {"functions": {"Shell": {}}}, } } monkeypatch.setattr(catalogues, "fetch_json_url", lambda _url: (data, "ok")) def resolve(name: str, _pe: str) -> str | None: return "/bin/true" if name == "true" else None monkeypatch.setattr(catalogues, "_resolve_binary_path", resolve) out = catalogues.check_gtfo(_minimal_ctx(tmp_path)) assert not any(f.id == "gtfo-absent-all" for f in out) assert not any(f.id.startswith("gtfo-api-") for f in out) lol2 = next(f for f in out if f.id == "lol-002") assert "true" in lol2.evidence assert "not_found=1" in lol2.evidence def test_check_gtfo_absent_when_env_set(monkeypatch, tmp_path: Path) -> None: monkeypatch.setenv("APPLEPY_GTFO_LIST_ABSENT", "1") monkeypatch.delenv("APPLEPY_GTFO_DETAILED", raising=False) monkeypatch.delenv("APPLEPY_SKIP_CATALOG_FETCH", raising=False) data = {"executables": {"onlymissing": {"functions": {"Shell": {}}}}} monkeypatch.setattr(catalogues, "fetch_json_url", lambda _url: (data, "ok")) monkeypatch.setattr(catalogues, "_resolve_binary_path", lambda _n, _pe: None) out = catalogues.check_gtfo(_minimal_ctx(tmp_path)) absent = next(f for f in out if f.id == "gtfo-absent-all") assert "onlymissing" in absent.evidence def test_check_gtfo_detailed_emits_per_binary(monkeypatch, tmp_path: Path) -> None: monkeypatch.setenv("APPLEPY_GTFO_DETAILED", "1") monkeypatch.delenv("APPLEPY_GTFO_LIST_ABSENT", raising=False) monkeypatch.delenv("APPLEPY_SKIP_CATALOG_FETCH", raising=False) data = {"executables": {"true": {"functions": {"Shell": {}}}}} monkeypatch.setattr(catalogues, "fetch_json_url", lambda _url: (data, "ok")) monkeypatch.setattr(catalogues, "_resolve_binary_path", lambda _n, _pe: "/bin/true") out = catalogues.check_gtfo(_minimal_ctx(tmp_path)) assert any(f.id == "gtfo-api-true" for f in out)