Offensive testing to make Dropbox (and the world) a safer place

Dropbox invests heavily in our security program. We have lots of teams dedicated to securing Dropbox, each working on exciting things. Some recent examples covered on our tech blog include:

  • Our Product Security team rolled out support for WebAuthn to boost user adoption of two-step verification and upleveled our industry-leading public bug bounty program
  • Because security is everyone’s responsibility, our Security Culture team helps our employees make consistently secure and informed decisions that protect Dropbox, our users, and our employees
  • Our Detection and Response Team (DART) implementation of extensive instrumentation throughout our infrastructure to catch any indications of compromise.

And that’s just a few teams so far—you’ll hear from all of our teams in upcoming blog posts.

This post will focus on our Offensive Security team. These are the people that leverage real-world adversarial techniques to test and improve the effectiveness of our security program at Dropbox.

We recently conducted an attack simulation as a red team exercise with a third-party vendor. Penetration testing is great for identifying unknown vulnerabilities in your systems and showing how susceptible they are to being exploited; however, the tester’s goals are typically limited to just that. What about post-exploitation? An attacker who wants access to our user data, for example, still has their work cut out for them. They need to learn how to navigate through our environments, breach other internal security barriers, exfiltrate data out of our networks, and do so without raising alarm. Or at least, if they do raise alarm, be able to accomplish their goals before we’re able to kick them out.

We’ve invested a lot in our hardening, detection, alerting, and response capabilities at Dropbox. Even if an attacker breaks in and accesses various systems in our environments without triggering an alarm, we have extensive instrumentation to trace activity post-exploitation. So how do we know we’re doing a good job? That’s the kind of testing we were going for with our most recent attack simulation. Our testing goals included measuring the steady-state of our detection and alerting program, as well as measuring our team’s response when a breach has been identified. Identifying new ways to break into Dropbox was in scope for this engagement, but even if none were found, we were going to simulate the effects of a breach by just planting malware ourselves (discretely, of course, so as not to tip off the detection and response team).

However, we didn’t have to simulate this breach. Our third-party partner, Syndis, found vulnerabilities in Apple software we use at Dropbox that didn’t just affect our macOS fleet, it affected all Safari users running the latest version at the time—a so-called zero-day vulnerability). When chained together, these vulnerabilities resulted in the ability for an attacker to run arbitrary code on a victim’s computer by having the victim simply visit a maliciously crafted web page.

We notified Apple of these issues, and they were quick to acknowledge our report. Apple released fixes for the issues in about a month, which is much better than the industry norm of “within 90 days.” The issues were granted CVEs, and we’ve validated the fixes, as did Syndis. We provide details of the vulnerabilities and the validation of the fixes in the Appendix.

This engagement was a win for us, for Apple, and for internet users on various levels. Not only did we get to test our defensive posture, we also made the internet safer by identifying and reporting vulnerabilities in macOS. Syndis went above and beyond in finding this exploit chain during our engagement, and using it during our attack simulation exercise allowed us to test our readiness against attacks using zero-day vulnerabilities. This is an excellent example of the security community becoming stronger because of good actors doing the right thing.

Dropbox protects the data of more than 500 million registered users. We know that we are targeted by adversaries that could develop and use zero-day exploits against us, and we need to protect ourselves accordingly. The risk of getting hit with zero-day exploits is a reality of being connected to the internet, but detecting these is tricky. A powerful zero-day will always gain a foothold, so this was a test of our instrumentation for detecting and alerting on post-exploit activity. Our partner noted “Dropbox demonstrated admirable monitoring, detection, and incident response” after the engagement. Although our teams and systems performed well against this well-armed adversary, we won’t get complacent. Extensive independent validation will always be a core strategy of Dropbox Security Team, and we’ll continue to adapt and learn from each new incident.

Appendix

Timeline of disclosure

  • February 19, 2018—Report vulnerabilities to Apple
  • February 19, 2018—Apple acknowledges report
  • February 21, 2018—Apple is provided with proof of concept
  • February 21, 2018—Apple thanks us for the additional information and says they are investigating
  • March 29, 2018—Apple releases security updates here.

