Created
January 2, 2020 07:00
-
-
Save Quiark/d289d73697956c8020b330526223a70e to your computer and use it in GitHub Desktop.
restricted version of sbtool that is compilable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// courtesy of clang | |
// https://github.com/applesrc/clang/blob/bb8f644/src/projects/compiler-rt/lib/sanitizer_common/sanitizer_mac_spi.cc | |
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 | |
}; | |
extern const enum sandbox_filter_type SANDBOX_CHECK_NO_REPORT; | |
extern const enum sandbox_filter_type SANDBOX_CHECK_CANONICAL; | |
int sandbox_check(pid_t pid, const char *operation, enum sandbox_filter_type type, ...); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// code by Jonathan Levin | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <sys/stat.h> | |
#include <sys/errno.h> | |
#include <signal.h> // kill(2) | |
#include <string.h> // strcmp, etc. | |
#include "sandbox.h" // Mine | |
#include <dlfcn.h> | |
void *g_sblibHandle = NULL; | |
char* operation_names[] = { | |
"default", | |
"appleevent-send", | |
"authorization-right-obtain", | |
"device*", | |
"device-camera", | |
"device-microphone", | |
"distributed-notification-post", | |
"file*", | |
"file-chroot", | |
"file-ioctl", | |
"file-issue-extension", | |
"file-map-executable", | |
"file-mknod", | |
"file-mount", | |
"file-read*", | |
"file-read-data", | |
"file-read-metadata", | |
"file-read-xattr", | |
"file-revoke", | |
"file-search", | |
"file-unmount", | |
"file-write*", | |
"file-write-create", | |
"file-write-data", | |
"file-write-flags", | |
"file-write-mode", | |
"file-write-owner", | |
"file-write-setugid", | |
"file-write-times", | |
"file-write-unlink", | |
"file-write-xattr", | |
"generic-issue-extension", | |
"qtn-user", | |
"qtn-download", | |
"qtn-sandbox", | |
"hid-control", | |
"iokit*", | |
"iokit-issue-extension", | |
"iokit-open", | |
"iokit-set-properties", | |
"iokit-get-properties", | |
"ipc*", | |
"ipc-posix*", | |
"ipc-posix-issue-extension", | |
"ipc-posix-sem", | |
"ipc-posix-shm*", | |
"ipc-posix-shm-read*", | |
"ipc-posix-shm-read-data", | |
"ipc-posix-shm-read-metadata", | |
"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", | |
"load-unsigned-code", | |
"lsopen", | |
"mach*", | |
"mach-bootstrap", | |
"mach-issue-extension", | |
"mach-lookup", | |
"mach-per-user-lookup", | |
"mach-priv*", | |
"mach-priv-host-port", | |
"mach-priv-task-port", | |
"mach-register", | |
"mach-task-name", | |
"network*", | |
"network-inbound", | |
"network-bind", | |
"network-outbound", | |
"user-preference*", | |
"user-preference-read", | |
"user-preference-write", | |
"process*", | |
"process-exec*", | |
"process-exec-interpreter", | |
"process-fork", | |
"process-info*", | |
"process-info-listpids", | |
"process-info-pidinfo", | |
"process-info-pidfdinfo", | |
"process-info-pidfileportinfo", | |
"process-info-setcontrol", | |
"process-info-dirtycontrol", | |
"process-info-rusage", | |
"pseudo-tty", | |
"signal", | |
"sysctl*", | |
"sysctl-read", | |
"sysctl-write", | |
"system*", | |
"system-acct", | |
"system-audit", | |
"system-chud", | |
"system-debug", | |
"system-fsctl", | |
"system-info", | |
"system-kext*", | |
"system-kext-load", | |
"system-kext-unload", | |
"system-lcid", | |
"system-mac-label", | |
"system-nfssvc", | |
"system-privilege", | |
"system-reboot", | |
"system-sched", | |
"system-set-time", | |
"system-socket", | |
"system-suspend-resume", | |
"system-swap", | |
"system-write-bootstrap", | |
NULL | |
}; | |
void usage() | |
{ | |
fprintf(stderr,"Johnny's Sandbox Utility, v0.1\n"); | |
fprintf(stderr,"Usage: %s _pid_ [what]...\n", getprogname()); | |
fprintf(stderr,"Where: what = all: All operations (not ready yet)\n"); | |
fprintf(stderr," mach: Check all known mach ports\n"); | |
fprintf(stderr," file: Check file access (Requires dir or file argument)\n"); | |
fprintf(stderr," inspect: Call syscall_inspect on this PID\n"); | |
fprintf(stderr," vtrace: Call syscall_vtrace on this PID\n"); | |
fprintf(stderr,"\n"); | |
} | |
int checkAll (pid_t Pid) | |
{ | |
int op = 0; | |
while (operation_names[op]) | |
{ | |
int denied = sandbox_check (Pid, operation_names[op], SANDBOX_CHECK_NO_REPORT, NULL); | |
printf("%s: %s\n", operation_names[op], denied ? "deny" : "allow"); | |
op++; | |
} | |
return 0; | |
} | |
int main(int argc, char **argv) | |
{ | |
// First open libsandbox.1.dylib. Yes, we're linked with it, | |
// but No, versions change significantly between 3xx and 459+ | |
// If we can't find it, no biggy - the inspect feature will just be disabled. | |
char *libsb = getenv ("LIBSB"); | |
if (!libsb) libsb = "libsandbox.1.dylib"; | |
g_sblibHandle = dlopen (libsb, RTLD_GLOBAL); | |
if (argc < 2) { usage(); exit(1);} | |
// If first argument is a PID, go for sandbox_check | |
uint32_t pid = 0; | |
int rc = 0; | |
char container[1024]; | |
char *path = "/tmp"; | |
rc = sscanf (argv[1], "%d", &pid); | |
if (rc != 1) | |
{ | |
fprintf(stderr,"Expecting a PID as the first argument. \"%s\" sure as heck isn't\n", | |
argv[1]); | |
usage(); | |
exit(5); | |
} | |
char buf[4096]; | |
// Does PID exist? a simple check | |
rc = kill (pid, 0); | |
if (rc < 0) { fprintf (stderr, "%d: No such process\n", pid); exit(2);} | |
// Do a quick check to see if the process is at all sandboxed | |
if (pid) | |
{ | |
rc = sandbox_check (pid, NULL, 0); | |
if (rc == 0) { fprintf(stderr,"Process %d is not sandboxed. All further checks are moot (everything allowed).\n",pid); | |
if (strcmp(argv[2], "inspect")) exit(0); | |
} | |
// If we have a PID, maybe it is contained? | |
container[0] = '\0'; | |
int len = 0x339; | |
uint64_t pid64 = pid; | |
rc = sandbox_container_path_for_pid (pid, container, 1024); | |
if (rc == 0) { | |
printf("PID %d Container: %s\n", pid, container); | |
} | |
else printf("PID %d is sandboxed, but not containerized\n",pid); | |
} | |
// If no more arguments, then we're done. | |
if (argc == 2) { return 0; }; | |
if (argc == 3) { | |
if (strcmp(argv[2],"file") == 0) | |
{ | |
fprintf(stderr,"file: options requires an argument (file or folder to check)\n"); | |
exit(5); | |
} | |
#ifdef SB459 | |
if (strncmp(argv[2], "vtrace", strlen(argv[2])) == 0) | |
{ | |
int rc = sandbox_vtrace_enable(); | |
fprintf(stderr,"RC: %d\n",rc); | |
char *rep = sandbox_vtrace_report(); | |
fprintf(stderr,"rep: %p\n",rep); | |
exit(rc); | |
} | |
#endif | |
if (strncmp(argv[2], "inspect", strlen(argv[2])) == 0) | |
{ | |
//int rc = __sandbox_ms("Sandbox",0x10, &pid2,pid2,buf, 4096); | |
//printf("RC: %d, Buf: %s\n", rc,buf); | |
typedef int sbip_func(int, char **buf, int *size); | |
sbip_func *sandbox_inspect_pid = dlsym(g_sblibHandle, "sandbox_inspect_pid"); | |
if (sandbox_inspect_pid) { | |
int size = 0; | |
char *buf = NULL; | |
rc = sandbox_inspect_pid(pid,&buf,&size); | |
if (rc == 0) fprintf(stdout,"%s\n", buf); | |
else | |
fprintf(stderr,"sandbox_inspect_pid failed (RC: %d)\n", rc); | |
} | |
else { fprintf (stderr," Cant find sandbox_inspect_pid in libsandbox.\nLikely iOS version too old or too new (though you can try __sandbox_ms (0x10) directly)\n"); } | |
} | |
if (strcmp(argv[2],"mach") == 0) | |
{ | |
fprintf(stderr,"Checking Mach services for %d....\n",pid); | |
char **services = NULL; // get_launchd_endpoints(1); | |
int s = 0; | |
for (s = 0; | |
services[s]; | |
s++) | |
{ | |
int mach_check = sandbox_check (pid, | |
"mach-lookup", | |
SANDBOX_FILTER_RIGHT_NAME | SANDBOX_CHECK_NO_REPORT, | |
services[s]); | |
printf("%s: %s\n", services[s], mach_check ?"Nope": "Yep"); | |
} | |
return 0; | |
} | |
if (strcmp(argv[2], "all") == 0) { exit(checkAll(pid)); } | |
path = realpath(argv[2],NULL); | |
} | |
// Check if the path exists, otherwise sandbox_check will fail (for the wrong reason) | |
if (strcmp(argv[2],"file") == 0) | |
{ | |
path = argv[3]; | |
if (!path) { fprintf(stderr,"Path %s doesn't exist\n", argv[2]); exit(1); } | |
int read_denied = sandbox_check (pid, "file-read-data", SANDBOX_FILTER_PATH | SANDBOX_CHECK_NO_REPORT, path); | |
int write_denied = sandbox_check (pid, "file-write-data", SANDBOX_FILTER_PATH | SANDBOX_CHECK_NO_REPORT, path); | |
// I like verbose messages. And tertiary operators. Even if nested | |
printf("The sandbox is %s restricting PID %d from reading %s writing to %s\n", | |
read_denied ? "" :"not", | |
pid, | |
write_denied ? (read_denied ? "and" : "but is restricting") : | |
(read_denied ? "but not restricting" : "or"), | |
path); | |
// For those of you wanting to script this, the return value says all | |
exit ( (read_denied ? 0x10 : 0) + (write_denied ? 0x20 : 0)); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment