TippingPoint Digital Vaccine Laboratories

ThreaLinQ: A Look at Adobe Flash Policy Files

Over the past few weeks I have been looking at Adobe Flash 9, specifically the policy file changes that were introduced with this version. By default, cross-domain communication is not allowed by Adobe Flash. Cross-domain communication violates the single origin policy that should be enforced by Internet applications, such as web browsers and browser extensions, in order to protect users and servers from cross-site request forgery (which by the way is an excellent modern day example of the classic "confused deputy" problem). Adobe Flash decided to implement a method by which cross-domain communications can be allowed by policy in order to interface with the likes of AJAX, DHTML, JavaScript, etc. The first attempt at doing so worked pretty well for a few years and then began to fall prey to two basic attacks. The first, being that the policy files themselves could be compromised via a number of popular attack vectors, as they were usually just files that existed somewhere in the web root directory and were duly served up over HTTP by the web server. The second attack being that this system was vulnerable to DNS rebinding attacks.

Adobe Flash 9 seeks to address these shortcomings by enforcing a new protocol for opening sockets. The communication happens over port 843/tcp and begins with the client's Flash application sending a single null-terminated XML entity that looks like the following:

0000  3C 70 6F 6C 69 63 79 2D 66 69 6C 65 2D 72 65 71  <policy-file-req
0010  75 65 73 74 2F 3E 00                             uest/>.
Thus, the Flash application will not open a socket to a remote server without obtaining permission from the remote server. Then the remote server responds with the appropriate policy file, after which the appropriate ports are opened for the Flash application. Here is an example of a policy file returned by Livly Island, a place in which proper care and feeding of cute little virtual pets takes place:

0000  3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E 3D 22 31  <?xml version="1
0010  2E 30 22 3F 3E 0A 3C 63 72 6F 73 73 2D 64 6F 6D  .0"?>.<cross-dom
0020  61 69 6E 2D 70 6F 6C 69 63 79 3E 0A 20 20 3C 73  ain-policy>.  <s
0030  69 74 65 2D 63 6F 6E 74 72 6F 6C 20 70 65 72 6D  ite-control perm
0040  69 74 74 65 64 2D 63 72 6F 73 73 2D 64 6F 6D 61  itted-cross-doma
0050  69 6E 2D 70 6F 6C 69 63 69 65 73 3D 22 6D 61 73  in-policies="mas
0060  74 65 72 2D 6F 6E 6C 79 22 2F 3E 0A 20 20 3C 61  ter-only"/>.  <a
0070  6C 6C 6F 77 2D 61 63 63 65 73 73 2D 66 72 6F 6D  llow-access-from
0080  20 64 6F 6D 61 69 6E 3D 22 77 77 77 2E 6C 69 76   domain="www.liv
0090  6C 79 2E 63 6F 6D 22 20 73 65 63 75 72 65 3D 22  ly.com" secure="
00A0  66 61 6C 73 65 22 20 74 6F 2D 70 6F 72 74 73 3D  false" to-ports=
00B0  22 38 30 2C 35 35 35 31 2D 35 35 35 34 22 2F 3E  "80,5551-5554"/>
00C0  0A 3C 2F 63 72 6F 73 73 2D 64 6F 6D 61 69 6E 2D  .</cross-domain-
00D0  70 6F 6C 69 63 79 3E 0A 0A                       policy>..
Here's another one, which I had to truncate and sanitize in order to the protect the innocent. The policy file probably isn't the best place to store system configuration settings and passwords

<?xml version="1.0"?>.<!DOCTYPE cross-domain-policy SYSTEM>
<!-- Policy file for http://www.XXXXXXXX.com -->
<cross-domain-policy>.
<allow-access-from domain="*.XXXXXXXX.com" to-ports="*" secure="false"/>
   <allow-access-from domain="XXX.XXX.XXX.*" to-ports="*" secure="false"/>
   <allow-access-from domain="XXX.XXX.XXX.*" to-ports="*" secure="false"/>
   <allow-access-from domain="XXX.XXX.XXX.*" to-ports="*" secure="false"/>
</cross-domain-policy>
<!-- NOTES on this screw file:.
  The latest version of flash requires this be served using a lightweight server,
that server receives a null-terminated string. and returns this file. To support
this I installed the python script they provided on gs2 & configured it to run. 
as a daemon when the machine boots. For details on the entire process look here:.    
    http://www.adobe.com/devnet/flashplayer/articles/fplayer9_security.html
  Some tricks with this file:
    to-ports="all" is bad syntax, should be to-ports="*"
    wildcards "*" are good, for example:
    *.XXXXXXXX.com.      XXX.XXX.XXX.*.      etc....    
  secure="false" indicates don't use the https protocol
  On gs2 the python utility lives in the following locations:

   /etc/rc.d/init.d/flashpolicyd    (edit this file to configure the whole thing)
      the releated rc.3/rc.4/rc.4 directories:

< ... snip! ...>
So, you get the idea. Now, what does this have to do with ThreatLinQ, and who really cares?

Well, I set out to answer a few questions about this protocol, namely who uses it on the Internet and are there people poking and prodding this protocol and testing it for weakness, and would it make sense to block certain manifestations of this traffic?

