Show Notes

87 - Gatekeeper Bypass, Opera RCE, and Prototype Pollution

Archive Utility on macOS had a bug when encountering long file paths during extraction that would result in the extracted files not recieving the com.apple.quarantine attribute that Gatekeeper looks for.

The root cause of this is that iterator that applies the quarantine attribute will exit early when it encounters a filename that exceeds the PATH_MAX value and the return code is never checked. By not having the attribute applied the file will avoid usual code signing checks that would apply to quarantined files.

An actual attack utilizing this trick is a bit more complicated as the path still needs to be accessible in the Finder application so a user can be coerced into executing the no-longer quarantined executable. To do this the author made use of symlinks and some ceever naming to make it appear like a normal application bundle.

Three more OAuth flow vulnerabilities

First some quick background, Oauth flows to apps can use a custom URI as a whitelisted callback url, the challenge is that any application can register that same handler and recieve the callback. So Facebook does apply some defenses against this.

  1. If in a webview from within the Facebook or Workplace applications they whitelist redirects with specific schemes and block some of their generic ones like fb{APP_ID://
  2. If using a mobile browser they ask for confirmation rather than immediately redirecting.
  3. Check for certain headers that indicate its a native login using the ProxyAuth activity expored by com.facebook.katana
  4. If the headers are found, then an addition key calling_package_key or android_key needs to be provided which indicate the application that started the ProxyAuth activity

Stealing a Workplace Account First-Party Access Token

The Workplace OAuth flow didn’t implement the confirmation prompt (second defense from the list above) so one could pull off the traditional attack flow against the work.workplace.com/dialog/oauth endpoint by first registering a fb{{First-party Workplace App id}}://authorize URI scheme, and then trigger an OAuth login redirecting to it.

Abusing ProxyAuth Activity

The ProxyAuth activity usually will generate an android_key to send along with the request to indicate the calling application. In some cases ProxyAuth will fail to generate a key which results in an empty key being send. While the m.facebook.com/dialog/oauth endpoint would result in a authorization dialog, the workplace endpoint would immediately redirect successfully.

Bypassing WebView URI Whitelist

The author found that if xd_arbiter or dialog/return/arbiter endpoints were specified in the redirect_uri and used a fb:// schema then it would redirect to fb://www.facebook.com which an attacker could potentially control.

Three meme vulnerabilities in Cisco Hyperflex, two unauthenticated RCEs, one unauthenticated directory traversal attack in a file upload, and two traversal attacks that were authenticated.

The first RCE is during the authentication process. In order to generate the password hash to compare with the content of the /etc/shadow file the Golang application generates some python code which it passes to python as an argument to -c. In tradition, RCE form, there is no sanitization of the password to ensure the attacker cannot breakout of the resulting python code resulting in a fairly easy command injection.

The second RCE is in the /storfs-asup endpoint, which is handled by a service running on Apache Tomcat. Decompiling the class file they found that the service was ultimately created command string that would be passed into bash -c that would reflect a couple request parameters (token, and mode) without sanitization into the command line allowing for a trivial escape and code execution.

There was one trick of note here though, and that was because the storfs-asup service is only available if port 80 is exposed. So an https service wouldn’t expose, however /crossdomain.xml will get proxies to the same tomcat instance. So a trick with tomcat is to use /crossdoamin.xml/..;/storfs-asup/ to access the otherwise blocked off endpoint.

The third vulnerability is a file upload endpoint /upload which was vulnerable to directory traversal and also accessible without authentication.

There were also two similar traversal vulnerabilities found in two authenticated endpoints which resulted in filewrites as root. These bugs were not accepted by Cisco though as they would require knowledge of the same credentials used to SSH onto the machine.

Root cause here is an XSS in the “My Flow” feature resulting in client-side code execution.

My Flow is a shared space between your computer and phone to share links, images, videos with yourself, and uses a built-in browser extension. The problem code was in the drag-and-drop event handling. When a user drops an image onto the page, a new element is created with the innerHTML attribute set to what is expected to be the source URL of the image file. However it is possible to control the data of the dataTransfer event so HTML could be included instead of the expected image. Enabling XSS on the Opera page.

In looking to gain higher privileges the author looked at what functionality was available on this extensions page, turns out it had access to opr.operaTouchPrivate which is a collection of functions to be used by the My Flow applicataion, including SEND_FILE and OPEN_FILE functions which can be used to first write a file such as a bat and then open it leading to command execution.

Whats interesting here is more the inclusion of methodology for finding the pollution points and the script gadgets that could abuse the pollution rather than the specific vulnerabilities.

That said they did discover four vulnerabilities.

  1. The first netted them a $4000 bounty, but is pretty light on details. Pollution led to controlling the URL a webworker would load its source from, but as it was a web worker it didn’t have access to the page DOM. However they manage “something” involving opening sensitive pages in iframes and then changing the logged in account to presumably exfil that information.

  2. Jira Service Management < 4.18.0 - They found that Jira Service Management was using backbone to process query parameters leading to pollution and ultimately XSS by setting the isFresh field and then the payload in onmousemove. This recieved a $2000 bounty from Mozilla who was using the service. The vulnerability was also reported to Jira for a $600 bounty. Jira did fix the issue by blacklisting the important keys, but one of the authors was able to bypass this fix by including a [ or ] in the key as those characters would get stripped after it passed the parameter blacklist.

  3. XSS on apple.com - This one was discovered using a chrome extension to test for pollution in authenticated endpoint. Finding one on apple.com where polluting the src field and setting it to image and onerror to the javascript payload resulting in XSS, and a $6000 bounty.

  4. HubSpot Analytics - HubSpot was using deparam which parses the query string in a vulnerable way. As HubSpot is an analytics service that is embeded in other websites there was no universal XSS but it is noted that several applications were vulnerable to XSS because of using HubSpot. They also bypassed two of HubSpot’s fixes. The first because they only blacklisted the __proto__ key, so constructor could be used.

The second bypass is pretty cool and happens in two stages but is a pain to simplify how it works. First, the blacklist only runs on complex keys like an array access. This can be effective as usually to abuse prototype pollution issues you would set a field on the prototype like __proto__[somethingelse]=payload. So is blacklists prototype access when doing so.

The bypass took advantage of this and some code that would convert a single value into an array if it saw the same key twice. So myarray=1&myarray2 would first be obj[myarray] = 1 then becomes obj[myarray] = [1,2]. First by sending a “simple key” of __proto__= (no value) it would see that __proto__ already had a value set, so convert it into an array using the existing value of obj.__proto__ as the first element. Becoming obj[__proto__] = [Object.__proto__, ""]

This meant that accessing the 0 element of obj would actually point to Object.__proto__, and 0 is naturally not a blacklisted key. So 0[tainted]=polluted would become an assignment to obj[0][tained] and obj[0] is Object__proto__

Really elegant bypass, but took a bit to comprehend from the image in the writeup.

  1. Segment Analytics - Due to the use of the querystring component, Segment Analytics was vulnerable to prototype pollution, though only when properties are numeric. Finding a gadget to exploit this issue is difficult, though they point out one library that has one is knockout.js, due to it’s use of regular expressions that run against page content. By utilizing properties 4 and 5, XSS can be achieved on a site that uses both querystring and knockout, though the authors were not able to achieve XSS in any of the applications they tested.