The vulnerabilities

1. Safari automatic download and mounting of disk images
CoreTypes defines a list of a safe Uniform Type Identifiers (UTI) that will automatically be opened by Safari. These can be found in LSRiskCategorySafe. Of particular interest here is com.real.smil.

If we check the Launch Services database with lsregister, we see this is defined in CoreTypes and described as “synchronized multimedia integration language,” and appears to be associated with the Real Player media application. A number of file extensions are associated with this UTI, including “.smi”.

$ touch a.smi
$ mdls a.smi | grep -e "kMDItemContentType\s\|kMDItemKind"
kMDItemContentType                 = "com.real.smil"
kMDItemKind                        = "Self Mounting Image"

We can see the “.smi” filetype has the com.real.smil content type, but it’s described as a “Self Mounting Image.” This is because on macOS 10.12.6 the Disk Image Mounter application also associates itself with this extension, and lists itself as the default handler for the extension. The Disk Image Mounter application specifies the com.apple.disk-image-smi UTI for “.smi” extensions, but the com.real.smil defined in CoreTypes takes precedence.

This issue was assigned CVE-2017-13890. https://support.apple.com/en-us/HT208692

CoreTypes
Available for: OS X El Capitan 10.11.6, macOS Sierra 10.12.6
Impact: Processing a maliciously crafted webpage may result in the mounting of a disk image
Description: A logic issue was addressed with improved restrictions.
CVE-2017-13890: Apple, Theodor Ragnar Gislason of Syndis

2. Mounting disk image causes application launch
The bless utility is able to “set volume bootability and startup disk options.” An interesting option is --openfolder, which can be used to “Specify a folder to be opened in Finder when the volume is mounted by the system.” Despite that description, when the argument to --openfolder points to a loadable bundle, which are applications packaged as directories with names ending in “.bundle,” then the application will be launched instead of being opened in Finder. This effectively meant we now have a way to automatically launch applications by simply visiting a web page in Safari. However, the usefulness to an attacker is still limited at this point because they can’t launch arbitrary code. Gatekeeper protects against this kind of attack by only allowing applications downloaded from the app store and apps that are signed by known developers. Launch Services checks for these upon launching our application and throws the following error:

For the exploit chain to work, a Gatekeeper bypass was needed to avoid this check.

This was given CVE-2018-4176. https://support.apple.com/en-us/HT208692

Disk Images
Available for: OS X El Capitan 10.11.6, macOS Sierra 10.12.6, macOS High Sierra 10.13.3
Impact: Mounting a malicious disk image may result in the launching of an application
Description: A logic issue was addressed with improved validation.
CVE-2018-4176: Theodor Ragnar Gislason of Syndis

3. Gatekeeper bypass
Notice the message in the error above: “’evil’ can’t be opened because it is from an unidentified developer,” with a note that “evil” is on a disk image downloaded by Safari. Syndis then noticed a couple things:

  1. They could launch copies of signed application bundles, such as Terminal.app, located on our disk image.
  2. Modifying the Info.plist of the bundle does not invalidate the signature.

With the Info.plist it is possible to specify which file extensions can be opened with an application. It’s also possible to register new file extensions, which will help ensure the application is the default handler. Upon launching the app, Launch Services registers the app and these file extensions associated in its database. This can be seen using the lsregister command:

...
--------------------------------------------------------------------------------
Container mount state: mounted
bundle  id:            2740
        Mach-O UUIDs:  67FFA762-AB52-31F0-AC80-E72008760B13
        sequenceNum:   2740
        FamilyID:      0
        PurchaserID:   0
        DownloaderID:  0
        installType:   0
        appContainer:  #
        dataContainer: #
        path:          /Volumes/bundle/Terminal.app
        name:          Terminal
        displayName:   Terminal
...
        bundle flags:  apple-internal  has-display-name  launch-disabled  (0000000000000103)
...
                {
            CFBundleTypeExtensions =             (
                workingpoc
            );
            CFBundleTypeRole = invalid;
            LSIsAppleDefaultForType = 1;
        },
