In die vorige beeld is dit moontlik om te observeer hoe die sandbox gelaai sal word wanneer 'n toepassing met die regte com.apple.security.app-sandbox uitgevoer word.
Die kompilator sal /usr/lib/libSystem.B.dylib aan die binêre koppel.
Dan, libSystem.B sal ander verskeie funksies aanroep totdat die xpc_pipe_routine die regte van die app na securityd stuur. Securityd kontroleer of die proses in die Sandbox gequarantine moet word, en indien wel, sal dit gequarantine word.
Laastens, sal die sandbox geaktiveer word met 'n oproep na __sandbox_ms wat __mac_syscall sal aanroep.
Moontlike Bypasses
Om die kwarantyn eienskap te omseil
Lêers geskep deur sandboxed prosesse word bygevoeg met die kwarantyn eienskap om sandbox ontsnapping te voorkom. As jy egter daarin slaag om 'n .app gids te skep sonder die kwarantyn eienskap binne 'n sandboxed toepassing, kan jy die app bundel binêre laat wys na /bin/bash en 'n paar omgewing veranderlikes in die plist voeg om open te misbruik om die nuwe app sonder sandbox te begin.
Daarom, op die oomblik, as jy net in staat is om 'n gids met 'n naam wat eindig op .app is te skep sonder 'n kwarantyn eienskap, kan jy die sandbox ontsnap omdat macOS net kontroleer die kwarantyn eienskap in die .app gids en in die hoof uitvoerbare (en ons sal die hoof uitvoerbare na /bin/bash wys).
Let daarop dat as 'n .app bundel reeds gemagtig is om te loop (dit het 'n kwarantyn xttr met die gemagtig om te loop vlag aan), kan jy dit ook misbruik... behalwe dat jy nou nie binne .app bundels kan skryf nie tensy jy 'n paar bevoorregte TCC toestemmings het (wat jy nie binne 'n sandbox hoog sal hê nie).
Selfs al is 'n toepassing bedoel om sandboxed te wees (com.apple.security.app-sandbox), is dit moontlik om die sandbox te omseil as dit uitgevoer word vanaf 'n LaunchAgent (~/Library/LaunchAgents) byvoorbeeld.
Soos verduidelik in hierdie pos, as jy volharding wil verkry met 'n toepassing wat sandboxed is, kan jy dit laat outomaties uitgevoer word as 'n LaunchAgent en dalk kwaadwillige kode via DyLib omgewing veranderlikes inspuit.
Misbruik van Auto Begin Plekke
As 'n sandboxed proses kan skryf in 'n plek waar later 'n onsandboxed toepassing die binêre gaan uitvoer, sal dit in staat wees om te ontsnap net deur daar die binêre te plaas. 'n Goeie voorbeeld van hierdie soort plekke is ~/Library/LaunchAgents of /System/Library/LaunchDaemons.
Vir dit mag jy selfs 2 stappe nodig hê: Om 'n proses met 'n meer toelaatbare sandbox (file-read*, file-write*) jou kode te laat uitvoer wat werklik in 'n plek sal skryf waar dit onsandboxed uitgevoer sal word.
As jy vanaf die sandbox proses in staat is om ander prosesse te kompromitteer wat in minder beperkende sandboxes (of geen) loop, sal jy in staat wees om na hul sandboxes te ontsnap:
Hierdie navorsing het 2 maniere ontdek om die Sandbox te omseil. Omdat die sandbox van gebruikersland toegepas word wanneer die libSystem biblioteek gelaai word. As 'n binêre dit kan vermy om dit te laai, sal dit nooit sandboxed word nie:
As die binêre heeltemal staties gecompileer was, kan dit vermy om daardie biblioteek te laai.
As die binêre nie enige biblioteke hoef te laai nie (omdat die linker ook in libSystem is), sal dit nie libSystem hoef te laai nie.
Shellcodes
Let daarop dat selfs shellcodes in ARM64 moet gekoppel word in libSystem.dylib:
# Compile itgcc-Xlinker-sectcreate-Xlinker__TEXT-Xlinker__info_plist-XlinkerInfo.plistsand.c-osand# Create a certificate for "Code Signing"# Apply the entitlements via signingcodesign-s<cert-name>--entitlementsentitlements.xmlsand
Die app sal probeer om die lêer ~/Desktop/del.txt te lees, wat die Sandbox nie sal toelaat.
Skep 'n lêer daar, aangesien die Sandbox oorgestap is, sal dit in staat wees om dit te lees:
echo"Sandbox Bypassed">~/Desktop/del.txt
Kom ons debuge die toepassing om te sien wanneer die Sandbox gelaai word:
# Load app in debugginglldb./sand# Set breakpoint in xpc_pipe_routine(lldb) bxpc_pipe_routine# run(lldb) r# This breakpoint is reached by different functionalities# Check in the backtrace is it was de sandbox one the one that reached it# We are looking for the one libsecinit from libSystem.B, like the following one:(lldb) bt* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1* frame #0: 0x00000001873d4178 libxpc.dylib`xpc_pipe_routineframe#1: 0x000000019300cf80 libsystem_secinit.dylib`_libsecinit_appsandbox + 584frame#2: 0x00000001874199c4 libsystem_trace.dylib`_os_activity_initiate_impl + 64frame#3: 0x000000019300cce4 libsystem_secinit.dylib`_libsecinit_initializer + 80frame#4: 0x0000000193023694 libSystem.B.dylib`libSystem_initializer + 272# To avoid lldb cutting info(lldb) settingssettarget.max-string-summary-length10000# The message is in the 2 arg of the xpc_pipe_routine function, get it with:(lldb) p (char *) xpc_copy_description($x1)(char *) $0 = 0x000000010100a400 "<dictionary: 0x6000026001e0> { count = 5, transaction: 0, voucher = 0x0, contents =\n\t\"SECINITD_REGISTRATION_MESSAGE_SHORT_NAME_KEY\" => <string: 0x600000c00d80> { length = 4, contents = \"sand\" }\n\t\"SECINITD_REGISTRATION_MESSAGE_IMAGE_PATHS_ARRAY_KEY\" => <array: 0x600000c00120> { count = 42, capacity = 64, contents =\n\t\t0: <string: 0x600000c000c0> { length = 14, contents = \"/tmp/lala/sand\" }\n\t\t1: <string: 0x600000c001e0> { length = 22, contents = \"/private/tmp/lala/sand\" }\n\t\t2: <string: 0x600000c000f0> { length = 26, contents = \"/usr/lib/libSystem.B.dylib\" }\n\t\t3: <string: 0x600000c00180> { length = 30, contents = \"/usr/lib/system/libcache.dylib\" }\n\t\t4: <string: 0x600000c00060> { length = 37, contents = \"/usr/lib/system/libcommonCrypto.dylib\" }\n\t\t5: <string: 0x600000c001b0> { length = 36, contents = \"/usr/lib/system/libcompiler_rt.dylib\" }\n\t\t6: <string: 0x600000c00330> { length = 33, contents = \"/usr/lib/system/libcopyfile.dylib\" }\n\t\t7: <string: 0x600000c00210> { length = 35, contents = \"/usr/lib/system/libcorecry"...
# The 3 arg is the address were the XPC response will be stored(lldb) registerreadx2x2=0x000000016fdfd660# Move until the end of the function(lldb) finish# Read the response## Check the address of the sandbox container in SECINITD_REPLY_MESSAGE_CONTAINER_ROOT_PATH_KEY(lldb) memoryread-fp0x000000016fdfd660-c10x16fdfd660:0x0000600003d04000(lldb) p (char *) xpc_copy_description(0x0000600003d04000)(char *) $4 = 0x0000000100204280 "<dictionary: 0x600003d04000> { count = 7, transaction: 0, voucher = 0x0, contents =\n\t\"SECINITD_REPLY_MESSAGE_CONTAINER_ID_KEY\" => <string: 0x600000c04d50> { length = 22, contents = \"xyz.hacktricks.sandbox\" }\n\t\"SECINITD_REPLY_MESSAGE_QTN_PROC_FLAGS_KEY\" => <uint64: 0xaabe660cef067137>: 2\n\t\"SECINITD_REPLY_MESSAGE_CONTAINER_ROOT_PATH_KEY\" => <string: 0x600000c04e10> { length = 65, contents = \"/Users/carlospolop/Library/Containers/xyz.hacktricks.sandbox/Data\" }\n\t\"SECINITD_REPLY_MESSAGE_SANDBOX_PROFILE_DATA_KEY\" => <data: 0x600001704100>: { length = 19027 bytes, contents = 0x0000f000ba0100000000070000001e00350167034d03c203... }\n\t\"SECINITD_REPLY_MESSAGE_VERSION_NUMBER_KEY\" => <int64: 0xaa3e660cef06712f>: 1\n\t\"SECINITD_MESSAGE_TYPE_KEY\" => <uint64: 0xaabe660cef067137>: 2\n\t\"SECINITD_REPLY_FAILURE_CODE\" => <uint64: 0xaabe660cef067127>: 0\n}"
# To bypass the sandbox we need to skip the call to __mac_syscall# Lets put a breakpoint in __mac_syscall when x1 is 0 (this is the code to enable the sandbox)(lldb) breakpointset--name__mac_syscall--condition'($x1 == 0)'(lldb) c# The 1 arg is the name of the policy, in this case "Sandbox"(lldb) memoryread-fs $x00x19300eb22:"Sandbox"## BYPASS## Due to the previous bp, the process will be stopped in:Process2517stopped* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1frame#0: 0x0000000187659900 libsystem_kernel.dylib`__mac_syscalllibsystem_kernel.dylib`:-> 0x187659900<+0>:movx16,#0x17d0x187659904<+4>:svc#0x800x187659908<+8>:b.lo0x187659928 ; <+40>0x18765990c<+12>:pacibsp# To bypass jump to the b.lo address modifying some registers first(lldb) breakpointdelete1# Remove bp(lldb) registerwrite $pc 0x187659928#b.lo address(lldb) registerwrite $x0 0x00(lldb) registerwrite $x1 0x00(lldb) registerwrite $x16 0x17d(lldb) cProcess2517resumingSandboxBypassed!Process2517exitedwithstatus=0 (0x00000000)
Selfs met die Sandbox omseil TCC sal die gebruiker vra of hy die proses wil toelaat om lêers van die lessenaar te lees