Monday, August 30, 2010

MakeMeLaughNow - analysis of new generation facebook worm

A new facebook worm malware application 'makemelaughnow' is out in the wild.
It escapes FB sandbox mechanisms and activates BEFORE displaying the credentials form -  only by visiting application home page you send messages to your friends and update your status.
As the news on niebezpiecznik.pl say, it uses Facebook mobile site (touch.facebook.com) to propagate. I did a quick analysis - Let's take a look on what's exactly going on in the app code.

Disclaimer: Don't do this at home - I'm a professional stunt driver and like to live dangerously. Don't do this analysis on your standard Facebook account, use a virtual machine in case there's some exploit embedded etc. When I found out that touch.facebook.com is involved, I just added:

127.0.0.1 touch.facebook.com

to /etc/hosts (that redirects all requests to touch.facebook.com to my computer), but please be more careful. You've been warned.

Quick lookaround

The app homepage looks like this:


All you can see is some ads displayed. But a lot of things happen underneath. Let's look at the Firebug net panel:

The app, even before requesting any permissions from you, sends requests to touch.facebook.com possibly sending messages and performing other actions on your behalf. These are marked red in the screenshot (I block touch site). After that the ads from be2.pl are downloaded. So the app is clearly some sort of malware.

Getting the code

The actual app code and HTML sits in http://apps.facebook.com/fbml/fbjs_ajax_proxy.php?__a=1. It is sanboxed in JSON file and looks like this:

After downloading the JSON file locally and extracting it (I used PHP & Spidermonkey for extraction and Eclipse for formatting) we get the final app code (see step2_2.js ).

Sandbox

All Facebook apps are sandboxed to disallow them from referring global window object (so that they can't change Facebook page, redirect, send hidden forms etc). For this particular analysis, the important things to notice are:
  • JS code and objects are in prefixed namespace (aBIGNUMBER_variable_name)
  • HTML objects have namespaced IDs (<div id="appBIGNUMBER_name">)
  • $FBJS object is used to prevent app from referring to global window object. For our purpose you can assume that:
    • $FBJS.idx(a) === a
    • $FBJS.ref(this) === this
  • For convenience, I replaced the BIGNUMBER with 'x' character. 
All the code used in this post is hosted on github.com - take a look, it's really interesting.

    Analysis

    Obfuscation method

    The app, after being initialized, starts with the following statement (line 111):
    ax_domethod = ax_findvalues.firefunc(ax_document.getElementById('help_container').getFirstChild().getTitle());  
    So it gets the title of one of its DOM elements and passes it to some function. What's in the title then? Looking at the page source (app.html) we can see that it looks strange:
    <div id="app100124540047022_m" 
      class="m" 
      fbcontext="6ff9e32a4c8c"
      title="choy:ketmdslqxb.ujpzgvnra/fiw_?="/>
    
    It looks as if the title is some sort of a key that could be used to decrypt the hidden application variables. And we're right. In fact, choy:ketmdslqxb.ujpzgvnra/fiw_?= is a dictionary - ax_create.help() function picks characters from this dictionary to form URLs, field names etc. The character offsets are defined in, slightly obfuscated ax_meth variable.

    Scraping data

    Ok, so the app is obfuscated and uses DOM object to decrypt its variables. But what does it do?
    Let's look at ax_findvalues:
    var ax_findvalues = {
    a : ((new ax_RegExp('st_.or._i.\\\x22 .al.e=\\\x22(.*?)\\\x22', ''))), 
        // <form action="http://www.facebook.com/wallpost.php" post_form_id value
    b : ((new ax_RegExp('b_d.s.\\\x22 v..ue=\\\x22(.*?)\\\x22', ''))), 
        // value = type="hidden" id="fb_dtsg" name="fb_dtsg"
    c : ((new ax_RegExp('p.o..le\\.p.p\\?i.=(\\d+)\\\x22', ''))),
        // href="http://www.facebook.com/profile.php?id=xxx" your profile ID
    d : ((new ax_RegExp('na.e=\\\x22i.s\\[]\\\x22 v.l.e=\\\x22(.*?)\\\x22', 'gi'))), 
        // name=ids[] value= -- your friend ids
    //...
    
    This variable contains some interesting regular expressions - these are used to extract all your friend IDs, your own ID and a few unique credentials from HTML code embedded by Facebook with the application. But the app could do nothing with this data, as we're protected by sandboxing, right? Well, not really.

    Exploited by touching

    Looking deeper into the code, we could see that the obfuscated data is:
    m=http://touch.facebook.com/message_send.php
    ftarg=fra
    su=http://touch.facebook.com/submit_status.php (status update)
    pid=post_form_id
    lp=http://touch.facebook.com/reqs.php?id=
    fhome=http://touch.facebook.com/home.php
    fbd=fb_dtsg
    hc=fb_dtsg
    
    So, probably, the app is contacting touch.facebook.com to send messages and submit new status. Again, we're right. The actual process is:
    1. ax_findvalues.firefunc() extracts your friend IDs and other data into ax_sheep, ax_params variables (line 264)
    2. new form and iframe are created 
    3. ax_methodaction (line 183) fills out the form to touch.facebook.com with this message to a few (max.20) of your friends:

      i thought of you...


      im using up my fb ad credits to send u a gift so HERE = http://apps.facebook.com/makemelaughnow/


    4. If you have more than 500 friends, or less then 2, a status update: "only go here if you are my TRUE friend http://apps.facebook.com/makemelaughnow/" is sent instead
    5. You become a fan of the app (line 297)
    6. The ad is displayed and the app cleans up its objects

    Conclusion

    What we can see here, is that an app is probably using a vulnerability in Facebook where mobile site is using the same credentials as normal site, but is not protected by sandbox mechanism. So the app, instead of asking for permissions to e.g. update your status, silently gets the session data from DOM and sends the requests through touch.facebook.com, avoiding sandbox protection and spreading quickly - so it's similar to CSRF / session hijacking vulnerability. It's clearly an error on Facebook site that's being exploited. Lesson to be learned - don't forget about your mobile sites.

      3 comments:

      Adomas Svirskas said...

      Thanks Krzysztof, this is helpful!

      DREAMER said...

      Thanks for the nice analysis and the time spent! Maybe we can learn a lesson by not repeating the same error Facebook fallen in cross-site session granting.

      Anonymous said...

      zielonyflaming.pl Wonderful Site, Maintain the good work. Thank you!