About these ads

David Vassallo's Blog

If at first you don't succeed; call it version 1.0

Category Archives: Security

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

About these ads

Pyinstaller – building exe files from python under Kali

I was trying to build my own malicious file… Since I love python, it was natural for me to go down the python + pyinstaller route. Initially, I coded everything on windows, downloaded and installed PyInstaller [1] on windows, and attempted to use the usual pyinstaller -F my_script.py to build my executable. But then I started running into problems with modules….

The usual pip install module_name was a frustrating experience on windows (oh how I miss linux in times like this…) and I continuously hit the vcvarsall.bat error [2], even after installing Visual Studio express 2008, and the “Microsoft Visual C++ Compiler for Python 2.7″. I also went down the MinGW route [3], only to be frustrated by another missing DLL (“msvcr71.dll is missing”)

Then I remembered that the VEIL framework [4] on my Kali Linux box generates .exe files and is a python framework… and research confirmed it uses PyInstaller in the background to generate these EXEs. Digging into the source code… it uses wine to call the windows version of python, and runs pyinstaller under the wine environment.

So then it was a simple thing to emulate them… like so:

 

wine32 “C:\\Python27\\python.exe” /usr/share/pyinstaller/pyinstaller.py /tmp_my_script.py

 

And that was it… everything compiled and ready to roll….

References

[1] http://www.pyinstaller.org/

[2] http://stackoverflow.com/questions/2817869/error-unable-to-find-vcvarsall-bat

[3] http://ultrainfinitum.blogspot.com/2012/12/python-error-unable-to-find-vcvarsallbat.html

[4] https://www.veil-framework.com/

Follow

Get every new post delivered to your Inbox.

Join 177 other followers