sobota, 1 marca 2014

Analysis of swfupload CVE-2013-2205 Security.allowDomain('*') flaw

Intro

Yes - I know it's the old one. As far as I've got lots of stuff to do, I had small amount of time to take a closer look to this vulnerability, found by Szymon Gruszecki and identified by CVE-2013-2205. But I also wanted to understand how to exploit this kind of issues. As far as I couldn't find any usefull PoCs or examples on the Internet - I decided to learn it and make a post. I belive it will be usefull for someone. :)

At first, please take a look to secure swfupload fix for this vuln. Yes - it's just one removed line. :)

Security.allowDomain('*')


It will be short - for details please visit Adobe documentation. Security.allowDomain() is function, which allows flash movie to be embeded and interacted from other domain. For example, we have resource-a.com where swf-a.swf is stored (with Security.allowDomain('resource-b.com')) - we are able to embed swf-a.swf on resource-b.com and interact with all functions that are added through ExternalInterface.addCallback() method.

Depends on context of application, it can be used for example to bypass Same-Policy Origin. How? If our swf-a.swf can make some http requests to hosted resource and get the response that can be passed somehow to our javascript code... you know what's next ;-)

Analysis

Most interesting functions that we should take a look are StartUpload(), ReturnUploadStart(), HTTPError_Handler(), UploadSuccess():

private function UploadSuccess(file: FileItem, serverData: String, responseReceived: Boolean = true): void {
if (this.serverDataTimer !== null) {
this.serverDataTimer.stop();
this.serverDataTimer = null;
}
if (this.assumeSuccessTimer !== null) {
this.assumeSuccessTimer.stop();
this.assumeSuccessTimer = null;
}
this.successful_uploads++;
file.file_status = FileItem.FILE_STATUS_SUCCESS;
this.Debug("Event: uploadSuccess: File ID: " + file.id + " Response Received: " + responseReceived.toString() + " Data: " + serverData);
ExternalCall.UploadSuccess(this.uploadSuccess_Callback, file.ToJavaScriptObject(), serverData, responseReceived);
this.UploadComplete(false);
}
view raw gistfile1.as hosted with ❤ by GitHub


UploadSuccess() is called after successful upload (wow). As we can see, it calls UploadSuccess callback (that can be defined to our own javascript function) with serverData as one of parameters - serverData is content response from requested uploadURL.

The attack

Ok - so if we are able to get content of other resource (SOP bypass), we are able to steal csrf tokens from forms. The attack scenario is simple - zoczus.mooo.com is hosting swfupload from wordpress 3.5.1 on lab.ropchain.org. After victim (logged into wp-admin panel) upload any file, we'll make request to user-new.php, parse response for nonce value, and make standard csrf attack to add other admin account. No other interaction (than file upload) is needed.
I created this proof of concept. Remember to modify wordpress-url to valid Wordpress resource.

Exploit in action: