Adobe Flash: Bypassing the local sandbox to exfiltrate data, obtain Windows user credentials (CVE-2016-4271)
September 2016 marked the arrival of Flash Player 23. This time, it was more than just a security patch: Adobe disables the local-with-filesystem sandbox from this release forward.
Having been part of Flash since ActionScript 3, introduced some ten years ago, the local sandbox’s demise is pretty significant. For developers, this means they will have to make the necessary adaptions. Ironically, with some of the Flash APIs now being deprecated, local file system interaction likely will require resorting to HTML5 techniques.
Historically, the local sandbox has been a popular target for devising various bypass vulnerabilities. Data exfiltration is one of them. This has resulted in an ongoing arms race, with Adobe blacklisting keywords and pseudo URIs, and white hats (plus others) finding ways around those blacklists.
With the local sandbox seemingly being a popular target, early last year I decided to join the race and have a look as well. This turned up a subtle but interesting flaw. In short, a combination of two URI schemes enable SMB access, sufficient to exfiltrate local data, and expose Windows user credentials to a remote server.
Having reported this design flaw to Adobe, it was acknowledged in APSB16-29 and assigned CVE-2016-4271. It turns out my report contributed to Adobe’s decision to drop the Flash local sandbox, so here’s a write up of how the flaw works.
By definition, not so local
When opening a local SWF file, it is intended to run in the default Flash sandbox dubbed
local-with-filesystem. From Adobe, we have:
local file: A local SWF file describes any file referenced by using the “file” protocol or a UNC path, which does not include an IP address or a qualifying domain. For example, “\test\test.swf” and “file:\test.swf” are considered local files, while “\test.com\test.swf” and “\192.168.0.1\test.swf” are not considered local files.
local-with-filesystem: The default sandbox for local files. SWF files in this sandbox may not contact the Internet (or any servers) in any way—they may not access network endpoints with addresses such as HTTP URLs.
Both definitions are somewhat peculiar. We will illustrate this by discussing the mentioned schemes that locate a resource: UNC and the File URI.
Windows supports the UNC scheme to locate shared files and devices. A UNC string has a myriad of possibilities, with paths being expressed using an IP address, FQDN or NetBIOS host name. Hence, UNC paths are quite complex, and most importantly, in principle anything but local. Therefore, to meet the local file definition, Flash’s
URLLoader disallows paths including an IP address, FQDN, or NetBIOS name - but with the latter category still permitting the local host’s name. Examples of valid UNC syntax include
\\10.0.0.1\share\remote_resource.txt \\[local NetBIOS host]\c$\local_resource.txt
where only the second is accepted by Flash.
What about the other option - the File URI? This scheme expresses another variety of locations, albeit restricted to the local file system. There is one caveat, though: one path can be expressed in more than one way. From Wikipedia,
file://localhost/c|/WINDOWS/clock.avi file:///c|/WINDOWS/clock.avi file://localhost/c:/WINDOWS/clock.avi
all refer to the same resource. We will see later how this characteristic comes into play.
What’s in a scheme: exfiltrating local data
To summarize, we have the UNC and File URI schemes, with Flash restricting the former, and the latter taking only local paths. Now, what if we could combine them in one string? Taking the File URI as the top level, the Win32 Shell API conveniently lets us proceed using UNC notation by prepending the UNC path with
/, and replacing any back slashes with their forward counterpart. We have:
(UNC syntax) \\10.0.0.1\share\remote_resource.txt (File URI + modified UNC) file://///10.0.0.1/share/remote_resource.txt
where both refer to the same resource.
URLLoader presumably calls the Win32 API at some point, and so this raises the obvious question of interest: does Flash still restrict UNC when inside a File URI string? Consider these examples:
(1) file://///evilserver.com/ (2) file://///184.108.40.206/ (3) file://///192.168.1.1/
(1) and (2) throw a SecurityError as expected:
Interestingly though, (3) throws a different error:
Code #2032 is Flash terminology for Stream Error. Let’s see what actually happens:
Success! We have established an SMB connection from the victim’s machine to our remote server.
local-with-filesystem providing local file system access, we still need a means to upload the data from the victim’s machine. No Flash API will let us write to SMB resources, so we have to come up with something else. The basic approach is to append file content to the SMB path request. From there, the steps to take include:
- Format file content to meet SMB path request limits:
- Split content into <260 bytes chunks (path
- URL encode to avoid forbidden characters (e.g. /, \, #, @)
- Split content into <260 bytes chunks (path
- Append chunks to SMB resource requests
- Make the consecutive requests
- Capture requests on remote (attacker-controlled) side
- URL decode, reconstruct complete file on remote side
Having done all that, our malicious Flash application outputs:
Meanwhile, we create a Python script doubling as SMB server and requests logger. On the attacker-controlled side, we have:
This shows we have succesfully exfiltrated a local file - to be precise, the Windows
hosts file - from the victim’s machine.
SMB at play: leaking Windows user credentials
Server Message Block, commonly abbreviated as SMB, is the protocol of choice for sharing files over Windows networks.
SMB’s primary authentication scheme uses NTLM hashing to send over user passwords. This hash should be handled with caution: an 8-character password permutation can be bruteforced in under 6 hours, or if you are unlucky, less with a decent rainbow table.
Unfortunately, keeping your hash private may not be that trivial. A victim’s machine can be made to transmit user credentials along with any of its SMB requests. One option is to have the SMB server deny access without authentication, effectively signalling Windows to try logging on with current user credentials. In essence, this translates to sending the username in plain text as well as the NTLM password hash. Hence, all it takes for an attacker to obtain user credentials is triggering Windows to connect to their malicious SMB server, let that SMB server deny access without authentication, after which the Windows machine will send the password hash.
SMBtrap, a Python script using
impacket’s SMB support, leverages this characteristic to do just that. It hosts an SMB server, performs protocol negotiation and session setup, and finally terminates at the point where it receives user credentials:
In the above example, I have provided SMBtrap a precomputed NTLMv2 hash for the password ‘123321ab’. However, SMBtrap can be adapted to incorporate a real dictionary or invoke a tool like Hashcat.
One may consider this flaw particularly worrying. A typical Windows account, being part of the Administrators group, has the ability to self-elevate. While this would still require an RCE, privilege escalation becomes significantly easier. Impersonating the user and then using the returned token handle will usually suffice to run arbitrary processes with elevated privileges.
A word about affected versions
The flaw as described descends from Flash Player’s security design. I have verified all supported browsers and Microsoft Office products are vulnerable. Hence, this raises the question: how long has the flaw been part of Flash?
To answer this question, we return to ActionScript 3. Flash Player 9, released in June 2006, introduced this scripting language version and its corresponding sandbox policies. Attempting to run the SWF in Flash Player 9 gives:
That looks surprisingly similar.
The flaw at hand is subtle but unforgiving: the File URI, being taken as local, effectively whitewashes the remote UNC path and therefore slips through Adobe’s blacklist.
Arguably, a blacklist approach is likely to fail at some point. That is, without even having considered other allowed schemes, like pseudo and custom URIs. On the other hand, with Windows enabling to combine multiple URI schemes in one, constructing a proper whitelist would seem a difficult task.
Fortunately, the local sandbox’s demise renders this question moot. For websites still requiring Adobe’s runtime, browsing the web just got a little safer as the process of deprecating Flash continues.
Affected host environments
Firefox Chrome Internet Explorer 6 to 11 Edge Microsoft Office 2010, 2013 and 2016
Flash Player 220.127.116.11 to 18.104.22.168 Windows XP, Vista, 7, 8.x and 10
27-03-2016: Vulnerability reported to Adobe PSIRT. 28-03-2016: Adobe acknowledges the vulnerability and assigns it PSIRT-5019. 10-04-2016: Requested status update. Adobe replies various mitigation options are being evaluated. 26-04-2016: Requested status update. Adobe replies it plans to introduce a new sandbox security policy: the local-with-filesystem sandbox will be disabled by default. Adobe expects this policy to arrive in Flash Player in Fall 2016. 13-09-2016: Adobe fixes the vulnerability in Flash Player 22.214.171.124. 05-02-2017: Vulnerability published.
- Adobe Security Bulletin APSB16-29
- SecurityTracker - Adobe Flash Player Bugs Let Remote Users Obtain Potentially Sensitive Information and Execute Arbitrary Code
- Radboud University - Radboud student discovers decade-old security flaw in Adobe Flash
- Security.NL (Dutch) - Radboud-student ontdekt 10 jaar oud lek in Flash Player