...
}
        library:       (null)
        schemesList:   ssh, telnet, x-man-page
...
        --------------------------------------------------------
        claim   id:            15108
                name:          (null)
                rank:          Default
                roles:         Viewer  
                flags:         apple-default  apple-internal  doc-type  
                icon:          
                bindings:      .workingpoc
...

This gives a way to register new file extensions and launch signed applications. However, we don’t yet have a way of launching our own applications or commands. Leveraging the Terminal app was the next logical step, considering it’s meant for running arbitrary commands. When trying to launch shell scripts with the techniques above however, Gatekeeper prevents execution because of the quarantine bit that’s set from being downloaded by Safari.

Here’s the real trick—if we’re able to open a file with our new extension that’s associated with our copy of Terminal, then the quarantine bit is not checked, and it runs in the system’s version of Terminal without prompt.

This was given CVE-2018-4175. https://support.apple.com/en-us/HT208692

LaunchServices
Available for: OS X El Capitan 10.11.6, macOS Sierra 10.12.6, macOS High Sierra 10.13.3
Impact: A maliciously crafted application may be able to bypass code signing enforcement
Description: A logic issue was addressed with improved validation.
CVE-2018-4175: Theodor Ragnar Gislason of Syndis

The exploit

Syndis was able to chain these together in a two-stage exploit to achieve arbitrary code execution for a user who visits a specially crafted web page with Safari. The first stage includes a modified version of the Terminal app, which is registered as a handler for a new file extension (.workingpoc). In addition it would contain a blank folder called “test.bundle” which would be set as the default “openfolder” which automatically would open /Applications/Terminal.app without prompt. The second stage includes an unsigned shellscript with the extension “.workingpoc” which is then executed within the running Terminal application without prompt.

Validating the fixes

Apple provided fixes for the vulnerabilities identified with the update announced here, on March 29, 2018: https://support.apple.com/en-us/HT208692

CVE-2017-13890
The com.real.smil UTI appears to have been removed from CoreTypes. A quick check shows “.smi” files now have the appropriate content type:

$ mdls a.smi | grep -e "kMDItemContentType\s\|kMDItemKind"
kMDItemContentType                 = "com.apple.disk-image-smi"
kMDItemKind                        = "Self Mounting Image"

And this can be further verified by comparing the Launch Services database between 10.12.6 and 10.13.4:

10.12.6

claim   id:            3804
                name:          Self Mounting Image
                rank:          Default
                roles:         Viewer  
                flags:         apple-default  apple-internal  relative-icon-path  doc-type  
                icon:          Contents/Resources/diskcopy-doc.icns
                bindings:      com.real.smil, .smi

10.13.4

claim   id:            22824
                name:          Self Mounting Image
                rank:          Default
                roles:         Viewer  
                flags:         apple-default  apple-internal  relative-icon-path  doc-type  
                icon:          Contents/Resources/diskcopy-doc.icns
                bindings:      com.apple.disk-image-smi, .smi

As a result, Safari no longer automatically opens “.smi” files with the Disk Image Mounter application.

CVE-2018-4176
Using the bless command to open an loadable bundle no longer causes the bundle to launch. Instead, the directory is opened with the Finder application, as the command says it will do.

CVE-2018-4175
In 10.12.6 our script was launched without prompt in the second stage of our exploit. In 10.13.4 we are now presented with a warning that we have never launched this new application before:

Even if the first two CVEs weren’t addressed, we consider a user who’s presented with this dialog after simply visiting a web page in Safari has been sufficiently warned that continuing is potentially unsafe.

If we’re to click Open here, we notice the bundle flags for our modified Terminal no longer include launch-disabled in the Launch Services database:

...
--------------------------------------------------------------------------------
Container mount state: mounted
bundle  id:            2740
        Mach-O UUIDs:  67FFA762-AB52-31F0-AC80-E72008760B13
...
        path:          /Volumes/bundle/Terminal.app
...
        bundle flags:  apple-internal  has-display-name  (0000000000000003)
...