Earlier today I noticed several of my friends had been hit by a Facebook worm that updated their status, created an event, and finally invited all of their friends to the event. The purpose of the worm was to widely distribute several "work from home" and similar scams. All of this happened instantly when they clicked on a link that they had seen posted by another user that had fallen for the trap. Knowing that Facebook would fix the issue soon, I immediately opened up my HTTP debugging tools and set about discovering how it worked.
Step 1: The user clicks a shortened url posted by a friend that has been hit by the worm. Each victim's status is updated with a new shortened url, and multiple URL shorteners are used.
Step 2: The user is redirected to one of many domains. In my case it was http://vidxapp3.co.cc/joblp/?go=973
Step 3: The exploit site loads an iframe to one of many facebook applications that have been set up by the attacker. The facebook application to use is chosen randomly from a large list to make the exploit more difficult to stop.
In addition to disallowing certain tags, FBML provides the developer with the ability to use special tags such as the Like button. These tags are turned into HTML prior to being served to the user's browser, and a sandboxing method is employed to prevent FBJS from accessing them (To click the like button without the user's permission, for example). The sandboxing method essentially consists of applying an attribute to the HTML that tells the FBJS getter methods provided to developers that they should not be allowed to fetch the element via getElementById or any other methods.
Step 4: The malicious Facebook application makes a Ajax request through Facebook's servers to load additional FBML.
Due to an error on Facebook's part, the developer is able to get around the normal FBJS sandboxing methods for the like button using code essentially like the following:
You likely see the problem here. The <fb:like> FBML tag will generate HTML that will contain the HTML attributes that instruct FBJS to disallow access to it, but that won't matter because the HTML simply gets rendered as text inside the textarea.
Step 5: The malicious application uses FBJS to parse the HTML generated from the like button and steal the CSRF protection tokens from it (You can read more about CSRF here).
Here's the code (Cleaned up slightly from the modifications Facebook's FBJS parser makes to try to sandbox it):
You can see that the FBJS code steals two CSRF protection keys. One is fb_dtsg, and the other is post_form_id. These keys are then used to set the source of an iframe to a URL such that the attacker now has access to those keys.
Step 6: The attacker's iframe makes a request to http://westernshowercurtains.info/app/golike.php?p=4490d3098311ba39ba6db0932c3310e1&d=_xURo
Which uses CSRF to make the user Like (fan) a page:
Step 7: The attacker's iframe makes a request to http://westernshowercurtains.info/app/gostatus.php?p=4490d3098311ba39ba6db0932c3310e1&d=_xURo which updates the user's status using the following code:
Step 8: The attacker's iframe makes a request to http://westernshowercurtains.info/app/goauth.php?app=159222847426674&p=4490d3098311ba39ba6db0932c3310e1&d=_xURo which authorizes the Facebook application using the following code:
If you look carefully, you'll notice that the application will now be granted permission to publish to stream, create an event, and RSVP for events.
After step 8, Facebook reads the next parameter from the form and redirects the user to step 10 at http://westernshowercurtains.info/app/gomessage.php?p=4490d3098311ba39ba6db0932c3310e1&app=159222847426674&d=_xURo.
Step 9: The application creates an event on the user's behalf and invites all of their friends (server side)
Step 10: This user is redirected to a page with another CSRF form to spam all of their friends with messages.
Facebook patched the security flaw used by this worm shortly after it was discovered. FBML tags inside of textareas are now no longer converted to HTML.
This was a particularly interesting worm due to the use of an FBML flaw as an attack vector. Approximately a year ago I reported a similar issue due to improper sand-boxing of FBJS Dialog boxes. As with many technologies as complex as FBML, they can provide an excellent method of attack for hackers that are willing to learn their way around them.
Perhaps wisely, Facebook has chosen to move away from FBML canvas applications. Until then, hopefully we won't see too many more of these vulnerabilities discovered by the bad guys.
Like this post? Please vote it up on YC News.