aegis-rex 1.5.1 → 1.5.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/package.json +1 -1
- package/vendor/rex.py +38 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aegis-rex",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Headless-drivable security auditor for Linux, macOS and Windows. Runs a 17-check local audit and can be driven by an AI agent (--capabilities / --audit --json / --fix). npm is the distribution channel; the tool itself is dependency-free Python.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"rex": "bin/rex.js"
|
package/vendor/rex.py
CHANGED
|
@@ -118,7 +118,7 @@ IS_LINUX = _OS == "Linux"
|
|
|
118
118
|
# ============================================================
|
|
119
119
|
# KONFIGURATION
|
|
120
120
|
# ============================================================
|
|
121
|
-
VERSION = "1.5.
|
|
121
|
+
VERSION = "1.5.2"
|
|
122
122
|
APP_NAME = "ÆGIS Security Audit"
|
|
123
123
|
|
|
124
124
|
# Lines emitted by find(1)/stat(1) *about* a path rather than *as a result*.
|
|
@@ -714,24 +714,45 @@ class AuditEngine:
|
|
|
714
714
|
return status, out or "No world-accessible binaries found in System32"
|
|
715
715
|
|
|
716
716
|
else: # Linux + macOS
|
|
717
|
-
|
|
717
|
+
# Where a distro's package manager is allowed to drop a
|
|
718
|
+
# SUID/SGID binary. A stock Ubuntu box carries ~30 helpers in
|
|
719
|
+
# /usr/bin and /usr/lib (sudo, passwd, mount, su, pkexec …);
|
|
720
|
+
# reporting that inventory as a defect buries the one binary
|
|
721
|
+
# that was actually put there by hand. So the bit itself is
|
|
722
|
+
# inventoried, and only *where* it was found decides the status.
|
|
723
|
+
managed_dirs = (
|
|
724
|
+
"/usr/bin/", "/usr/sbin/", "/usr/lib/", "/usr/lib32/",
|
|
725
|
+
"/usr/lib64/", "/usr/libexec/", "/bin/", "/sbin/",
|
|
726
|
+
"/lib/", "/lib32/", "/lib64/",
|
|
727
|
+
)
|
|
718
728
|
if IS_MAC:
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
729
|
+
managed_dirs = ("/usr/bin/", "/usr/sbin/", "/usr/lib/",
|
|
730
|
+
"/usr/libexec/", "/bin/", "/sbin/", "/System/")
|
|
731
|
+
# /home is deliberately absent: a recursive scan of home dirs
|
|
732
|
+
# exceeded 120s on a real machine, and an audit that stalls is
|
|
733
|
+
# worse than one with a stated scope. The remaining roots are
|
|
734
|
+
# sub-second.
|
|
735
|
+
scan_roots = ["/usr", "/bin", "/sbin", "/lib", "/lib64",
|
|
736
|
+
"/usr/local", "/opt", "/tmp", "/var/tmp"]
|
|
737
|
+
existing = [p for p in scan_roots if os.path.isdir(p)]
|
|
738
|
+
out = cmd(["find"] + existing + ["-perm", "/6000", "-type", "f"], timeout=25)
|
|
722
739
|
real, noise = self._split_noise(out)
|
|
723
|
-
if
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
740
|
+
managed = [f for f in real if f.startswith(managed_dirs)]
|
|
741
|
+
unexpected = [f for f in real if not f.startswith(managed_dirs)]
|
|
742
|
+
suffix = f"\n({len(noise)} path(s) not readable, skipped)" if noise else ""
|
|
743
|
+
if unexpected:
|
|
744
|
+
lines = unexpected[:30]
|
|
745
|
+
body = "\n".join(lines)
|
|
746
|
+
if len(unexpected) > 30:
|
|
747
|
+
body += f"\n[truncated at 30 of {len(unexpected)} results]"
|
|
748
|
+
if managed:
|
|
749
|
+
body += (f"\n({len(managed)} SUID/SGID binary(ies) under "
|
|
750
|
+
f"distro-managed paths, expected inventory)")
|
|
751
|
+
return "warn", body + suffix
|
|
752
|
+
if managed:
|
|
753
|
+
return "ok", (f"{len(managed)} SUID/SGID binaries found, all under "
|
|
754
|
+
f"distro-managed paths (expected inventory)" + suffix)
|
|
755
|
+
return "ok", "No SUID/SGID files found in scanned paths" + suffix
|
|
735
756
|
|
|
736
757
|
# ── World-Writable Files ──────────────────────────────
|
|
737
758
|
elif section == "World-Writable Files":
|