{"id":3941,"date":"2025-08-24T18:15:50","date_gmt":"2025-08-24T09:15:50","guid":{"rendered":"https:\/\/h4ck.kr\/?p=3941"},"modified":"2025-08-24T18:15:51","modified_gmt":"2025-08-24T09:15:51","slug":"%ec%8b%a4%ec%8a%b5-cve-2020-3836cuck00-%ec%9d%b4%ed%95%b4%ed%95%98%ea%b8%b0","status":"publish","type":"post","link":"https:\/\/h4ck.kr\/?p=3941","title":{"rendered":"[\uc2e4\uc2b5] CVE-2020-3836(cuck00) \uc774\ud574\ud558\uae30"},"content":{"rendered":"\n<p>\uad00\ub828 \uae00\uacfc \ucf54\ub4dc\ub4e4\uc740 \uc544\ub798 \ub9c1\ud06c\uc5d0\uc11c \ud655\uc778\ud558\uc2e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4. <\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/wh1te4ever\/xnu_1day_practice\/blob\/main\/CVE-2020-3836\">https:\/\/github.com\/wh1te4ever\/xnu_1day_practice\/blob\/main\/CVE-2020-3836<\/a><\/p>\n\n\n\n<div class=\"wp-block-jetpack-markdown\"><h2>\ubc84\uadf8 \uc54c\uc544\ubcf4\uae30<\/h2>\n<p>\ud574\ub2f9 \ubc84\uadf8\ub294 \uc8fc\uc5b4\uc9c4 \uc0ac\uc6a9\uc790 \uacf5\uac04\uc758 mach port name\uc744 \uc81c\uacf5\ud558\uba74,\n\ucee4\ub110 \uacf5\uac04\uc758 ipc_port \uad6c\uc870\uccb4 \uc8fc\uc18c\ub97c \uc720\ucd9c\uc2dc\ud0ac \uc218 \uc788\ub294 \ubc84\uadf8\uac00 \uc874\uc7ac\ud55c\ub2e4.  \uc544\uc8fc \uc624\ub798\ub41c xnu-123.5 \ubc84\uc804\uc5d0\ub3c4 \uc874\uc7ac\ud558\ub294 \ubc84\uadf8\uc774\uba70, \uc57d 20\ub144 \uc774\uc0c1 \uc720\uc9c0\ub418\uc5c8\ub2e4.<\/p>\n<p>IOKit \ub4dc\ub77c\uc774\ubc84\ub4e4\uc740 \uc790\uc8fc \ucf5c\ubc31 \uba54\ucee4\ub2c8\uc998\uc744 \uc0ac\uc6a9\ud558\uba70, \ubcf4\ud1b5 mach \ud3ec\ud2b8\ub97c \uc911\uc2ec\uc73c\ub85c \uad6c\ud604\ub41c\ub2e4.\n\uc801\uc5b4\ub3c4 \uc0c1\ub2f9\uc218 \ub4dc\ub77c\uc774\ubc84\ub4e4\uc774 \uc0ac\uc6a9\ud558\ub294 <code>IOUserClient<\/code>\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uae30\ub2a5 \uc911 \ud558\ub098\ub294 <strong><code>OSAsyncReference64<\/code><\/strong> \ud568\uc218\uc774\ub2e4. \ud574\ub2f9 \ud0c0\uc785 \uc120\uc5b8\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n<p><a href=\"https:\/\/github.com\/apple-oss-distributions\/xnu\/blob\/xnu-6153.61.1\/iokit\/IOKit\/OSMessageNotification.h#L92\">https:\/\/github.com\/apple-oss-distributions\/xnu\/blob\/xnu-6153.61.1\/iokit\/IOKit\/OSMessageNotification.h#L92<\/a><\/p>\n<pre><code class=\"language-cpp\">\/\/ --------------\nenum {\n\tkOSAsyncRef64Count  = 8,\n\tkOSAsyncRef64Size   = kOSAsyncRef64Count * ((int) sizeof(io_user_reference_t))\n};\ntypedef io_user_reference_t OSAsyncReference64[kOSAsyncRef64Count];\n<\/code><\/pre>\n<p><code>io_user_reference_t<\/code>\ub294 <code>uint64_t<\/code>\ud0c0\uc785\uc774\uc9c0\ub9cc, \ud574\ub2f9 \uac12\uc740 \uc0ac\uc6a9\uc790 \uacf5\uac04\uc5d0\uc11c \uac00\uc838\uc628 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4. \uc774 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uace0\uc790 \ud558\ub294 \ub4dc\ub77c\uc774\ubc84\ub294 \uc704\uc758 \uad6c\uc870\uccb4\ub97c \uc9c1\uc811 \ub9cc\ub4e4\uac70\ub098 <code>IOUserClient::setAsyncReference64<\/code>\ub97c \ud638\ucd9c\ud560 \uc218 \uc788\ub2e4. \uc0ac\uc2e4 \uadf8 \uad6c\ud604 \uc790\uccb4\ub294 \ud06c\uac8c \uc911\uc694\ud558\uc9c0 \uc54a\uace0, \uc9c4\uc9dc \uc911\uc694\ud55c \uac83\uc740 \uc720\uc800\ub79c\ub4dc\ub85c \ub2e4\uc2dc \uc804\uc1a1\ub418\ub294 \uba54\uc2dc\uc9c0\uac00 \uc5b4\ub5bb\uac8c \uad6c\uc131\ub418\ub290\ub0d0\uc778\ub370, \uc774\ub294 <code>IOUserClient::_sendAsyncResult64<\/code>\uc5d0 \uc758\ud574 \uc774\ub8e8\uc5b4\uc9c4\ub2e4.<\/p>\n<p>\uc5ec\uae30\uc11c \ubc84\uadf8\ub97c \ubc1c\uacac\ud560 \uc218 \uc788\ub294\ub370, \uc8fc\uc694 \ubd80\ubd84\uc744 \u201cXXX BELOW HERE \u2026\u201d\ub85c \ud45c\uc2dc\ud574\ub193\uc558\ub2e4. \uc790\uc138\ud788 \uc0b4\ud3b4\ubcf4\uc790.<\/p>\n<p><a href=\"https:\/\/github.com\/apple-oss-distributions\/xnu\/blob\/xnu-6153.61.1\/iokit\/Kernel\/IOUserClient.cpp#L2030\">https:\/\/github.com\/apple-oss-distributions\/xnu\/blob\/xnu-6153.61.1\/iokit\/Kernel\/IOUserClient.cpp#L2030<\/a><\/p>\n<pre><code class=\"language-cpp\">IOReturn\nIOUserClient::_sendAsyncResult64(OSAsyncReference64 reference,\n    IOReturn result, io_user_reference_t args[], UInt32 numArgs, IOOptionBits options)\n{\n\tstruct ReplyMsg {\n\t\tmach_msg_header_t msgHdr;\n\t\tunion{\n\t\t\tstruct{\n\t\t\t\tOSNotificationHeader     notifyHdr;\n\t\t\t\tIOAsyncCompletionContent asyncContent;\n\t\t\t\tuint32_t                 args[kMaxAsyncArgs];\n\t\t\t} msg32;\n\t\t\tstruct{\n\t\t\t\tOSNotificationHeader64   notifyHdr;\n\t\t\t\tIOAsyncCompletionContent asyncContent;\n\t\t\t\tio_user_reference_t      args[kMaxAsyncArgs] __attribute__ ((packed));\n\t\t\t} msg64;\n\t\t} m;\n\t};\n\tReplyMsg      replyMsg;\n\tmach_port_t   replyPort;\n\tkern_return_t kr;\n\n\t\/\/ If no reply port, do nothing.\n\t\/\/ **XXX BELOW HERE 1**\n\t**replyPort = (mach_port_t) (reference[0] &amp; ~kIOUCAsync0Flags);** \n\tif (replyPort == MACH_PORT_NULL) {\n\t\treturn kIOReturnSuccess;\n\t}\n\n\tif (numArgs &gt; kMaxAsyncArgs) {\n\t\treturn kIOReturnMessageTooLarge;\n\t}\n\n\tbzero(&amp;replyMsg, sizeof(replyMsg));\n\treplyMsg.msgHdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND \/*remote*\/,\n\t    0 \/*local*\/);\n\treplyMsg.msgHdr.msgh_remote_port = replyPort;\n\treplyMsg.msgHdr.msgh_local_port  = NULL;\n\treplyMsg.msgHdr.msgh_id          = kOSNotificationMessageID;\n\tif (kIOUCAsync64Flag &amp; reference[0]) {\n\t\treplyMsg.msgHdr.msgh_size =\n\t\t    sizeof(replyMsg.msgHdr) + sizeof(replyMsg.m.msg64)\n\t\t    - (kMaxAsyncArgs - numArgs) * sizeof(io_user_reference_t);\n\t\treplyMsg.m.msg64.notifyHdr.size = sizeof(IOAsyncCompletionContent)\n\t\t    + numArgs * sizeof(io_user_reference_t);\n\t\treplyMsg.m.msg64.notifyHdr.type = kIOAsyncCompletionNotificationType;\n\t\t**\/\/ XXX BELOW HERE 2\n\t\tbcopy(reference, replyMsg.m.msg64.notifyHdr.reference, sizeof(OSAsyncReference64));**\n\n\t\treplyMsg.m.msg64.asyncContent.result = result;\n\t\tif (numArgs) {\n\t\t\tbcopy(args, replyMsg.m.msg64.args, numArgs * sizeof(io_user_reference_t));\n\t\t}\n\t} else {\n\t\t...\n\t}\n\n\t...\n\treturn kr;\n}\n<\/code><\/pre>\n<p>\ud574\ub2f9 <code>IOUserClient::_sendAsyncResult64<\/code> \ud568\uc218\ub294 <code>OSAsyncReference64<\/code>\ub97c \ubc1b\uc544 \uadf8\uac78 \ube44\ub86f\ud55c \uc5ec\ub7ec \uac12\uc744 mach \uba54\uc2dc\uc9c0\ub85c \uc720\uc800\ub79c\ub4dc\uc5d0 \ubcf4\ub0b8\ub2e4.\n\uadf8\ub7f0\ub370 \uc5ec\uae30\uc11c <code>OSAsyncReference64<\/code>\uc758 \uccab \ubc88\uc9f8 \uc694\uc18c\uac00 <code>mach_port_t<\/code>, \uc989 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0bc mach \ud3ec\ud2b8\uc774\ub2e4.<\/p>\n<pre><code class=\"language-cpp\">replyPort = (mach_port_t) (reference[0] &amp; ~kIOUCAsync0Flags);\n<\/code><\/pre>\n<p>\uc5ec\uae30\uc11c\uc758 <code>mach_port_t<\/code>\ub294 \uadf8\ub0e5 \ucee4\ub110\uc5d0\uc11c\uc758 \uc0dd\uc9dc \ud3ec\uc778\ud130\uc778\ub370,\n\ucee4\ub110 \ud3ec\uc778\ud130\ub97c \ub2f4\uc740 \uad6c\uc870\uccb4\ub97c \uc804\ub2ec\ud574\uc11c \uadf8\uac78 \uadf8\ub300\ub85c \uc720\uc800\ub79c\ub4dc\ub85c \ubcf4\ub0b4\uae30 \ub54c\ubb38\uc5d0 \ub9ad\uc774 \ubc1c\uc0dd\ud55c\ub2e4.<\/p>\n<pre><code class=\"language-cpp\">bcopy(reference, replyMsg.m.msg64.notifyHdr.reference, sizeof(OSAsyncReference64));\n<\/code><\/pre>\n<h2>\ud2b8\ub9ac\uac70 \ubc29\ubc95<\/h2>\n<p><a href=\"https:\/\/blog.siguza.net\/cuck00\/\">Siguza\ub2d8\uaf10\uc11c \uac8c\uc2dc\ud55c \ube14\ub85c\uadf8 \uae00<\/a>\uc5d0\uc11c\ub294 \ub2e4\uc74c\uacfc \uac19\uc558\ub2e4.<\/p>\n<blockquote>\n<p>\uc77c\ubc18\uc801\uc778 IOSurface \ucd08\uae30\ud654(\uc720\uc800\ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc11c\ud53c\uc2a4 \uc0dd\uc131)\uac00 \ub05d\ub09c \ub4a4\uc5d0\ub294, \ud574\uc57c \ud560 \uc77c\uc740 \ub2e8\uc9c0:<\/p>\n<ul>\n<li><code>setNotify<\/code>(\uc678\ubd80 \uba54\uc11c\ub4dc 17)\ub97c \ud638\ucd9c\ud558\uba74\uc11c \ube44\ub3d9\uae30 \ud568\uc218 \uc911 \ud558\ub098\uc640 mach \ud3ec\ud2b8\ub97c \ud568\uaed8 \uc804\ub2ec\ud569\ub2c8\ub2e4.<\/li>\n<li><code>incrementUseCount<\/code>\ub97c \ud638\ucd9c\ud55c \ub4a4 \uc774\uc5b4\uc11c <code>decrementUseCount<\/code>(\uac01\uac01 \uba54\uc11c\ub4dc 14\uc640 15)\ub97c \ud638\ucd9c\ud569\ub2c8\ub2e4 \u2014 \uc774\ub4e4\uc774 \uc6d0\ub798 \ubb34\uc2a8 \uc6a9\ub3c4\ub85c \ub9cc\ub4e4\uc5b4\uc9c4 \uac74\uc9c0\ub294 \ubaa8\ub974\uaca0\uc9c0\ub9cc, \uc774 \uce74\uc6b4\ud2b8\uac00 0\uc5d0 \ub3c4\ub2ec\ud558\uba74 \uc720\uc800\ub79c\ub4dc\ub85c \uba54\uc2dc\uc9c0\uac00 \uc804\uc1a1\ub429\ub2c8\ub2e4.<\/li>\n<li>\uc790\uc2e0\uc758 mach \ud3ec\ud2b8\uc5d0\uc11c \uba54\uc2dc\uc9c0\ub97c \uc218\uc2e0\ud558\uace0, \uacf5\uc9dc\ub85c \uc5bb\uc740 \ucee4\ub110 \ud3ec\uc778\ud130\ub97c \uc990\uae30\uba74 \ub429\ub2c8\ub2e4.<\/li>\n<\/ul>\n<\/blockquote>\n<p>IOUserClient::_sendAsyncResult64 \ud568\uc218\uae4c\uc9c0 \uc5b4\ub5bb\uac8c \ub3c4\ub2ec\ud560 \uc218 \uc788\uc5c8\ub294\uc9c0 \uad81\uae08\ud574\uc11c PoC \ucf54\ub4dc\ub97c \uc2e4\ud589\uc2dc\ucf1c\ubd24\ub2e4. \uadf8 \uacb0\uacfc, <code>IOSurfaceRootUserClient::decrement_surface_use_count<\/code> \ud568\uc218\ub97c \ud1b5\ud574 \ub3c4\ub2ec \uac00\ub2a5\ud55c\uac83\uc744 \ud655\uc778\ud558\uc600\ub2e4. \uc5ec\uae30\uc11c\ubd80\ud130 \uac70\uc2ac\ub85c \uc62c\ub77c\uac00\ubcf4\uba74\uc11c \ubd84\uc11d\ud574\ubcf4\uaca0\ub2e4.<\/p>\n<ul>\n<li>kernel\uc758 <code>IOUserClient::_sendAsyncResult64<\/code> \ud568\uc218 \uc911 <code>mach_msg_send_from_kernel_proper<\/code> call\ud558\ub294 \uacf3\uc5d0 \ube0c\ud3ec\uac78\uc5c8\uc744 \ub54c\uc758 BackTrace<\/li>\n<\/ul>\n<pre><code class=\"language-nasm\">(lldb) bt\n* thread #2, stop reason = breakpoint 20.1\n  * frame #0: 0xffffff800746bbeb kernel`IOUserClient::_sendAsyncResult64(reference=0xffffff801875f3d0, result=0, args=&lt;unavailable&gt;, numArgs=2, options=0) at IOUserClient.cpp:2108:8 [opt]\n    frame #1: 0xffffff7f89344929 &lt;- IOSurface`IOSurfaceRootUserClient::notify_surface+0x30\n    frame #2: 0xffffff7f89340ce0 &lt;- IOSurface`IOSurfaceRoot::notifySurface+0x3C\n    frame #3: 0xffffff7f89343a19 IOSurface`IOSurfaceRootUserClient::decrement_surface_use_count+0x67\n    frame #4: 0xffffff8007466fcb kernel`IOUserClient::externalMethod(this=&lt;unavailable&gt;, selector=&lt;unavailable&gt;, args=&lt;unavailable&gt;, dispatch=&lt;unavailable&gt;, target=&lt;unavailable&gt;, reference=&lt;unavailable&gt;) at IOUserClient.cpp:5888:10 [opt]\n    frame #5: 0xffffff8007470083 kernel`::is_io_connect_method(connection=0xffffff8015f73610, selector=15, scalar_input=&lt;unavailable&gt;, scalar_inputCnt=&lt;unavailable&gt;, inband_input=&lt;unavailable&gt;, inband_inputCnt=0, ool_input=0, ool_input_size=0, inband_output=&quot;&quot;, inband_outputCnt=0xffffff80188b460c, scalar_output=0xffffff90a48b3d00, scalar_outputCnt=0xffffff90a48b3cfc, ool_output=0, ool_output_size=0xffffff80157551a8) at IOUserClient.cpp:4495:16 [opt]\n    frame #6: 0xffffff8006e22c22 kernel`_Xio_connect_method(InHeadP=&lt;unavailable&gt;, OutHeadP=0xffffff80188b45e0) at device_server.c:8389:18 [opt]\n    frame #7: 0xffffff8006d41998 kernel`ipc_kobject_server(request=0xffffff80157550e0, option=3) at ipc_kobject.c:389:4 [opt]\n    frame #8: 0xffffff8006d18625 kernel`ipc_kmsg_send(kmsg=0xffffff80157550e0, option=3, send_timeout=0) at ipc_kmsg.c:1937:10 [opt]\n    frame #9: 0xffffff8006d2f0d5 kernel`mach_msg_overwrite_trap(args=&lt;unavailable&gt;) at mach_msg.c:553:8 [opt]\n    frame #10: 0xffffff8006e4b485 kernel`mach_call_munger64(state=0xffffff80141abaa0) at bsd_i386.c:618:24 [opt]\n    frame #11: 0xffffff8006ce3226 kernel`hndl_mach_scall64 + 22\n(lldb) \n<\/code><\/pre>\n<p><code>IOSurface::decrement_use_count<\/code> \ud568\uc218\ub294 <code>IOSurfaceRoot::notifySurface<\/code> \ud568\uc218\ub97c \ud638\ucd9c\uc2dc\ud0ac \uc218 \uc788\ub294 \ub798\ud37c\uc774\uba70,<\/p>\n<pre><code class=\"language-cpp\">void __fastcall IOSurface::decrement_use_count(IOSurface *this)\n{\n  if ( OSDecrementAtomic((SInt32 *)(this-&gt;field_C0 + 20LL)) == 1 )\n  {\n    if ( this-&gt;field_25 )\n      IOSurface::purge(this);\n    IOSurfaceRoot::notifySurface((IORecursiveLock **)this-&gt;field_28, 0, this);\n  }\n}\n<\/code><\/pre>\n<p>\ud2b8\ub9ac\uac70\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc800 v4 \ubcc0\uc218\uac12\uc774 1\uc744 \ubc18\ud658\uc2dc\ucf1c\uc57c \ud55c\ub2e4.\nv4\ub97c \uc9c0\uc815\ud574\uc8fc\ub294 \uacf3\uc740 <code>IOSurfaceClient::decrement_use_count<\/code> \ud568\uc218\uc5d0 \uc788\uc73c\uba70,<\/p>\n<pre><code class=\"language-cpp\">__int64 __fastcall IOSurfaceRootUserClient::decrement_surface_use_count(IOSurfaceRootUserClient *this, unsigned int a2)\n{\n  IOSurfaceClient *v2; \/\/ r15\n  IOSurface *IOSurface; \/\/ r14\n  bool v4; \/\/ r15\n\n  IOLockLock((IOLock *)this-&gt;m_lock);\n  if ( LODWORD(this-&gt;i_surfaceClientCapacity) &gt; a2 &amp;&amp; (v2 = this-&gt;m_IOSurfaceClientArrayPointer[a2]) != 0 )\n  {\n    IOSurface = v2-&gt;IOSurface;\n    IOSurface-&gt;struct_19F28_vtable-&gt;__ZNK9IOSurface6retainEv(IOSurface);\n    v4 = IOSurfaceClient::decrement_use_count(v2);\n    IOLockUnlock((IOLock *)this-&gt;m_lock);\n    if ( v4 )                                   \/\/ 0x1a198 = vtable\n      IOSurface-&gt;struct_19F28_vtable-&gt;__ZN9IOSurface19decrement_use_countEv(IOSurface);\n    IOSurface-&gt;struct_19F28_vtable-&gt;__ZN9IOSurface7releaseEv(IOSurface);\n    return 0;\n  }\n  else\n  {\n    IOLockUnlock((IOLock *)this-&gt;m_lock);\n    return 3758097090LL;\n  }\n}\n<\/code><\/pre>\n<p>\uc774 \uacbd\uc6b0, +0x24 \uc624\ud504\uc14b\uc744 use_count \ud544\ub4dc\uac12\uc73c\ub85c \ucd94\uce21\ud560 \uc218 \uc788\ub294\ub370,\nuse_count \ud544\ub4dc\uac00 \uac10\uc18c \uc804 1\uc774\uc5ec\uc57c \ub41c\ub2e4.<\/p>\n<p><strong>\uadf8\ub798\uc11c <code>decrementUseCount<\/code> \ud638\ucd9c\uc804\uc5d0 use_count \ud544\ub4dc\uac12\uc744 1\ub85c \ub9cc\ub4e4\uae30 \uc704\ud574\n\uba3c\uc800<code>incrementUseCount<\/code> \ud568\uc218\ub97c \ud638\ucd9c\ud574\ub458 \ud544\uc694\uac00 \uc788\ub2e4\ub294 \uac83\uc774\ub2e4.<\/strong><\/p>\n<pre><code class=\"language-cpp\">bool __fastcall IOSurfaceClient::decrement_use_count(void *this)\n{\n  int v1; \/\/ eax\n\n  v1 = *((_DWORD *)this + 0x24);\n  if ( v1 )\n    *((_DWORD *)this + 0x24) = v1 - 1;\n  return v1 == 1;\n}\n<\/code><\/pre>\n<p>\uac01\uac01\uc758 \ud638\ucd9c\ubc88\ud638\ub294 \ub2e4\uc74c\uacfc \uac19\uace0<\/p>\n<ul>\n<li>14: <code>IOSurfaceRootUserClient::increment_surface_use_count<\/code><\/li>\n<li>15:  <code>IOSurfaceRootUserClient::decrement_surface_use_count<\/code><\/li>\n<\/ul>\n<p>\uc544\ub798\ub294 <code>incrementUseCount<\/code> \uad00\ub828 \ud568\uc218 \ucf54\ub4dc\uc774\ub2e4.<\/p>\n<ul>\n<li>IOSurfaceRootUserClient::increment_surface_use_count<\/li>\n<\/ul>\n<pre><code class=\"language-cpp\">__int64 __fastcall IOSurfaceRootUserClient::increment_surface_use_count(IOSurfaceRootUserClient *this, unsigned int a2)\n{\n  IOSurfaceClient *v2; \/\/ r15\n  IOSurface *IOSurface; \/\/ r14\n  bool v4; \/\/ r15\n\n  IOLockLock((IOLock *)this-&gt;m_lock);\n  if ( LODWORD(this-&gt;i_surfaceClientCapacity) &gt; a2 &amp;&amp; (v2 = this-&gt;m_IOSurfaceClientArrayPointer[a2]) != 0 )\n  {\n    IOSurface = v2-&gt;IOSurface;\n    IOSurface-&gt;struct_19F28_vtable-&gt;__ZNK9IOSurface6retainEv(IOSurface);\n    v4 = IOSurfaceClient::increment_use_count(v2);\n    IOLockUnlock((IOLock *)this-&gt;m_lock);\n    if ( v4 )\n      IOSurface-&gt;struct_19F28_vtable-&gt;__ZN9IOSurface19increment_use_countEv(IOSurface);\n    IOSurface-&gt;struct_19F28_vtable-&gt;__ZN9IOSurface7releaseEv(IOSurface);\n    return 0;\n  }\n  else\n  {\n    IOLockUnlock((IOLock *)this-&gt;m_lock);\n    return 0xE00002C2LL;\n  }\n}\n<\/code><\/pre>\n<h3>IOSurfaceRoot::setSurfaceNotify<\/h3>\n<p><code>incrementUseCount<\/code>  \ud568\uc218\ub97c \ud638\ucd9c\ud558\uae30 \uc804\uc5d0\ub294 \uc0ac\uc6a9\uc790 \uacf5\uac04\uc758 mach \ud3ec\ud2b8\uc640 \ud568\uaed8 \uc804\ub2ec\uc2dc\ucf1c\uc8fc\uc5b4\uc57c \ud55c\ub2e4.<\/p>\n<p>\ud638\ucd9c \ubc88\ud638\ub294 17\uc5d0 \ud574\ub2f9\ud55c\ub2e4.<\/p>\n<pre><code class=\"language-cpp\">__int64 __fastcall IOSurfaceRoot::setSurfaceNotify(\n        __int64 a1,\n        mach_port_t *a2,\n        mach_vm_address_t *a3,\n        IOSurfaceRootUserClient *a4)\n{\n  __int64 **v6; \/\/ rax\n  _QWORD *v7; \/\/ rax\n  _QWORD *v8; \/\/ r12\n  _QWORD *v9; \/\/ r13\n  __int64 v10; \/\/ rax\n  _QWORD *v11; \/\/ rax\n  unsigned int v12; \/\/ ebx\n\n  IORecursiveLockLock(*(IORecursiveLock **)(a1 + 256));\n  v6 = *(__int64 ***)(a1 + 336);\n  if ( v6 )\n  {\n    while ( v6[4] != (__int64 *)a3[1] || v6[11] != (__int64 *)a4 )\n    {\n      v6 = (__int64 **)*v6;\n      if ( !v6 )\n        goto LABEL_5;\n    }\n    v12 = -536870199;\n  }\n  else\n  {\nLABEL_5:\n    v7 = IOMalloc(0x60u);\n    if ( v7 )\n    {\n      v8 = v7;\n      v9 = (_QWORD *)(a1 + 336);\n      memset(v7, 0, 0x60u);\n      IOUserClient::setAsyncReference64(v8 + 2, *a2, *a3, a3[1]);\n      v8[11] = a4;\n      v8[10] = a3[2];\n      v10 = *(_QWORD *)(a1 + 336);\n      if ( v10 )\n      {\n        if ( *(_QWORD **)(v10 + 8) != v9 )\n          IOSurfaceRoot::setSurfaceNotify((const void *)(a1 + 336));\/\/ panic\n        *v8 = v10;\n        v11 = (_QWORD *)(v10 + 8);\n      }\n      else\n      {\n        *v8 = 0;\n        v11 = (_QWORD *)(a1 + 344);\n      }\n      *v11 = v8;\n      *v9 = v8;\n      v8[1] = v9;\n      v12 = 0;\n    }\n    else\n    {\n      v12 = -536870211;\n    }\n  }\n  IORecursiveLockUnlock(*(IORecursiveLock **)(a1 + 256));\n  return v12;\n}\n<\/code><\/pre>\n<h2>Result<\/h2>\n<pre><code class=\"language-nasm\">seo@seos-iMac-Pro CVE-2020-3836 % .\/leak\n[*] page size: 0x1000, kr=(os\/kern) successful\n[*] IOSurface_init success, IOSurface_id=0x2\n[*] port: 0x2703, (os\/kern) successful\n[*] leaked_port_addr: 0xffffff80173028b0\n...\n\n(lldb) p\/x *(ipc_port_t)0xffffff80173028b0\n(ipc_port) $36 = {\n  ip_object = {\n    io_bits = 0x80000000\n    io_references = 0x00000002\n    io_lock_data = (interlock = 0x0000000000000000)\n  }\n  ip_messages = {\n    data = {\n      port = {\n        waitq = {\n          waitq_type = 0x00000001\n          waitq_fifo = 0x00000001\n          waitq_prepost = 0x00000000\n          waitq_irq = 0x00000000\n          waitq_isvalid = 0x00000001\n          waitq_turnstile = 0x00000000\n          waitq_eventmask = 0x00000000\n          waitq_interlock = (lock_data = 0x0000000000000000)\n          waitq_set_id = 0x0000000000000000\n          waitq_prepost_id = 0x0000000000000000\n           = {\n            waitq_queue = {\n              next = NULL\n              prev = NULL\n            }\n            waitq_prio_queue = (pq_root_packed = 0x0000000000000000)\n             = {\n              waitq_ts = NULL\n              waitq_tspriv = 0x0000000000000000\n            }\n          }\n        }\n        messages = {\n          ikmq_base = NULL\n        }\n        seqno = 0x00000001\n        receiver_name = 0x00002703\n        msgcount = 0x0000\n        qlimit = 0x0005\n        qcontext = 0x00000000\n      }\n      pset = {\n        setq = {\n          wqset_q = {\n            waitq_type = 0x00000001\n            waitq_fifo = 0x00000001\n            waitq_prepost = 0x00000000\n            waitq_irq = 0x00000000\n            waitq_isvalid = 0x00000001\n            waitq_turnstile = 0x00000000\n            waitq_eventmask = 0x00000000\n            waitq_interlock = (lock_data = 0x0000000000000000)\n            waitq_set_id = 0x0000000000000000\n            waitq_prepost_id = 0x0000000000000000\n             = {\n              waitq_queue = {\n                next = NULL\n                prev = NULL\n              }\n              waitq_prio_queue = (pq_root_packed = 0x0000000000000000)\n               = {\n                waitq_ts = NULL\n                waitq_tspriv = 0x0000000000000000\n              }\n            }\n          }\n          wqset_id = 0x0000000000000000\n           = (wqset_prepost_id = 0x0000270300000001, wqset_prepost_hook = 0x0000270300000001)\n        }\n      }\n    }\n     = {\n      imq_klist = {\n        slh_first = NULL\n      }\n      imq_inheritor_knote = NULL\n      imq_inheritor_turnstile = NULL\n      imq_inheritor_thread_ref = NULL\n      imq_srp_owner_thread = NULL\n    }\n  }\n  data = {\n    receiver = 0xffffff801286fb40\n    destination = 0xffffff801286fb40\n    timestamp = 0x1286fb40\n  }\n  kdata = {\n    kobject = 0x0000000000000000\n    imp_task = NULL\n    sync_inheritor_port = NULL\n    sync_inheritor_knote = NULL\n    sync_inheritor_ts = NULL\n  }\n  ip_nsrequest = NULL\n  ip_pdrequest = NULL\n  ip_requests = NULL\n  kdata2 = {\n    premsg = NULL\n    send_turnstile = NULL\n  }\n  ip_context = 0x0000000000000000\n  ip_sprequests = 0x00000000\n  ip_spimportant = 0x00000000\n  ip_impdonation = 0x00000000\n  ip_tempowner = 0x00000000\n  ip_guarded = 0x00000000\n  ip_strict_guard = 0x00000000\n  ip_specialreply = 0x00000000\n  ip_sync_link_state = 0x00000000\n  ip_sync_bootstrap_checkin = 0x00000000\n  ip_immovable_receive = 0x00000000\n  ip_no_grant = 0x00000000\n  ip_immovable_send = 0x00000000\n  ip_impcount = 0x00000000\n  ip_mscount = 0x00000001\n  ip_srights = 0x00000001\n  ip_sorights = 0x00000000\n}\n<\/code><\/pre>\n<h2>\ucc38\uace0\ud55c \uc790\ub8cc \ubc0f \ucd9c\ucc98<\/h2>\n<p>Exploit Code<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/Siguza\/cuck00\">https:\/\/github.com\/Siguza\/cuck00<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/jakeajames\/time_waste\/blob\/master\/time_waste\/exploit.c#L93\">https:\/\/github.com\/jakeajames\/time_waste\/blob\/master\/time_waste\/exploit.c#L93<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/staturnzz\/chimera_patch\/blob\/main\/src\/time_saved.c#L36\">https:\/\/github.com\/staturnzz\/chimera_patch\/blob\/main\/src\/time_saved.c#L36<\/a><\/p>\n<\/li>\n<\/ul>\n<p>Writeup<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/rls1004.github.io\/2020-12-10-cuck00\/\">https:\/\/rls1004.github.io\/2020-12-10-cuck00\/<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/bugs.chromium.org\/p\/project-zero\/issues\/detail?id=1969\">https:\/\/bugs.chromium.org\/p\/project-zero\/issues\/detail?id=1969<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/blog.siguza.net\/cuck00\/\">https:\/\/blog.siguza.net\/cuck00\/<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\uad00\ub828 \uae00\uacfc \ucf54\ub4dc\ub4e4\uc740 \uc544\ub798 \ub9c1\ud06c\uc5d0\uc11c \ud655\uc778\ud558\uc2e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4. https:\/\/github.com\/wh1te4ever\/xnu_1day_practice\/blob\/main\/CVE-2020-3836<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[72],"tags":[11,12,13,25],"class_list":["post-3941","post","type-post","status-publish","format-standard","hentry","category-realworld","tag-ios","tag-ios-kernel","tag-macos","tag-pwnable"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/h4ck.kr\/index.php?rest_route=\/wp\/v2\/posts\/3941","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/h4ck.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/h4ck.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/h4ck.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/h4ck.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3941"}],"version-history":[{"count":1,"href":"https:\/\/h4ck.kr\/index.php?rest_route=\/wp\/v2\/posts\/3941\/revisions"}],"predecessor-version":[{"id":3942,"href":"https:\/\/h4ck.kr\/index.php?rest_route=\/wp\/v2\/posts\/3941\/revisions\/3942"}],"wp:attachment":[{"href":"https:\/\/h4ck.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3941"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/h4ck.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3941"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/h4ck.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3941"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}