First, who is using it, according to my brief 2 week study:

  • 35% Unknown
  • 23% Chat
  • 16% Games
  • 7% Gambling
  • 5% Social Networking
  • 4% Search Engines
  • 3% Finance
  • 3% News
  • 2% Advertisement / Web Analytics
  • 1% Scientific
  • 1% Webcam Sharing

Of particular interest is the 35% of unknown. These sites were often hosted DHCP or virtual hosting servers that were no longer listening on port 843/tcp and my attempts to gain further information usually resulted in connections timing out. Interesting. When hostnames where actually listed in the files, they all were registered to free DNS hosting services. All of the above set of warning flags and it seems to me that the majority of these "unknown" websites could very well be malicious.

So, let's look at what these sites were serving up. The following four examples are coming from the server after the initial request is made by the Flash client. Here are some examples:

0000  3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E 3D 22 31  <?xml version="1
0010  2E 30 22 3F 3E 3C 21 44 4F 43 54 59 50 45 20 63  .0"?><!DOCTYPE c
0020  72 6F 73 73 2D 64 6F 6D 61 69 6E 2D 70 6F 6C 69  ross-domain-poli
0030  63 79 20 53 59 53 54 45 4D 20 22 2F 78 6D 6C 2F  cy SYSTEM "/xml/
0040  64 74 64 73 2F 63 72 6F 73 73 2D 64 6F 6D 61 69  dtds/cross-domai
0050  6E 2D 70 6F 6C 69 63 79 2E 64 74 64 22 3E 3C 63  n-policy.dtd"><c
0060  72 6F 73 73 2D 64 6F 6D 61 69 6E 2D 70 6F 6C 69  ross-domain-poli
0070  63 79 3E 3C 61 6C 6C 6F 77 2D 61 63 63 65 73 73  cy><allow-access
0080  2D 66 72 6F 6D 20 64 6F 6D 61 69 6E 3D 22 2A 22  -from domain="*"
0090  20 74 6F 2D 70 6F 72 74 73 3D 22 2A 22 20 2F 3E   to-ports="*" />
00A0  3C 2F 63 72 6F 73 73 2D 64 6F 6D 61 69 6E 2D 70  </cross-domain-p
00B0  6F 6C 69 63 79 3E 00                               olicy>.




0000  20 3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E 3D 22   <?xml version="
0010  31 2E 30 22 3F 3E 0A 3C 63 72 6F 73 73 2D 64 6F  1.0"?>.<cross-do
0020  6D 61 69 6E 2D 70 6F 6C 69 63 79 3E 0A 3C 61 6C  main-policy>.<al
0030  6C 6F 77 2D 61 63 63 65 73 73 2D 66 72 6F 6D 20  low-access-from 
0040  64 6F 6D 61 69 6E 3D 22 2A 22 74 6F 2D 70 6F 72  domain="*"to-por
0050  74 73 3D 22 2A 22 2F 3E 0A 3C 2F 63 72 6F 73 73  ts="*"/>.</cross
0060  2D 64 6F 6D 61 69 6E 2D 70 6F 6C 69 63 79 3E 00  -domain-policy>.
0070  67 20 62 67 73 3F 00 00 00 00 00 00              g bgs?......




0000  20 3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E 3D 22   <?xml version="
0010  31 2E 30 22 3F 3E 0A 3C 63 72 6F 73 73 2D 64 6F  1.0"?>.<cross-do
0020  6D 61 69 6E 2D 70 6F 6C 69 63 79 3E 0A 3C 61 6C  main-policy>.<al
0030  6C 6F 77 2D 61 63 63 65 73 73 2D 66 72 6F 6D 20  low-access-from 
0040  64 6F 6D 61 69 6E 3D 22 2A 22 74 6F 2D 70 6F 72  domain="*"to-por
0050  74 73 3D 22 2A 22 2F 3E 0A 3C 2F 63 72 6F 73 73  ts="*"/>.</cross
0060  2D 64 6F 6D 61 69 6E 2D 70 6F 6C 69 63 79 3E 00  -domain-policy>.
0070  CC CC DC 64 62 02 00 0F A8 02 02 00              ...db.......



0000  3C 63 72 6F 73 73 2D 64 6F 6D 61 69 6E 2D 70 6F  <cross-domain-po
0010  6C 69 63 79 3E 0A                                  licy>.


First thing I noticed is that three of the above examples contain extra information after the null-terminated policy XML. This is something that is expressly forbidden by Adobe's spec. What this is is being used for is unclear. Perhaps it could be a side channel or some sort of authorization bypass? The fourth example is strange, because this is coming from the server back to the client after the client has already sent a similar request. This could be misconfiguration on the part of the server, but since the server was no longer reachable I could not verify. Finally and most importantly, notice that these examples sort of defeat the cross-domain protections by allowing access from all domains to all ports.

So, I think it's clear that there are people out there that are poking and prodding and perhaps using and abusing Adobe Flash Policy files for nefarious purposes. So, given this assertion, I asked myself, "should this sort of thing be blocked?" I thought long and hard about this and didn't really come to a clear conclusion. There many be one or two edge cases where it makes sense to block all of these policy files (thereby blocking Flash socket connections to non-standard port), but the more difficult question is should we selectively block requests that allow access from any domain?

What do you think? I'd like to open these questions up to a wider audience, so post a comment and lets discuss!





Tags: adobe,flash,socket,policy
Published On: 2008-09-12 12:53:04

Comments post a comment

No comments.
Trackback