Sandbox Validator patch

This commit is contained in:
Karmaz95
2024-07-29 17:59:13 +02:00
parent 6b9e495ff0
commit 01721cfba4
3 changed files with 364 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sysctl.h>
#include <unistd.h>
enum sandbox_filter_type {
SANDBOX_FILTER_NONE,
SANDBOX_FILTER_PATH,
SANDBOX_FILTER_GLOBAL_NAME,
SANDBOX_FILTER_LOCAL_NAME,
SANDBOX_FILTER_APPLEEVENT_DESTINATION,
SANDBOX_FILTER_RIGHT_NAME,
SANDBOX_FILTER_PREFERENCE_DOMAIN,
SANDBOX_FILTER_KEXT_BUNDLE_ID,
SANDBOX_FILTER_INFO_TYPE,
SANDBOX_FILTER_NOTIFICATION,
SANDBOX_FILTER_XPC_SERVICE_NAME = 12,
SANDBOX_FILTER_IOKIT_CONNECTION,
};
const char* filter_type_strings[] = {
"NONE",
"PATH",
"GLOBAL_NAME",
"LOCAL_NAME",
"APPLEEVENT_DESTINATION",
"RIGHT_NAME",
"PREFERENCE_DOMAIN",
"KEXT_BUNDLE_ID",
"INFO_TYPE",
"NOTIFICATION",
"XPC_SERVICE_NAME",
"IOKIT_CONNECTION"
};
void print_filter_types() {
printf("\nAvailable filter types:\n");
for (size_t i = 0; i < sizeof(filter_type_strings) / sizeof(filter_type_strings[0]); i++) {
printf(" %s\n", filter_type_strings[i]);
}
}
int sandbox_check(pid_t, const char *operation, enum sandbox_filter_type, ...);
int pid_exists(pid_t pid) {
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
struct kinfo_proc info;
size_t info_size = sizeof(info);
return (sysctl(mib, 4, &info, &info_size, NULL, 0) == 0 && info_size > 0);
}
void usage() {
fprintf(stderr, "Usage: %s <pid> [<operation> [<filter_type> <filter_value>]]\n", getprogname());
fprintf(stderr, "Checks if the specified process is sandboxed or if a specific operation is allowed.\n\n");
fprintf(stderr, "Examples:\n");
fprintf(stderr, " %s 93298\n", getprogname());
fprintf(stderr, " %s 93298 \"file-read*\"\n", getprogname());
fprintf(stderr, " %s 93298 \"file-read*\" PATH \"/users/karmaz/.trash\"\n", getprogname());
fprintf(stderr, " %s 93298 \"authorization-right-obtain\" RIGHT_NAME \"system.burn\"\n", getprogname());
print_filter_types();
exit(1);
}
enum sandbox_filter_type get_filter_type(const char* filter_type_str) {
for (size_t i = 0; i < sizeof(filter_type_strings) / sizeof(filter_type_strings[0]); i++) {
if (strcmp(filter_type_str, filter_type_strings[i]) == 0) {
return i;
}
}
return SANDBOX_FILTER_NONE;
}
int main(int argc, char **argv) {
if (argc < 2 || argc == 4 || argc > 5) {
usage();
}
pid_t pid = atoi(argv[1]);
if (!pid_exists(pid)) {
fprintf(stderr, "%d: No such process\n", pid);
exit(2);
}
const char *operation = NULL;
enum sandbox_filter_type filter_type = SANDBOX_FILTER_NONE;
const char *filter_value = NULL;
if (argc >= 3) {
operation = argv[2];
}
if (argc == 5) {
filter_type = get_filter_type(argv[3]);
if (filter_type == SANDBOX_FILTER_NONE) {
fprintf(stderr, "Invalid filter type: %s\n", argv[3]);
exit(3);
}
filter_value = argv[4];
}
int rc = (argc == 2)
? sandbox_check(pid, NULL, SANDBOX_FILTER_NONE)
: sandbox_check(pid, operation, filter_type, filter_value);
if (rc == 0) {
printf("Operation '%s' is %s for process %d",
(operation ? operation : "sandbox status"),
(argc == 2 ? "not sandboxed" : "allowed"),
pid);
} else {
printf("Operation '%s' is not allowed for process %d",
(operation ? operation : "sandbox status"),
pid);
}
if (argc == 5) {
printf(" (Filter type: %s, Value: %s)", argv[3], filter_value);
}
printf("\n");
return rc;
}

View File

@@ -0,0 +1,196 @@
default
appleevent-send
authorization-right-obtain
boot-arg-set
device*
device-camera
device-microphone
darwin-notification-post
distributed-notification-post
dynamic-code-generation
file*
file-chroot
file-clone
file-ioctl
file-issue-extension
file-link
file-lock
file-map-executable
file-mknod
file-mount
file-mount-update
file-read*
file-read-data
file-read-metadata
file-read-xattr
file-revoke
file-search
file-test-existence
file-unmount
file-write*
file-write-acl
file-write-create
file-write-data
file-write-finderinfo
file-write-flags
file-write-mode
file-write-owner
file-write-setugid
file-write-times
file-write-unlink
file-write-xattr
fs-quota*
fs-quota-get
fs-quota-on
fs-quota-off
fs-quota-set*
fs-quota-set-limits
fs-quota-set-usage
fs-quota-stat
fs-quota-sync
fs-rename
fs-snapshot*
fs-snapshot-create
fs-snapshot-delete
fs-snapshot-mount
fs-snapshot-revert
generic-issue-extension
qtn-user
hid-control
iokit*
iokit-get-properties
iokit-issue-extension
iokit-open*
iokit-open-user-client
iokit-open-service
iokit-set-properties
ipc*
ipc-posix*
ipc-posix-issue-extension
ipc-posix-sem*
ipc-posix-sem-create
ipc-posix-sem-open
ipc-posix-sem-post
ipc-posix-sem-unlink
ipc-posix-sem-wait
ipc-posix-shm*
ipc-posix-shm-read-data
ipc-posix-shm-write*
ipc-posix-shm-write-create
ipc-posix-shm-write-data
ipc-posix-shm-write-unlink
ipc-sysv*
ipc-sysv-msg
ipc-sysv-sem
ipc-sysv-shm
job-creation
lsopen
mach*
mach-bootstrap
mach-cross-domain-lookup
mach-derive-port
mach-host*
mach-host-exception-port-set
mach-host-special-port-set
mach-issue-extension
mach-kernel-endpoint
mach-lookup
mach-priv*
mach-priv-host-port
mach-priv-task-port
mach-register
mach-task*
mach-task-inspect
mach-task-name
mach-task-read
mach-task-special-port*
mach-task-special-port-get
mach-task-special-port-set
necp-client-open
network*
network-inbound
network-bind
network-outbound
nvram*
nvram-delete
nvram-get
nvram-set
opendirectory-user-modify
process*
process-codesigning
process-exec*
process-exec-interpreter
process-fork
process-info*
process-info-codesignature
process-info-dirtycontrol
process-info-ledger
process-info-listpids
process-info-rusage
process-info-pidinfo
process-info-pidfdinfo
process-info-pidfileportinfo
process-info-setcontrol
process-legacy-codesigning*
process-legacy-codesigning-blob-get
process-legacy-codesigning-cdhash-get
process-legacy-codesigning-entitlements-blob-get
process-legacy-codesigning-entitlements-der-blob-get
process-legacy-codesigning-identity-get
process-legacy-codesigning-status*
process-legacy-codesigning-status-get
process-legacy-codesigning-status-set
process-legacy-codesigning-teamid-get
process-legacy-codesigning-text-offset-get
pseudo-tty
signal
socket-ioctl
socket-option*
socket-option-get
socket-option-set
syscall*
syscall-unix
syscall-mach
syscall-mig
sysctl*
sysctl-read
sysctl-write
system*
system-acct
system-audit
system-automount
system-debug
system-fcntl
system-fsctl
system-info
system-kas-info
system-kext*
system-kext-load
system-kext-unload
system-kext-query
system-mac*
system-mac-label
system-mac-syscall
system-memorystatus-control
system-necp-client-action
system-nfssvc
system-package-check
system-privilege
system-reboot
system-sched
system-set-time
system-socket
system-suspend-resume
system-swap
user-preference*
user-preference-read
managed-preference-read
user-preference-write
storage-class-map
process-exec-update-label
default-message-filter
iokit-async-external-method
iokit-external-method
iokit-external-trap
mach-message-send
xpc-message-send

View File

@@ -0,0 +1,44 @@
import sys
import lief
def extract_sandbox_operations(binary):
"""Extract sandbox operations from the Sandbox.kext file."""
extracted_strings = []
# Get strings from the __cstring (string table)
for section in binary.sections:
if section.type == lief.MachO.SECTION_TYPES.CSTRING_LITERALS:
strings_bytes = section.content.tobytes()
strings = strings_bytes.decode('utf-8', errors='ignore')
extracted_strings.extend(strings.split('\x00'))
operations = []
capture = False
# Extract operations based on specific markers
for string in extracted_strings:
if string == 'default':
capture = True
if capture:
operations.append(string)
if string == 'xpc-message-send':
capture = False
return operations
def main(file_path):
# Load the Mach-O binary using LIEF
binary = lief.parse(file_path)
# Extract and print sandbox operations
operations = extract_sandbox_operations(binary)
for operation in operations:
print(operation)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python sandbox_operations.py <path_to_sandbox_kext>")
sys.exit(1)
file_path = sys.argv[1]
main(file_path)