mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-27 20:29:39 +02:00
[pitboss] phase 18: Track E.2 — macOS sandbox-exec backend
This commit is contained in:
parent
b127ea2832
commit
6ca9bddedb
12 changed files with 921 additions and 2 deletions
34
src/dynamic/sandbox_profiles/base.sb
Normal file
34
src/dynamic/sandbox_profiles/base.sb
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
;; Phase 18 (Track E.2) — base sandbox-exec profile.
|
||||
;;
|
||||
;; macOS interpreters (python3, node, ruby, java) need access to a wide
|
||||
;; surface of user-level frameworks, caches, and mach services that a
|
||||
;; deny-default profile cannot enumerate without breaking cold-start.
|
||||
;; The pragmatic baseline used here is `allow default` plus a targeted
|
||||
;; deny set covering filesystem-escape paths the dynamic verifier
|
||||
;; specifically wants to confine:
|
||||
;;
|
||||
;; * `/etc/passwd` + `/private/etc/passwd` — the canonical "did you
|
||||
;; escape the sandbox?" file used by path-traversal payloads.
|
||||
;; * `/etc/master.passwd` + shadow files.
|
||||
;; * `/etc/shadow` (Linux convention, present via openssh on some hosts).
|
||||
;;
|
||||
;; Per-cap profiles compose by `(import "base.sb")` and adding caps' own
|
||||
;; deny / allow rules. Apple's `sandbox-exec(1)` resolves imports
|
||||
;; relative to `/usr/share/sandbox` so we hand absolute paths via
|
||||
;; `-f <abs path>` and skip `(import ...)` for portability across CI
|
||||
;; images.
|
||||
|
||||
(version 1)
|
||||
(allow default)
|
||||
|
||||
;; Filesystem-escape denylist: every cap profile inherits this set so
|
||||
;; even SSRF / CMDI runs cannot smuggle out the host password file.
|
||||
(deny file-read*
|
||||
(literal "/etc/passwd")
|
||||
(literal "/etc/master.passwd")
|
||||
(literal "/etc/shadow")
|
||||
(literal "/etc/sudoers")
|
||||
(literal "/private/etc/passwd")
|
||||
(literal "/private/etc/master.passwd")
|
||||
(literal "/private/etc/shadow")
|
||||
(literal "/private/etc/sudoers"))
|
||||
24
src/dynamic/sandbox_profiles/cmdi.sb
Normal file
24
src/dynamic/sandbox_profiles/cmdi.sb
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
;; Phase 18 (Track E.2) — CODE_EXEC / command-injection profile.
|
||||
;;
|
||||
;; A tainted argv slot reaching `exec` or `os.system` is the sink under
|
||||
;; test, so process-exec must succeed (it is the observable behaviour
|
||||
;; the corpus oracle asserts on). Filesystem-escape via the spawned
|
||||
;; child is still denied — even if the child runs `cat /etc/passwd` it
|
||||
;; inherits the sandbox profile and hits EPERM on the read.
|
||||
|
||||
(version 1)
|
||||
(allow default)
|
||||
|
||||
(deny file-read*
|
||||
(literal "/etc/passwd")
|
||||
(literal "/etc/master.passwd")
|
||||
(literal "/etc/shadow")
|
||||
(literal "/etc/sudoers")
|
||||
(literal "/private/etc/passwd")
|
||||
(literal "/private/etc/master.passwd")
|
||||
(literal "/private/etc/shadow")
|
||||
(literal "/private/etc/sudoers")
|
||||
(subpath "/Users")
|
||||
(subpath "/var/db")
|
||||
(subpath "/private/var/db")
|
||||
(subpath "/Library/Keychains"))
|
||||
22
src/dynamic/sandbox_profiles/deserialize.sb
Normal file
22
src/dynamic/sandbox_profiles/deserialize.sb
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
;; Phase 18 (Track E.2) — DESERIALIZE profile.
|
||||
;;
|
||||
;; Unsafe-deserialise gadgets (pickle / Marshal / unserialize /
|
||||
;; ObjectInputStream) commonly chain to `exec()` or filesystem reads
|
||||
;; once a gadget object lands. `allow default` keeps the gadget paths
|
||||
;; runnable; the filesystem denylist prevents the gadget from
|
||||
;; exfiltrating host secrets.
|
||||
|
||||
(version 1)
|
||||
(allow default)
|
||||
|
||||
(deny file-read*
|
||||
(literal "/etc/passwd")
|
||||
(literal "/etc/master.passwd")
|
||||
(literal "/etc/shadow")
|
||||
(literal "/etc/sudoers")
|
||||
(literal "/private/etc/passwd")
|
||||
(literal "/private/etc/master.passwd")
|
||||
(literal "/private/etc/shadow")
|
||||
(literal "/private/etc/sudoers")
|
||||
(subpath "/Users")
|
||||
(subpath "/Library/Keychains"))
|
||||
50
src/dynamic/sandbox_profiles/path_traversal.sb
Normal file
50
src/dynamic/sandbox_profiles/path_traversal.sb
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
;; Phase 18 (Track E.2) — FILE_IO / path-traversal profile.
|
||||
;;
|
||||
;; The strictest of the per-cap profiles: blocks every host secret /
|
||||
;; user-data path a filesystem-escape payload would target. Read /
|
||||
;; write access to system libraries (`/usr`, `/System`, `/Library`) is
|
||||
;; preserved so the interpreter (python3 / node / java) can cold-start.
|
||||
;;
|
||||
;; Sensitive paths denied:
|
||||
;; * `/etc/{passwd,master.passwd,shadow,sudoers}` + their
|
||||
;; `/private/etc/...` mirrors — host credentials.
|
||||
;; * `/Users` — every user's home directory.
|
||||
;; * `/var/db` and `/private/var/db` — Open Directory and
|
||||
;; opendirectoryd state.
|
||||
;; * `/var/log` and `/private/var/log` — system + auth logs.
|
||||
;; * `/Library/Keychains` — host keychain databases.
|
||||
;;
|
||||
;; Writes outside WORKDIR are denied broadly: a tainted path payload
|
||||
;; cannot drop files into `/tmp` peers, `/var/folders`, or the user's
|
||||
;; home.
|
||||
|
||||
(version 1)
|
||||
(allow default)
|
||||
|
||||
(deny file-read*
|
||||
(literal "/etc/passwd")
|
||||
(literal "/etc/master.passwd")
|
||||
(literal "/etc/shadow")
|
||||
(literal "/etc/sudoers")
|
||||
(literal "/private/etc/passwd")
|
||||
(literal "/private/etc/master.passwd")
|
||||
(literal "/private/etc/shadow")
|
||||
(literal "/private/etc/sudoers")
|
||||
(subpath "/Users")
|
||||
(subpath "/var/db")
|
||||
(subpath "/private/var/db")
|
||||
(subpath "/var/log")
|
||||
(subpath "/private/var/log")
|
||||
(subpath "/Library/Keychains"))
|
||||
|
||||
;; Writes: deny everything outside WORKDIR + `/dev/null`. The
|
||||
;; subpath-allow re-enables WORKDIR after the broad deny.
|
||||
(deny file-write*
|
||||
(subpath "/")
|
||||
(with no-log))
|
||||
(allow file-write*
|
||||
(subpath (param "WORKDIR"))
|
||||
(literal "/dev/null")
|
||||
(literal "/dev/dtracehelper")
|
||||
(literal "/dev/stdout")
|
||||
(literal "/dev/stderr"))
|
||||
22
src/dynamic/sandbox_profiles/ssrf.sb
Normal file
22
src/dynamic/sandbox_profiles/ssrf.sb
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
;; Phase 18 (Track E.2) — SSRF profile.
|
||||
;;
|
||||
;; Outbound network is allowed (the SSRF sink fires only when the
|
||||
;; harness actually makes the request, so an outbound-deny profile
|
||||
;; would mask the cap). Filesystem-escape denylist stays in effect so
|
||||
;; an SSRF payload that pivots to read host secrets cannot exfiltrate
|
||||
;; them.
|
||||
|
||||
(version 1)
|
||||
(allow default)
|
||||
|
||||
(deny file-read*
|
||||
(literal "/etc/passwd")
|
||||
(literal "/etc/master.passwd")
|
||||
(literal "/etc/shadow")
|
||||
(literal "/etc/sudoers")
|
||||
(literal "/private/etc/passwd")
|
||||
(literal "/private/etc/master.passwd")
|
||||
(literal "/private/etc/shadow")
|
||||
(literal "/private/etc/sudoers")
|
||||
(subpath "/Users")
|
||||
(subpath "/Library/Keychains"))
|
||||
Loading…
Add table
Add a link
Reference in a new issue